Source for file InstantClientScript.php
Documentation is available at InstantClientScript.php
6: * @copyright Copyright (c) 2004, 2010 David Grudl
7: * @license http://nettephp.com/license Nette license
8: * @link http://nettephp.com
10: * @package Nette\Forms
16: * Instant validation JavaScript generator.
18: * @copyright Copyright (c) 2004, 2010 David Grudl
19: * @package Nette\Forms
24: private $validateScripts;
27: private $toggleScript;
48: $el->name =
'frm-' .
($this->form instanceof
AppForm ?
$this->form->lookupPath('Nette\Application\Presenter', TRUE) :
$this->form->getName());
50: $this->validateScripts =
array();
51: $this->toggleScript =
'';
52: $this->central =
TRUE;
54: foreach ($this->form->getControls() as $control) {
55: $script =
$this->getValidateScript($control->getRules());
57: $this->validateScripts[$control->getHtmlName()] =
$script;
59: $this->toggleScript .=
$this->getToggleScript($control->getRules());
62: $this->central =
FALSE;
66: if ($this->validateScripts ||
$this->toggleScript) {
67: if ($this->central) {
71: foreach ($this->form->getComponents(TRUE, 'Nette\Forms\ISubmitterControl') as $control) {
72: if ($control->getValidationScope()) {
73: $control->getControlPrototype()->onclick("return nette.validateForm(this)", TRUE);
83: * Generates the client side validation script.
88: if (!$this->validateScripts &&
!$this->toggleScript) {
94: include dirname(__FILE__) .
'/InstantClientScript.phtml';
100: private function getValidateScript(Rules $rules)
103: foreach ($rules as $rule) {
106: if (strcasecmp($rule->operation, 'Nette\Forms\InstantClientScript::javascript') ===
0) {
107: $res .=
"$rule->arg\n";
111: $script =
$this->getClientScript($rule->control, $rule->operation, $rule->arg);
112: if (!$script) continue;
114: if (!empty($rule->message)) { // this is rule
116: .
"if (" .
($rule->isNegative ?
'' :
'!') .
"res) "
117: .
"return " .
json_encode((string)
vsprintf($rule->control->translate($rule->message, is_int($rule->arg) ?
$rule->arg :
NULL), (array)
$rule->arg)) .
";\n";
120: if ($rule->type ===
Rule::CONDITION) { // this is condition
121: $innerScript =
$this->getValidateScript($rule->subRules);
123: $res .=
"$script\nif (" .
($rule->isNegative ?
'!' :
'') .
"res) {\n" .
String::indent($innerScript) .
"}\n";
125: $this->central =
FALSE;
135: private function getToggleScript(Rules $rules, $cond =
NULL)
138: foreach ($rules->getToggles() as $id =>
$visible) {
139: $s .=
"visible = true; {$cond}\n"
140: .
"nette.toggle(" .
json_encode((string)
$id) .
", " .
($visible ?
'' :
'!') .
"visible);\n";
143: foreach ($rules as $rule) {
145: $script =
$this->getClientScript($rule->control, $rule->operation, $rule->arg);
147: $res =
$this->getToggleScript($rule->subRules, $cond .
"$script visible = visible && " .
($rule->isNegative ?
'!' :
'') .
"res;\n");
149: $el =
$rule->control->getControlPrototype();
150: if ($el->getName() ===
'select') {
151: $el->onchange("nette.forms[$formName].toggle(this)", TRUE);
153: $el->onclick("nette.forms[$formName].toggle(this)", TRUE);
154: //$el->onkeyup("nette.forms[$formName].toggle(this)", TRUE);
166: private function getClientScript(IFormControl $control, $operation, $arg)
175: case $operation ===
':filled' &&
$control instanceof
RadioList:
176: return "res = nette.getValue($elem) !== null;";
179: return "res=sender && sender.name==" .
json_encode($control->getHtmlName()) .
";";
183: foreach ((is_array($arg) ?
$arg :
array($arg)) as $item) {
186: $first =
$control->isFirstSkipped() ?
1 :
0;
187: return "var options = $elem.options; res = false;\n"
188: .
"for (var i=$first, len=options.length; i<len; i++)\n\t"
189: .
"if (options[i].selected && (" .
implode(' || ', $tmp) .
")) { res = true; break; }";
191: case $operation ===
':filled' &&
$control instanceof
SelectBox:
192: return "res = $elem.selectedIndex >= " .
($control->isFirstSkipped() ?
1 :
0) .
";";
194: case $operation ===
':filled' &&
$control instanceof
TextBase:
195: return "var val = nette.getValue($elem); res = val!='' && val!=" .
json_encode((string)
$control->getEmptyValue()) .
";";
197: case $operation ===
':minlength' &&
$control instanceof
TextBase:
198: return "res = nette.getValue($elem).length>=" . (int)
$arg .
";";
200: case $operation ===
':maxlength' &&
$control instanceof
TextBase:
201: return "res = nette.getValue($elem).length<=" . (int)
$arg .
";";
203: case $operation ===
':length' &&
$control instanceof
TextBase:
205: $arg =
array($arg, $arg);
207: return "var val = nette.getValue($elem); res = " .
($arg[0] ===
NULL ?
"true" :
"val.length>=" . (int)
$arg[0]) .
" && "
208: .
($arg[1] ===
NULL ?
"true" :
"val.length<=" . (int)
$arg[1]) .
";";
210: case $operation ===
':email' &&
$control instanceof
TextBase:
211: return 'res = /^[^@\s]+@[^@\s]+\.[a-z]{2,10}$/i.test(nette.getValue('.
$elem.
'));';
213: case $operation ===
':url' &&
$control instanceof
TextBase:
214: return 'res = /^.+\.[a-z]{2,6}(\\/.*)?$/i.test(nette.getValue('.
$elem.
'));';
216: case $operation ===
':regexp' &&
$control instanceof
TextBase:
218: return NULL; // regular expression must be JavaScript compatible
221: return "res = $arg.test(nette.getValue($elem));";
223: case $operation ===
':integer' &&
$control instanceof
TextBase:
224: return "res = /^-?[0-9]+$/.test(nette.getValue($elem));";
226: case $operation ===
':float' &&
$control instanceof
TextBase:
227: return "res = /^-?[0-9]*[.,]?[0-9]+$/.test(nette.getValue($elem));";
229: case $operation ===
':range' &&
$control instanceof
TextBase:
230: return "var val = nette.getValue($elem); res = " .
($arg[0] ===
NULL ?
"true" :
"parseFloat(val)>=" .
json_encode((float)
$arg[0])) .
" && "
231: .
($arg[1] ===
NULL ?
"true" :
"parseFloat(val)<=" .
json_encode((float)
$arg[1])) .
";";
234: return "res = nette.getValue($elem) != '';";
237: return "res = !this[" .
json_encode($control->getHtmlName()) .
"](sender);";
242: foreach ((is_array($arg) ?
$arg :
array($arg)) as $item) {
244: $tmp[] =
"val==nette.getValue(form[" .
json_encode($item->getHtmlName()) .
"])";
249: return "var val = nette.getValue($elem); res = (" .
implode(' || ', $tmp) .
");";