Dodatocna vlastna javascript funkcia v onsubmit
- MIKI
- Člen | 34
Zdravim,
chcem pridat vlastnu JS funkciu, ktora sa vykona pri odoslani formulara, do AppForm, s tym, ze sa zachova validacia formulara.
Inak povedane, ako mozem nastavit volanie urcitej JS funkcie po uspesnej validacii formulara a este pred odoslanim? Cim dlhsie nad tym premyslam, tym menej napadov na moznu realizaciu mam.
Vdaka za pomoc a napady
- MIKI
- Člen | 34
Dnes som sa tomu zase trochu venoval a nasiel som zrejme funkcne riesenie.
AppForm()->addSubmit()->getControlPrototype()->onclick('js_funkcia()');
V pripade jednoducheho formulara to je funkcne.
Taktiez som si aj nasiel chybu v JS funkcii, kvoli ktorej mi ani tato konstrukcia najprv nefungovala.
- MIKI
- Člen | 34
westrem napsal(a):
Diky, vedel som, ze to nebude take jednoduche :)
Bohuzial, nevykonava sa. Najprv sa spravi moja JS funkcia a potom je validacia.
A to je zle.
Je mozne to sice v JS funkcii osetrit, ale neexistuje lepsi sposob ako to
spravit aby to bolo po validacii? (bez zasahu do mojej JS funkcie?)
- westrem
- Člen | 398
Aku verziu Nette pouzivas? Ak 0.9.* tak existuje riesenie (trosku zdlhave) ale hodne ciste bez explicitneho zasahu do frameworku.
O pridavanie JS validacie sa stara InstantClientScript
, ktory
na tomto
riadku pridava JS validaciu. Ty tam chces mat svoju JS spolu s validaciou
cize tam chces toto:
return nette.validateForm(this) && tvoja_JS_funkcia()
K tomu aby si to dosiahol, si proste vytvor vlastny objekt, ktory bude
totozny ako InstantClientScript
len zmenis ten spominany riadok
(podedit nemozes, pretoze je final – tzn bud smaz final a poded a prepis si
tu funkciu alebo vytvor ten identicky objekt).
Dalej, aby sa pri renderingu uplatnil tvoj
InstantClientScript
je potrebne povedat to Rendereru, tzn poded
ConventionalRenderer
a zmen tento
riadok tak aby vracal instanciu tvojho ClientScriptu (tzn. v praxi podedis
od Conventional rendereru a prepises (override) tu funkciu
getClientScript
).
Tymto sposobom by si mal dosiahnut to, ze najskor sa spravi validacia (v JS podmienke je 1.) a nasledne sa vykona este tvoja JS_funkcia.
Este len tak z kuriozity: co chces tou JS funkciou spravit? Ci to nejde nahodou obecne aj inak ako takto :) a aby sme tu neriesili zbytocne nieco komplikovane.
- westrem
- Člen | 398
redhead napsal
Pardon pardon, bol som tak zazrany do napisania riesenia, ze som trochu plietol triedy a objekty .. mas samozrejme pravdu.
Taktiez s tym nastavovanim ClienScriptu som pozabudol, ze je tam aj setter (ked ma clovek otvorenych 5+ API okien, trochu strati prehlad co kde uz je)
- MIKI
- Člen | 34
redhead napsal(a):
westrem napsal
Diky obom. Presne toto som potreboval :)
Vysledok je asi takyto: Vytvoril som si novu triedu (skopirovany subor) MyInstantClientScript, do ktoreho som pridal nasledujuci text:
/** @var array */
private $afterValidateJS;
/** @var array */
private $beforeValidateJS;
...
public function __construct(Form $form)
{
$this->form = $form;
+ $this->afterValidateJS = array();
+ $this->beforeValidateJS = array();
}
...
/**
* Add JavaScript function after Form Validation on Submit
*/
public function addAfterValidateJS($jsfun)
{
$this->afterValidateJS[] = $jsfun;
}
/**
* Add JavaScript function before Form Validation on Submit
*/
public function addBeforeValidateJS($jsfun)
{
$this->beforeValidateJS[] = $jsfun;
}
/**
* Generate result onsubmit with JavaScript function
*/
private function getFormOnSubmitValidate()
{
$validate = 'nette.validateForm(this)';
$array = array_merge($this->beforeValidateJS, array($validate), $this->afterValidateJS);
return 'return '.join(' && ', $array);
}
A upravil vo funkcii enable() riadok L1 na riadok L2
if ($this->validateScripts || $this->toggleScript) {
if ($this->central) {
- $this->form->getElementPrototype()->onsubmit("return nette.validateForm(this)", TRUE); // L1
+ $this->form->getElementPrototype()->onsubmit($this->getFormOnSubmitValidate(), TRUE); // L2
} else {
Pri vytvarani formulara
$MyInstantCS = new MyInstantClientScript($form);
$MyInstantCS->addAfterValidateJS('mojaFunkcia()');
$form->getRenderer()->setClientScript($MyInstantCS);
A vo vyslednom formulari sa teda vygeneruje:
<form action="__ACTION__" method="post" id="__ID__" onsubmit="return nette.validateForm(this) && mojaFunkcia()">
Sice sa mi tam nepacia tie & ale v Opere a FireFoxe to funguje ako ma :)
Este raz diky za napad! A dufam, ze sa toto niekomu zide taktiez :)