přesná identifikace submit tlačítka

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

Připojím do prezenteru submit a pak se zeptám jestli byl form odeslán tímto tlačítkem.
Pokud byl formulář odeslán, pak Nette tvrdí TRUE, protože je to v tu chvíli jediný submit ve formu.

PROČ???

Informaci o odeslání/neodeslání formuláře přeci mohu mít i tak.
Automatické označování prvního tlačítka je chybné.

Jaký je váš názor?

Šaman
Člen | 2662
+
0
-

Trochu nechápu co přesně myslíš tím odesláním bez použití tlačítka. Když dáš ve formuláři ENTER, tak to nasimuluje stisk prvního Submitu, tzn. že ten formulář je skutečně odeslán tím tlačítkem. Anebo mluvíš o něcěm jiném?

mlha
Člen | 58
+
0
-

Co když formulář obsahuje několik submit tlačítek.
Při vytváření formuláře se musí testovat, kterým tlačítkem byl případně odeslán. Tento test ale nelze provést ihned po vložení submitu, ale až po vložení všech submitů.
Vytvoření submitu a test jeho odeslání tak nelze pořešit samostatnou metodou :(

jtousek
Člen | 951
+
0
-

Jak to souvisí s tvým prvním postem a proč je to problém? Připadá mi to logické.

newPOPE
Člen | 648
+
0
-

Tiez nerozumiem co vlastne chces dosiahnut.

Zostav formular v tovarni a nadefinuj obsluhu na jednotlive tlacitka

<?php
	$form->addSubmit('delete')
		->onClick[] = \callback($this, 'xyzFormDeleteClicked');
?>
Filip Procházka
Moderator | 4668
+
0
-

Myslím, že bude problém s tvou logikou, né s formuláři. Budeš muset změnit přístup, nebo si udělat fork a upravit si to :)

Martin
Člen | 171
+
0
-

mlha: Teda četl jsem Tvé posty 5×, než mi došlo, k čemu to asi potřebuješ. Máš pravdu, ale proč to neřešíš přes callbacky (lépe definovat jako pole)? A nemýlím-li se, callback lze zapsat i inline, jde-li Ti o vložení tlačítka jednou kdesi jinde předdefinovanou metodou. Respektive ->onClick[] = array($this, 'method'); použité ve třídě, odkud si budeš tlačítka vybírat, zafunguje na tamní metodu, budeš-li mít v továrničce k dispozici instanci této třídy. Nevím, jestli to lze nějak vymyslet i se self pro statické metody, ale většinou stejně v obsluze tlačítka potřebuješ provést něco poměrně nestatického. Řešil bych to třeba (nekoukej na PHP, to moc neumím, jsem OOP programátor v jiném jazyce) takto:

namespace MojeNamespace;
use Nette\...;
class MojeKomponentaObsahujiciMojeStandardniTlacikaProFormulare
{
	protected __this = NULL;

	/*protected $mujAktualniPresenter;*/ // to jen tak, kdybych ho někde potřeboval.
	__construct (/*$presenterTovarnicky*/)
	{
		/*$mujAktualniPresenter = $presenterTovarnicky;*/
		__this = $this;
	}

	public static function addMojeTlacitko1($form, /*$presenterTovarnicky,*/ $parametry) {
		$tlacitko = $form->addSubmit(...,...)
			->onClick = array(__this, 'obsluhaTlacitka1');
		//zde $this v extension metodě asi nebude obsahovat to pravé ořechové...
	}
	public function obsluhaTlacitka1($button) {
		//zde obsluha používající $button, z něj získaný $form a aktuální Presenter, nebo $mujAktualniPresenter
	}
}
//Přidám addMojeTlacitko1 do třídy FormControl:
Nette\Forms\FormControl::extensionMethod('addMojeTlacitko1', 'MojeNamespace\MojeKomponentaObsahujiciStandardniTlacikaProFormulare::addMojeTlacitko1');

