Více prvků na jednom řádku

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Ola
Člen | 385
+
0
-

Zdravím (opět :-)), tentokrát potřebuji nějak dostat více prvků na jeden řádek (bez nějakýho extendovvání conventionalrenderer apod.) .. Typicky třeba (readonly) textbox obsahující vyplněnou kategorii z minulého kroku, vedle něj tlačítko Upravit kategorii .. Nebo třebas datum narození – kdybych chtěl udělat 3 selecty vedle sebe (den, měsíc, rok).. Nevíte někdo o něčem?

Díky..

Jod
Člen | 701
+
0
-

Pokiaľ chceš nejaký readonly/disabled input tak skús

FormControl::setOption()

‚description‘ – textual or Html object description (recognized by ConventionalRenderer)

https://api.nette.org/…Control.html#…

Môžeš tam vložiť text, alebo Html object, ktorý sa ti zobrazí v bežnom zobrazení vpravo od formulárového prvku.

Ale neskúšal som neviem.

Ešte môžeš prepísať Renderer.

Editoval Jod (24. 1. 2009 14:24)

krajaac
Člen | 45
+
0
-

Ola napsal(a):

Zdravím (opět :-)), tentokrát potřebuji nějak dostat více prvků na jeden řádek (bez nějakýho extendovvání conventionalrenderer apod.) .. Typicky třeba (readonly) textbox obsahující vyplněnou kategorii z minulého kroku, vedle něj tlačítko Upravit kategorii .. Nebo třebas datum narození – kdybych chtěl udělat 3 selecty vedle sebe (den, měsíc, rok).. Nevíte někdo o něčem?

Díky..

Už jsi to nějak vyřešil? já teďkom dělám stejnou věc: Celý form chci vykreslit standartně, akorát v něm mám jeden SELECT, vedle kterého potřebuju mít SubmitButton.

Zatím jsem přišel na tohle:

<?php
	$button = $form->addSubmit('category_adder', 'Přidat');
	$button->onClick[] = array($this,'addCategory');

	$form->addSelect('category', 'Kategorie', $categories)
		->setOption('description', $button->getControl());
?>

Pak se ale buttonek vykreslí 2×.

Dalo by se to obejít tak, že tlačítko vytvořím místo addSubmit() přes new SubmitButton(). Tím ale přijdu o propojení formu a tlačítka…

Nevíte někdo jak na to?

krajaac
Člen | 45
+
0
-

Potom bych ještě pořeboval další podobnou specialitku:

mít text (v div, p, nebo i label) a vedle toho související Button.

Neporadí někdo?

Jak to vidím, tak asi bude potřeba napsat vlastní renderer..

R2D2
Člen | 22
+
0
-

Je nějaký speciální důvod proč ten form nevykreslíte dle svých požadavků až v šabloně? To jestli se políčka vykreslí vedle sebe nebo pod sebou, nebo jestli kolem budou další prvky, stejně logicky do šablony patří… já vim, je to pochodlný vypisovat jen jednu proměnnou, ale rozepsat to mi přijde jako jednodušší a přehlednější řešení.

Jod
Člen | 701
+
0
-

Musíš prepísať renderer. Ja som robil dynamické generovanie formulárov z poľa a spravil som ti nato takú šablonu, ktorá ten obsah dynamicky vygeneruje podľa toho ako chcem.

krajaac
Člen | 45
+
0
-

R2D2 napsal(a):

Je nějaký speciální důvod proč ten form nevykreslíte dle svých požadavků až v šabloně? To jestli se políčka vykreslí vedle sebe nebo pod sebou, nebo jestli kolem budou další prvky, stejně logicky do šablony patří… já vim, je to pochodlný vypisovat jen jednu proměnnou, ale rozepsat to mi přijde jako jednodušší a přehlednější řešení.

Ano, je. Mám jeden typ formulářů, které se liší jen v detailech. Všechny si je definuju v různých presenterech a k jejich vykreslení používám jednu globální šablonu. Vykreslovat form po částech až v šabloně by vyžadovalo další šablonu (která by se od té globální lišila minimálně = duplicity), sice by to bylo jednodušší a rychlejší, ale méně čisté při ohledu na celkový koncept aplikace.

Jod
Člen | 701
+
0
-

Generovanie prvkov v šablone sa ale dá srpaviť aj dynamicky.

David Grudl
Nette Core | 8147
+
0
-

Ano, tohle formulářům chybí. Řešit by se to mělo přes pokyny rendereru zapsané v setOptions(). Napadá někoho elegantní forma řešení?

Ola
Člen | 385
+
0
-

Co třeba:

$line1 = $form->addLine();

$line1->addText("text", "zadej");
$line1->addSelect("select", "vyber", $items);

$form->addText("text2", "zadej"); // již na další řádce

tedy podobně (stejně) jako u containerů ..

(teď koukám, že to mělo být přes setOption, tam ale moc dobře nevím jak to zrealizovat .. jedíně):

