Kde se generuje atribut nette rules?

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

Zdravím, mám menší problém a přemýšlím jak ho vyřešit.
Nemohu nikde prijit na to, jakym zpusobem se generuji atributy data-nette-rules – pokud chybi netteforms.js, prvky se pouze nezvaliduji(ackoli budou mit ty atributy), nebo je ten netteforms.js zodpovedny i za parsing tech pravidel do atributu?
Je to asi hloupy dotaz, ale pro vyreseni meho problemu stezejni.
Dekuji :)

CZechBoY
Člen | 3608
+
+1
-

JS jen validuje formularovy prvky u klienta (v prohlizeci), data atributy generuje php.

Kakaku
Člen | 27
+
0
-

V tom případě jsem ASI nalezl bug (nebo je to věc, která platí a na kterou je potřeba prostě dávat pozor?)

		$form->addText('login', 'Login:')
			->setType('email')
			->setHtmlId('email')
			->getControlPrototype()->addAttributes(array('class' => 'form-control'))
			->addRule(Form::EMAIL, "Zadání musí být platná e-mailová adresa")
			->setRequired();

nevygeneruje pole pravidel (data-nette-rules), ale pouhé prohození pořadí to opraví.

		$form->addText('login', 'Login:')
			->setType('email')
			->setHtmlId('email')
			->addRule(Form::EMAIL, "Zadání musí být platná e-mailová adresa")
			->setRequired()
->getControlPrototype()->addAttributes(array('class' => 'form-control'));
David Grudl
Nette Core | 8228
+
0
-

Je potřeba na to dávat pozor.

greeny
Člen | 405
+
+1
-

Kakaku napsal(a):

V tom případě jsem ASI nalezl bug (nebo je to věc, která platí a na kterou je potřeba prostě dávat pozor?)

		$form->addText('login', 'Login:')
			->setType('email')
			->setHtmlId('email')
			->getControlPrototype()->addAttributes(array('class' => 'form-control'))
			->addRule(Form::EMAIL, "Zadání musí být platná e-mailová adresa")
			->setRequired();

nevygeneruje pole pravidel (data-nette-rules), ale pouhé prohození pořadí to opraví.

		$form->addText('login', 'Login:')
			->setType('email')
			->setHtmlId('email')
			->addRule(Form::EMAIL, "Zadání musí být platná e-mailová adresa")
			->setRequired()
->getControlPrototype()->addAttributes(array('class' => 'form-control'));

Tohle je čistě o tom, že když zavoláš getControlPrototype() tak ti to vrátí objekt Html, kterej nemá metody addRule nebo setRequired (ale díky magickým metodám v tom Html to projde)

Michal Hlávka
Člen | 190
+
-5
-

@DavidGrudl a proč Nette nezahlásí, že nad getControlPrototype() nejde zavolat addRule metoda? http://i.imgur.com/ADV8LkM.png

David Grudl
Nette Core | 8228
+
+1
-

Protože jde. Přidá HTML atribut rule.

Felix
Nette Core | 1245
+
0
-

@emptywall Presne jak pise @DavidGrudl, je potreba na to davat pozor.

Tohle neni vec frameworku, ale spis nepozornosti. Ale i to se stava, dulezity je, ze se to vyresilo.

potapnik
Člen | 127
+
0
-

Každé rozumné IDE napovídá, co aktuálně použitá funkce vrací, tím bych se řídil, logika formulářů může být zpočátku poměrně záhadná, ale jak do toho člověk pronikne, tak to sází dobře. Časem možná narazíš, že potřebuješ dát formulářovému políčku spoustu vlastností, pravidel apod. Já to řeším tak, že si extendnu UI\Form a do toho extendnutého formu přidávám funkce podle typu pole, aby funkce vytvářející komponenty (ať už v presenteru nebo v továrně) neměly tisíc řádek. Příklad:

class PersonalDetailsForm extends Nette\Application\UI\Form {

	public function addTextLogin($name = 'login', $label = 'Login baby') {
		$control = $this->addText('login', 'Login:');

		// rules
		$control->addRule(self::EMAIL, "Zadání musí být platná e-mailová adresa")
			->addRule(self::....) // whatever
			->setRequired();

		// type, id and styles
		$control->setType('email')
				->setHtmlId('email')
				->getControlPrototype()->addAttributes(array('class' => 'form-control'));

		return $control;
	}

}

class LoginPresenter {
	protected function createComponentLoginForm() {
		$form = new PersonalDetailsForm();
		$form->addTextLogin();
		...
		return $form;
	}
}

Já osobně na tom „základním“ formu mám navěšené ještě další věci (translator, renderer a další ), takže ho ve výsledku mám jako aplikační službu, ale to už je na jinou diskuzi i ohledně toho, jestli je to vůbec architektonicky správně, takže tím bych tu nerad vyvolával offtopic.

Editoval potapnik (13. 7. 2016 21:09)

Šaman
Člen | 2665
+
0
-

@potapnik: Já myslím, že to, co máš v tom poděděném formu do továrny patří.

@Kakaku: Problém je v přílišném spoléhání na fluent. Nezáleží na pořadí, ale od getControlPrototype() už jsi na jiném objektu. Lepší je to rozepsat a fluent používat jen na několik nastavení stejné úrovně (třeba několik rules). Občas při složitějších pravidlech to ani jinak nejde.

<?php
$loginInput = $form->addText('login', 'Login:')
	->setType('email');
	->setHtmlId('email');
$loginInput->getControlPrototype()->addAttributes(array('class' => 'form-control'));
$loginInput->addRule(Form::EMAIL, "Zadání musí být platná e-mailová adresa")
    ->setRequired();
?>

Editoval Šaman (13. 7. 2016 21:58)

David Grudl
Nette Core | 8228
+
+1
-

Ono ->getControlPrototype()->addAttributes() jde nahradit za ->setAttribute() a objekt zůstane stejný.

potapnik
Člen | 127
+
0
-

@Šaman no, jenže já mám spousty políček, které potřebuji v aplikaci opakovaně (skoro všude), mají vlastní validační pravidla a pak ty formuláře rostou neúměrně…navíc, pokud si vzpomenu někde, že je potřeba doplnit do čísla smlouvy nějaké pravidlo, tak stačí doplnit na jednom místě. Ale to už je offtopic :)