//A pak v továrničce:

Class NejakyPresenter...
{
	...
	function createComponentMujForm($name)
	{
		//Pokud to nejde řešit přes statické callbacky (nevím), musím vytvořit instanci:
		$mojeTlacitka = new MojeKomponentaObsahujiciMojeStandardniTlacikaProFormulare(/*$this*/);
		$form = new Form($this, $name);
		...
		$form->addMojeTlacitko1(/*$this,*/ $parametry);
		//Zde už by měl callback fungovat - nezkoušel jsem
}

Možná tam ještě budeš muset předávat aktuální Presenter (původně jsem to napsal s tím, ale pak jsem zjistil, že to asi nebude potřeba, tak jsem to vykomentoval v konstruktoru i metodě, měl by se dát v obsluze získat z proměnné $form, je-li už připojena).

Editoval Martin (8. 5. 2011 23:40)

Patrik Votoček
Člen | 2221
+
0
-

mlha napsal(a):

Při vytváření formuláře se musí testovat, kterým tlačítkem byl případně odeslán. Tento test ale nelze provést ihned po vložení submitu, ale až po vložení všech submitů.

WTF? Můžeš si přece otestovat:

$form->addSubmit('sub1', "Save");
$form->addSubmit('sub2', "Save as new");

if ($form->values['sub1'] == "Save") {
	// save data
} elseif ($form->values['sub2'] == "Save as new") {
	// save data as new
}

Výše uvedený kód je jenom ukázka ve skutečnosti to funguje takto:

$form->addSubmit('sub1', "Save")->onClick[] = function(SubmitButton $button) {
	$values = $button->form->values;
	// save data
};
$form->addSubmit('sub2', "Save as new")->onClick[] = function(SubmitButton $button) {
	$values = $button->form->values;
	// save data as new
};

POZOR NA TO ABY JSI MĚL U JEDNOTLIVÝCH TLAČÍTEK VYPLNĚNÝ $caption. BEZ NĚJ TOTIŽ NEMÁ NETTE ŠANCI DETEKOVAT KTERÝM TLAČÍTKEM BYL FORMULÁŘ ODESLÁN!!!

Martin
Člen | 171
+
0
-

Patrik Votoček: No vida, jde to inline:-) . Po detailním prostudování druhého mlhova postu jsem pochopil, že mu jde o použití externí metody (kterou bude mít někde předpřipravenu pro více formulářů a která už bude mít v sobě zahrnutu obsluhu kliku), pak jeho posty dávají smysl. Možná se mýlím a to nahoře jsem tvořil zbytečně :-) V každém případě nebude nutné zbytečně vytvářet instanci, nějak mi nedošlo, jak to inline zapsat a že array je tam v příkladech použito jen z důvodu větší flexibility. Jak to ten David dělá (míněno ne jak to implementuje, ale jak ho něco tak univerzálně použitelného napadne), že tam lze použít pole, callback i inline funkci, a všechno funguje? Jako všechno v Nette :-)

Editoval Martin (8. 5. 2011 23:45)

Patrik Votoček
Člen | 2221
+
0
-

Já to právě nepochopil vůbec. Teď už mlhavě asi chápu. Pak může použít něco takovéhoto (pseudo kód):

$click = function(SubmitButton $button) {
	$form = $button->form;
        $values = $form->values;

	if ($form['sub1']->submittedBy) {
		// save data
	} elseif ($form['sub2']->submittedBy) {
		// save data as new
	}
};

$form->addSubmit('sub1', "Save")->onClick[] = $click;
$form->addSubmit('sub2', "Save as new")->onClick[] = $click;

Ale připadá mě to nehezké a spíš bych se pídil po tom proč chce něco takového dělat.

Martin
Člen | 171
+
0
-

