Furmuláře a formátování

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

Zdravím, měl bych dotaz. Nikde jsem nenašel, zda lze nějak ovlivnit vzhled formuláře?

Například nebudu chtít, aby se mi prvky formuláře kreslily do tabulky, ale budu si je chtít zobrazit po svém..

Standartně se přidávají prvky do formuláře(v ukázkách) takto:

$form->addText('name', 'Your name:');
$form->addText('age', 'Your age:', 5);

Ve vygenerovaném formuláři to bude vypadat:

Your name: <input …>
Your age: <input value=„5“ …>

Napadlo mě, že když nevyplním popisný název u přidávaného prvku, tak se třeba v tabulce nezobrazí onen prázdný sloupec (snad je to jasné..). Vkladám jen jeden prvek (kromě submit..), respektive všechny prvky jsou bez popisného textu, tak proč tabulka?

Např.:

$form->addTextArea('content'); // $form->addTextArea('content', 'Text:');

Chtěl bych, aby byla zobrazena pouze TextArea a pod tím Submit a Cancel. Jak toho lze prosím dosáhnout prostřednictvím presenteru? Případně, lze toho docílit i nějak jinak? (tohle jsou mé hlavní otázky topicu). Děkuji za vaše rady.

class TextPresenter extends Presenter
{
    public function renderEdit(...)
    {
        $form = $this['textForm'];
        ...

    }

    protected function createComponentTextForm()
    {
        $form = new AppForm;
        $form->addTextArea('content')->addRule(Form::FILLED, 'Vložte text prosím.');

        $form->addSubmit('save', 'Save')->getControlPrototype()->class('default');
        $form->addSubmit('cancel', 'Cancel')->setValidationScope(NULL);
        $form->onSubmit[] = callback($this, 'textFormSubmitted');

        $form->addProtection('Odešlete formulář znovu prosím (bezpečtnostní token vypršel).');

        return $form;
    }
}

Bohužel, i když nevyplním onen popisný název, tak se to stále zobrazí v tabulce.. :/.

  <textarea></textarea>
  <input type=„submit“ ..> <input type=„submit“ ..>
<form action="nejaka akce" method="post" name="frm-TextForm">

<table>
<tr class="required">
	<th><label class="required" for="frmTextForm-content"></label></th>

	<td><textarea cols="40" rows="10" name="content" id="frmTextForm-content">Textovz obsah</textarea></td>
</tr>

<tr>

	<th>&nbsp;</th>

	<td><input type="submit" class="default button" onclick="return nette.validateForm(this)" name="save" id="frmTextForm-save" value="Save" /> <input type="submit" class="button" name="cancel" id="frmTextForm-cancel" value="Cancel" /></td>
</tr>
</table>

<div><input type="hidden" name="_token_" id="frmTextForm-_token_" value="17ab040418da99a2723ea9cf841c46ee" /></div>
</form>

Je zbytečně přidán sloupec tabulky, který nebude nikdy využit. V kódu to je <th><label class="required" for="frmTextForm-content"></label></th> a <th>&nbsp;</th>.

Formulář vykresluji v šabloně takto:

...
{widget aboutUsForm}
...

Nešlo by Davide (pokud něco takového už není) doimpelemtovat takovou možnost, že budu moct ovlivnit nějakým způsobem výsledný „layout“ vygenerovaného formuláře?

třeba:

$form = new AppForm;
$form->layout = 'simple'; // prvdy se vykrasli na kazdy radek zvlast (bez tabulky)
$form->layout = 'table'; // tabulka, u ktere se vykresluje sloupec s popisnymi nazvy
$form->layout = 'simpletable'; // tabulka, u ktere se sloupec s popisnymi nazvy nevykresluje
...

nebo:

$form = new AppForm;
$form->layout = 'table'; // prvdy se vykrasli na kazdy radek zvlast (bez tabulky)
$form->columns = 1; // jeden sloupec

$form->addTextArea('content'); // vykresli se do prvniho radku tabulky (prvni radek je automaticky)
$form->addColumn(); // prida dalsi radek tabulky do ktereho budou vykresleny vsechny dalsi polozky, dokud nepridam dalsi radek tabulky
$form->addText('name', 'Your name:');
$form->addText('age', 'Your age:', 5);
$form->addColumn(); // dalsi radek (tento bude prazdny)
$form->addColumn(); // dalsi radek
$form->addSubmit('save', 'Save')->getControlPrototype()->class('default');
$form->addSubmit('cancel', 'Cancel')->setValidationScope(NULL);
...

Díky moc a doufám, že se tu někdo brzy ozve s něčím co mě potěší :).

Editoval Endrju (27. 2. 2010 2:08)

radas
Člen | 225
+
0
-

Můžeš formulář renderovat manuálně. Pěkný článek vyšel na Zdrojáku. Podle mě layout formuláře patří do šablony a ne do logiky aplikace.

Endrju
Člen | 147
+
0
-

Pecka, diky :). Uz si ani nepamatuju, ze neco takoveho v tom serialu na zdrojaku bylo 0:-).

Takze abych nezobrazoval levy sloupec s popiskama, tak staci pouzit wrappers a do kodu pridat

