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;
46: $this->validateScripts =
array();
47: $this->toggleScript =
'';
48: $this->central =
TRUE;
50: foreach ($this->form->getControls() as $control) {
51: $script =
$this->getValidateScript($control->getRules());
53: $this->validateScripts[$control->getHtmlName()] =
$script;
55: $this->toggleScript .=
$this->getToggleScript($control->getRules());
58: $this->central =
FALSE;
62: if ($this->validateScripts ||
$this->toggleScript) {
63: if ($this->central) {
67: foreach ($this->form->getComponents(TRUE, 'Nette\Forms\ISubmitterControl') as $control) {
68: if ($control->getValidationScope()) {
69: $control->getControlPrototype()->onclick("return nette.validateForm(this)", TRUE);
79: * Generates the client side validation script.
84: if (!$this->validateScripts &&
!$this->toggleScript) {
90: include dirname(__FILE__) .
'/InstantClientScript.phtml';
96: private function getValidateScript(Rules $rules)
99: foreach ($rules as $rule) {
102: if (strcasecmp($rule->operation, 'Nette\Forms\InstantClientScript::javascript') ===
0) {
103: $res .=
"$rule->arg\n";
107: $script =
$this->getClientScript($rule->control, $rule->operation, $rule->arg);
108: if (!$script) continue;
110: if (!empty($rule->message)) { // this is rule
113: .
"if (" .
($rule->isNegative ?
'' :
'!') .
"res) "
114: .
"return " .
json_encode((string)
$message) .
(strpos($message, '%value') ===
FALSE ?
'' :
".replace('%value', val);\n") .
";\n";
117: if ($rule->type ===
Rule::CONDITION) { // this is condition
118: $innerScript =
$this->getValidateScript($rule->subRules);
120: $res .=
"$script\nif (" .
($rule->isNegative ?
'!' :
'') .
"res) {\n" .
String::indent($innerScript) .
"}\n";
122: $this->central =
FALSE;
132: private function getToggleScript(Rules $rules, $cond =
NULL)
135: foreach ($rules->getToggles() as $id =>
$visible) {
136: $s .=
"visible = true; {$cond}\n"
137: .
"nette.toggle(" .
json_encode((string)
$id) .
", " .
($visible ?
'' :
'!') .
"visible);\n";
140: foreach ($rules as $rule) {
142: $script =
$this->getClientScript($rule->control, $rule->operation, $rule->arg);
144: $res =
$this->getToggleScript($rule->subRules, $cond .
"$script visible = visible && " .
($rule->isNegative ?
'!' :
'') .
"res;\n");
146: $el =
$rule->control->getControlPrototype();
147: if ($el->getName() ===
'select') {
148: $el->onchange("nette.forms[$formName].toggle(this)", TRUE);
150: $el->onclick("nette.forms[$formName].toggle(this)", TRUE);
151: //$el->onkeyup("nette.forms[$formName].toggle(this)", TRUE);
163: private function getClientScript(IFormControl $control, $operation, $arg)
172: case $operation ===
':filled' &&
$control instanceof
RadioList:
173: return "res = (val = nette.getValue($elem)) !== null;";
176: return "res = sender && sender.name==" .
json_encode($control->getHtmlName()) .
";";
180: foreach ((is_array($arg) ?
$arg :
array($arg)) as $item) {
183: $first =
$control->isFirstSkipped() ?
1 :
0;
184: return "var options = $elem.options; res = false;\n"
185: .
"for (var i=$first, len=options.length; i<len; i++)\n\t"
186: .
"if (options[i].selected && (" .
implode(' || ', $tmp) .
")) { res = true; break; }";
188: case $operation ===
':filled' &&
$control instanceof
SelectBox:
189: return "res = $elem.selectedIndex >= " .
($control->isFirstSkipped() ?
1 :
0) .
";";
191: case $operation ===
':filled' &&
$control instanceof
TextBase:
192: return "val = nette.getValue($elem); res = val!='' && val!=" .
json_encode((string)
$control->getEmptyValue()) .
";";
194: case $operation ===
':minlength' &&
$control instanceof
TextBase:
195: return "res = (val = nette.getValue($elem)).length>=" . (int)
$arg .
";";
197: case $operation ===
':maxlength' &&
$control instanceof
TextBase:
198: return "res = (val = nette.getValue($elem)).length<=" . (int)
$arg .
";";
200: case $operation ===
':length' &&
$control instanceof
TextBase:
202: $arg =
array($arg, $arg);
204: return "val = nette.getValue($elem); res = " .
($arg[0] ===
NULL ?
"true" :
"val.length>=" . (int)
$arg[0]) .
" && "
205: .
($arg[1] ===
NULL ?
"true" :
"val.length<=" . (int)
$arg[1]) .
";";
207: case $operation ===
':email' &&
$control instanceof
TextBase:
208: return 'res = /^[^@\s]+@[^@\s]+\.[a-z]{2,10}$/i.test(val = nette.getValue('.
$elem.
'));';
210: case $operation ===
':url' &&
$control instanceof
TextBase:
211: return 'res = /^.+\.[a-z]{2,6}(\\/.*)?$/i.test(val = nette.getValue('.
$elem.
'));';
213: case $operation ===
':regexp' &&
$control instanceof
TextBase:
215: return NULL; // regular expression must be JavaScript compatible
218: return "res = $arg.test(val = nette.getValue($elem));";
220: case $operation ===
':integer' &&
$control instanceof
TextBase:
221: return "res = /^-?[0-9]+$/.test(val = nette.getValue($elem));";
223: case $operation ===
':float' &&
$control instanceof
TextBase:
224: return "res = /^-?[0-9]*[.,]?[0-9]+$/.test(val = nette.getValue($elem));";
226: case $operation ===
':range' &&
$control instanceof
TextBase:
227: return "val = nette.getValue($elem); res = " .
($arg[0] ===
NULL ?
"true" :
"parseFloat(val)>=" .
json_encode((float)
$arg[0])) .
" && "
228: .
($arg[1] ===
NULL ?
"true" :
"parseFloat(val)<=" .
json_encode((float)
$arg[1])) .
";";
231: return "res = (val = nette.getValue($elem)) != '';";
234: return "res = !this[" .
json_encode($control->getHtmlName()) .
"](sender);";
239: foreach ((is_array($arg) ?
$arg :
array($arg)) as $item) {
241: $tmp[] =
"val==nette.getValue(form[" .
json_encode($item->getHtmlName()) .
"])";
246: return "val = nette.getValue($elem); res = (" .
implode(' || ', $tmp) .
");";