No třeba vymyslel krásnou metodu, která po stisku tlačítka s celým formulářem provede nějaký úžasný přemet a chce ji teď používat ve všech formulářích včetně jejího extra barevného tlačítka. Ale to, co jsem napsal, lze vlastně úplně jednoduše nahradit pomocí addComponent, kde komponenta bude v konstruktoru tvořit button s hotovou obsluhou onClick. To už není až tak ošklivé, ani zalevýmuchempravourukousedrbající, jako to, co jsem psal nahoře :-)

mlha
Člen | 58
+
0
-

Smyslem tohoto všeho je vyčlenit fragment formuláře (s vlastními pomocnými tlačítky) do samostatné metody. Tlačítka fragmentu modifikují (ovlivňují) část formuláře. A celý fragment se ve formuláři může vyskytovat opakovaně. Tento fragment by ale měl být i nadále součástí formuláře a měl by se podílet (jeho data) na běžném zpracování.

Ano je možné, že to, jak hodlám pracovat s formuláři, je už od základu chybné (snad ne).
Možná je lepší vydat se cestou vlastních komponent (subkomponent), ale v tom se zatím moc necítím.

Ale hlavní otázka, na kterou se ptám hned na začátku. To, že prohlížeč stiskem ENTER odešle formulář prvním submitem, je ok. Ale proč to samé dělá i Nette? (po prvním vloženém submitu tvrdí že byl submitBy). Přináší to nějakou výhodu?

Moc děkuji všem za příspěvky. Jdu je všechny ještě jednou pozorně prostudovat.

Editoval mlha (21. 6. 2011 10:49)

juzna.cz
Člen | 248
+
0
-

Nette se tak chova myslim kvuli chybe v IE. Prohlizec ma pri odeslani formulare enterem automaticky simulavat stisk prvniho tlacitka, coz vsak nektere verze IE nedelaji. Nette to tedy takto obchazi, aby se formulare chovaly stejne ve vsech prohlizecich.

Filip Procházka
Moderator | 4668
+
0
-

Prostě použij ty callbacky a nehackuj to :)

mlha
Člen | 58
+
0
-

HosipLan napsal(a):

Prostě použij ty callbacky a nehackuj to :)

Jenže ten callback bude zavolán až na po vytvoření formuláře a to je už pozdě.

Filip Procházka
Moderator | 4668
+
0
-

Proč je to pozdě?

mlha
Člen | 58
+
0
-

HosipLan napsal(a):

Proč je to pozdě?

Protože klik na tlačítko ovlivňuje samotný formulář. Například některé prvky se nemají vložit.

Nebo to jde dodatečně rušit už vložené prvky a vkládat nové na konkrétní místo?

Editoval mlha (23. 6. 2011 15:02)

Filip Procházka
Moderator | 4668
+
0
-

Ukaž mi zjednodušený příklad, toho o co se snažíš a já ti ukážu jak to udělat lépe, bez hackování formulářů :)

David Grudl
Nette Core | 8227
+
0
-

Tak jsem čekal, kdo první pochopí, co mlha vlastně chce a zachránil to juzna :-)

juzna.cz napsal(a):

Nette se tak chova myslim kvuli chybe v IE. Prohlizec ma pri odeslani formulare enterem automaticky simulavat stisk prvniho tlacitka, coz vsak nektere verze IE nedelaji. Nette to tedy takto obchazi, aby se formulare chovaly stejne ve vsech prohlizecich.

Tohle nešťastné chování, které způsobuje problémy jenž mlha popisuje (aniž by ho asi někdo chápal) existuje jako workaround pro nepříjemný bug v IE. Druhou možností by bylo automaticky přidávat do HTML <input disabled style="display:none">, což je takové divné.

…když to teď píšu, napadl mě ještě jeden workaroud, zkusím ho prověřit.

Zkusím tam dát ten input, co to udělá…

David Grudl
Nette Core | 8227
+
0
-

fixed

Filip Procházka
Moderator | 4668
+
0
-

Aj, příště lépe číst :)

mlha
Člen | 58
+
0
-

Děkuji