$form->addText("text", "zadej");
$form->addSelect("select", "vyber", $items)->setOption('after', $form['text);

stejně mi ale přijde lepší to první řešení ..

Editoval Ola (28. 1. 2009 6:29)

krajaac
Člen | 45
+
0
-

Ola napsal(a):

Co třeba:

$line1 = $form->addLine();

$line1->addText("text", "zadej");
$line1->addSelect("select", "vyber", $items);

$form->addText("text2", "zadej"); // již na další řádce

tedy podobně (stejně) jako u containerů ..

Jj, tohle mě taky napadlo. Ale na druhou stranu by FormLine (addLine) nemela zadny logicky vyznam, jako tomu je u FormContaineru. Ale zase jak se ted divam na FormGroups, tak ty taky tvori pouze vizualni strukturu

Možná takto?: (styl ala FormGroups)

$form->addSelect('name', 'Select:', $data)
	->setOption('appendNext', TRUE); ?
	->setOption('sameLine', TRUE); ?
	->setOption('nextLine', FALSE); ?
	->setOption('breakLine', FALSE); ?
	->setOption('breakAfter', FALSE); ?
	->setOption('\n', FALSE); ? :)
$form->addSubmit('button', 'Do It!');

Editoval krajaac (29. 1. 2009 1:50)

Jakub Šulák
Člen | 222
+
0
-

Můžu se zeptat, jak udělat šablonu v případě kdy mám n textboxů, u kterých neznám jejich názvy dopředu? Potřebuji je vykreslit v řádku tak, aby byl Label-TextInput-SubmitButton.

Dá se to dělat nějak přes Group? Jak se k nim dostanu v šabloně? Dá se nad nimi iterovat?

díky

Jod
Člen | 701
+
0
-

Na iterovanie použi addContainer. Na vykreslovanie si môžeš spraviť dynamickú šablonu.

Editoval Jod (12. 3. 2009 10:41)

Jakub Šulák
Člen | 222
+
0
-

Můžeš mi naznačit na zrojáku:

<?php
$translateForm = new AppForm($this,'trans');
$translateForm->addGroup();
foreach ($table as $item){
	$container = $translateForm->addContainer('words');
	$container->addHidden('id')->setValue($item->id);
	$container->addText('translation', $item->name,100)->setValue($item->translation);
	$container->addSubmit('delete', 'Smazat');
	$i++;
}
$translateForm->addSubmit('save', 'Uložit')
              ->onClick[] = array($this,'onSave');
$this->template->form = $translateForm;
?>

Potřebuji totiž vytvořit formulář, nad kterým pak budu iterovat. Tedy v šabloně by to pak vypadalo asi takto:

foreach ($form as $item){ // $item by byly jednotlive containery
  echo $item['id']; //vypise hidden input
}

Takto to ale nefunguje. Zastaví se to již na tom, že container musí mít jednoznačné označení komonenty. Jde mi o to, dostat ve výsledku hodnoty ve tvaru $values[]['id'], $values[]['translation'], $values[]['delete'] ([] – automaticky ohodnocené klíče).

Jod
Člen | 701
+
0
-
<?php
$translateForm = new AppForm($this,'trans');
$translateForm->addGroup();
foreach ($table as $index => $item){
        $container = $translateForm->addContainer($index);
        $container->addHidden('id')->setValue($item->id);
        $container->addText('translation', $item->name,100)->setValue($item->translation);
        $container->addSubmit('delete', 'Smazat');
        $i++;
}
$translateForm->addSubmit('save', 'Uložit')
              ->onClick[] = array($this,'onSave');
$this->template->form = $translateForm;
?>
{foreach $form->getComponents() as $c)
	{if $c instanceOf FormContainer}
		{foreach $c->components as $c2}
			{$c2->render()}
		{/foreach}
	{else}
		{$c->render()}
	{/if}
{/foreach}

Dá sa to spraviť aj cez bloky, najmä keď to chceš mať rekurzívne

Editoval romansklenar (14. 3. 2009 11:13)

romansklenar
Člen | 655
+
0
-

David Grudl napsal(a):

Ano, tohle formulářům chybí. Řešit by se to mělo přes pokyny rendereru zapsané v setOptions(). Napadá někoho elegantní forma řešení?

krajaac napsal(a):

Možná takto?: (styl ala FormGroups)

$form->addSelect('name', 'Select:', $data)
	->setOption('appendNext', TRUE); ?
	->setOption('sameLine', TRUE); ?
	->setOption('nextLine', FALSE); ?
	->setOption('breakLine', FALSE); ?
	->setOption('breakAfter', FALSE); ?
	->setOption('\n', FALSE); ? :)
$form->addSubmit('button', 'Do It!');

Něco z toho by se použít dalo, no ni? :)

Jakub Šulák
Člen | 222
+
0
-

Můžete sem prosím někdo napsat, co která direktiva v setOption() ovlivní? Zkouším si s tím hrát, ale žádné změny vykreslování jsem se nedočkal. Díky

romansklenar
Člen | 655
+
0
-

No z těch co tady jsou uvedené žádná nic neovlivní, je to jen nástřel. Ale není složité si to implementovat, tohle by mělo fungovat:

<?php

class CustomRenderer extends ConventionalRenderer
{

	/**
	 * Renders single visual row.
	 * @param  IFormControl
	 * @return string
	 */
	public function renderPair(IFormControl $control)
	{
		$pair = $this->getWrapper('pair container');
		$pair->add($this->renderLabel($control));
		$pair->add($this->renderControl($control));
		$pair->class($this->getValue($control->getOption('required') ? 'pair .required' : 'pair .optional'), TRUE);
		$pair->class($control->getOption('class'), TRUE);
		if (++$this->counter % 2) $pair->class($this->getValue('pair .odd'), TRUE);
		$pair->id = $control->getOption('id');

		$divider = $this->getDivider();
		if ($control->getOption('breakAfter')) {
			return $pair->render(0) . (string) $divider;
		} elseif ($control->getOption('breakBefore')) {
			return (string) $divider . $pair->render(0);
		// atd..
		} else {
			return $pair->render(0);
		}
	}


	/**
	 * Returns custom defined divider of control pairs
	 * @return Nette\Web\Html
	 */
	public function getDivider()
	{
		return Html::el('div')->class('divider');

		// taky lze resit dopsanim do pole $wrappers['pair']['divider'] = 'div class=divider'; a brat ho odtud
	}

}