protected function createComponentAboutUsForm()
{
	$form = new AppForm;

        $renderer = $form->getRenderer();
        $renderer->wrappers['label']['container'] = NULL;

	...

Edit: Jeste takova drobnost. Ted jsem si vsiml, ze ve vygenerovanem kodu to sice nevykrasli pro ten prvni sloupec ‚label‘ parovou znacku <td>…</td>, nicmene obsah ten znacky to porad vykresluje, tedy mi v kodu zustane napr. <label class="required" for="frmTextForm-content"></label>. Sice je obsah popisky prazdny, takze to na vysledku nic extra nemeni, ale vykresluje to ty tagy, ktere jsou uvnitr tagu specifikovaneho v $wrappers['label']['container'].

Co kdybych chtel v presenteru prece jen mit nastavene ty popisky a na zaklade nejake promenne jen skryval onen levy sloupec s popiskama? V tomto pripade by se sice nevykreslil tag <td>, ale obsah tohoto tagu ano. Musel bych tedy zase vymazat popisky..

Existuje i neco pro to, aby se ten levy sloupec VUBEC nezobrazoval (tedy ani jeho obsah)?

Editoval Endrju (27. 2. 2010 8:07)

Endrju
Člen | 147
+
0
-

Existuje i neco pro to, aby se ten levy sloupec VUBEC nezobrazoval (tedy ani jeho obsah)?

(viz. post vyse) Ozivuji vlakno, aby nezapadlo.. :)

Honza Kuchař
Člen | 1662
+
0
-

Manuální render.

Endrju
Člen | 147
+
0
-

Ahoj, opet se vracim k tomuto tematu.

Potrebuju poradit s manualnim vykreslovanim formulare. Koukal jsem na forum, kde se pisou vsemozna reseni a nezkuseny clovek se pak nevyzna a nevi co je stare a zda uz neni jednoduchsi reseni.. Chtel bych proto pozadat o pomoc.

Potrebuju formular vykreslit takto:

  • nad formularem budou chyby (chtel bych zaroven nejak nastavit formatovni vypisu tech chyb – budou obalene tagem div a ten se vykresli, jen kdyz nejake chyby budou..)
  • pak by byl obsah formulare, ktery zahrnuje:
    • TextArea obalena tagem div (zadna legend, jen container)
    • Pak tlacitko Odeslat a Zrusit, obe obalena tagem div (opet zadna legend, jen container)

Premyslel jsem, zda by mi k tomu postacil wrappers, nebo by to slo udelat i jinak. Kazdopadne ani s tim wrappers si poradne nevim rady a nevim, jake vsechny moznosti mi poskytuje.

Dekuji mockrat :)

Etch
Člen | 403
+
0
-

No nevim jestli sem to úplně dobře pochopil, ale pokud bych se měl přesně držet zadání tak asi takhle

	{$presenter['textForm']->render('begin')}
	{if !empty($presenter['textForm']->errors)}
		<div>
			{foreach $presenter['textForm']->errors AS $error}
				{$error}<br>
			{/foreach}
		</div>
	{/if}
	<div>
		{$presenter['textForm']['content']->control}
	</div>
	<div>
		{$presenter['textForm']['save']->control}
	</div>
	<div>
		{$presenter['textForm']['cancel']->control}
	</div>
	{$presenter['textForm']->render('end')}

ten výpis errorů by se dal udělat {$presenter['textForm']->render('error')}, ale vzhledem k tomu, že si chtěl mít plnou kontrolu na jejich výpisem tak je tam tahle „opičárna“ :)

EDIT: Typo

Editoval Etch (7. 3. 2010 2:37)

Endrju
Člen | 147
+
0
-

Etch, diky! Funguje to presne tak, jak jsem potreboval.

Pro uplnost (a pro ostani) jeste napisu jake zmeny jsem udelal, at je to kompetni.

Manualní render formuláře:

V presenteru jsem upravil tovarnicku na vytvoreni formulare takto:

class TextPresenter extends Presenter
{
	...

	protected function createComponentTextForm()
	{
		$form = new AppForm;
		$form->addTextArea('content')->addRule(Form::FILLED, 'Vložte text prosím.');

		$form->addSubmit('save', 'Save')->getControlPrototype()->class('default');
		$form->addSubmit('cancel', 'Cancel')->setValidationScope(NULL);
		$form->onSubmit[] = callback($this, 'textFormSubmitted');

		$form->addProtection('Odešlete formulář znovu prosím (bezpečtnostní token vypršel).');

		// Ulozim si formular do promenne, abych si v sablone usetril psani.
		// Budu pak v sablone moci pristupovat k prvkum formulare napriklad takto:
		// 	$form->render('begin')
		// Samozrejmne stale funguje zapis, tak jako psal Etch, tedy:
		// 	$presenter['textForm']->render('begin')
		$this->template->form = $form;
		return $form;
	}

	...

}

A v sablone, kde vykresluji formular napisu misto tohoto:

{widget textForm}

tohle:

{$form->render('begin')}
{if !empty($form->errors)}
<div class="errors">
	{foreach $form->errors AS $error}
		{$error}<br>
	{/foreach}
</div>
{/if}

<div>{$form['content']->control}</div>

<div>{$form['save']->control} {$form['cancel']->control}</div>

{$form->render('end')}

kod vypada naslednovne:

Editoval Endrju (7. 3. 2010 4:51)

despiq
Člen | 320
+
0
-

asi bych radeji daval ten formular do sablony az v render fazi a ne primo v tovarnicce, ta by mela ten objekt spis jenom vracet

takze v renderAkce

<?php
 $this->template->form = $this->getComponent('textForm');
?>

ale to ten formular bude muset zacit

<?php
 $form = new AppForm($this, $name);
?>
Ondřej Mirtes
Člen | 1536
+
0
-

despiq: Nemusí dělat žádnou úpravu, bude to fungovat i s tím původním konstruktorem.

Endrju
Člen | 147
+
0
-

diky za pripominku. presunul jsem to do render akce