]> git.openstreetmap.org Git - chef.git/blob - cookbooks/dmca/files/default/html/HTML/QuickForm/DHTMLRulesTableless.php
Merge remote-tracking branch 'github/pull/183'
[chef.git] / cookbooks / dmca / files / default / html / HTML / QuickForm / DHTMLRulesTableless.php
1 <?php
2 /**
3  * DHTML replacement for the standard JavaScript alert window for client-side
4  * validation
5  *
6  * LICENSE:
7  * 
8  * Copyright (c) 2005-2007, Mark Wiesemann <wiesemann@php.net>
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  *
15  *    * Redistributions of source code must retain the above copyright
16  *      notice, this list of conditions and the following disclaimer.
17  *    * Redistributions in binary form must reproduce the above copyright
18  *      notice, this list of conditions and the following disclaimer in the 
19  *      documentation and/or other materials provided with the distribution.
20  *    * The names of the authors may not be used to endorse or promote products 
21  *      derived from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
31  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  *
35  * @category   HTML
36  * @package    HTML_QuickForm_DHTMLRulesTableless
37  * @author     Alexey Borzov <borz_off@cs.msu.su>
38  * @author     Adam Daniel <adaniel1@eesus.jnj.com>
39  * @author     Bertrand Mansion <bmansion@mamasam.com>
40  * @author     Justin Patrin <papercrane@gmail.com>
41  * @author     Mark Wiesemann <wiesemann@php.net>
42  * @license    http://www.opensource.org/licenses/bsd-license.php New BSD License
43  * @version    CVS: $Id: DHTMLRulesTableless.php,v 1.10 2007/10/24 20:36:11 wiesemann Exp $
44  * @link       http://pear.php.net/package/HTML_QuickForm_DHTMLRulesTableless
45  */
46
47 require_once 'HTML/QuickForm.php';
48
49 /**
50  * This is a DHTML replacement for the standard JavaScript alert window for
51  * client-side validation of forms built with HTML_QuickForm
52  *
53  * @category   HTML
54  * @package    HTML_QuickForm_DHTMLRulesTableless
55  * @author     Alexey Borzov <borz_off@cs.msu.su>
56  * @author     Adam Daniel <adaniel1@eesus.jnj.com>
57  * @author     Bertrand Mansion <bmansion@mamasam.com>
58  * @author     Justin Patrin <papercrane@gmail.com>
59  * @author     Mark Wiesemann <wiesemann@php.net>
60  * @license    http://www.opensource.org/licenses/bsd-license.php New BSD License
61  * @version    Release: 0.3.3
62  * @link       http://pear.php.net/package/HTML_QuickForm_DHTMLRulesTableless
63  */
64 class HTML_QuickForm_DHTMLRulesTableless extends HTML_QuickForm {
65     // {{{ getValidationScript()
66
67     /**
68      * Returns the client side validation script
69      *
70      * The code here was copied from HTML_QuickForm and slightly modified to run rules per-element
71      *
72      * @access    public
73      * @return    string    Javascript to perform validation, empty string if no 'client' rules were added
74      */
75     function getValidationScript()
76     {
77         if (empty($this->_rules) || empty($this->_attributes['onsubmit'])) {
78             return '';
79         }
80
81         include_once('HTML/QuickForm/RuleRegistry.php');
82         $registry =& HTML_QuickForm_RuleRegistry::singleton();
83         $test = array();
84         $js_escape = array(
85             "\r"    => '\r',
86             "\n"    => '\n',
87             "\t"    => '\t',
88             "'"     => "\\'",
89             '"'     => '\"',
90             '\\'    => '\\\\'
91         );
92
93         foreach ($this->_rules as $elementName => $rules) {
94             foreach ($rules as $rule) {
95                 if ('client' == $rule['validation']) {
96                     unset($element);
97
98                     $dependent  = isset($rule['dependent']) && is_array($rule['dependent']);
99                     $rule['message'] = strtr($rule['message'], $js_escape);
100
101                     if (isset($rule['group'])) {
102                         $group    =& $this->getElement($rule['group']);
103                         // No JavaScript validation for frozen elements
104                         if ($group->isFrozen()) {
105                             continue 2;
106                         }
107                         $elements =& $group->getElements();
108                         foreach (array_keys($elements) as $key) {
109                             if ($elementName == $group->getElementName($key)) {
110                                 $element =& $elements[$key];
111                                 break;
112                             }
113                         }
114                     } elseif ($dependent) {
115                         $element   =  array();
116                         $element[] =& $this->getElement($elementName);
117                         foreach ($rule['dependent'] as $idx => $elName) {
118                             $element[] =& $this->getElement($elName);
119                         }
120                     } else {
121                         $element =& $this->getElement($elementName);
122                     }
123                     // No JavaScript validation for frozen elements
124                     if (is_object($element) && $element->isFrozen()) {
125                         continue 2;
126                     } elseif (is_array($element)) {
127                         foreach (array_keys($element) as $key) {
128                             if ($element[$key]->isFrozen()) {
129                                 continue 3;
130                             }
131                         }
132                     }
133
134                     $test[$elementName][] = $registry->getValidationScript($element, $elementName, $rule);
135                 }
136             }
137         }
138         $js = '
139 <script type="text/javascript"><!--//--><![CDATA[//><!--
140 qf_errorHandler = function(element, _qfMsg) {
141   div = element.parentNode;
142   var elementName = element.name.replace(/\[/, "_____");
143   var elementName = elementName.replace(/\]/, "_____");
144   if (_qfMsg != \'\') {
145     span = document.createElement("span");
146     span.className = "error";
147     _qfMsg = _qfMsg.substring(4);
148     span.appendChild(document.createTextNode(_qfMsg));
149     br = document.createElement("br");
150
151     var errorDiv = document.getElementById(elementName + \'_errorDiv\');
152     if (!errorDiv) {
153       errorDiv = document.createElement("div");
154       errorDiv.id = elementName + \'_errorDiv\';
155     } else {
156       if (   div.firstChild.textContent == \'\'
157           || _qfMsg == div.firstChild.textContent
158          ) {
159         return false;
160       }
161     }
162     while (errorDiv.firstChild) {
163       errorDiv.removeChild(errorDiv.firstChild);
164     }
165
166     errorDiv.insertBefore(br, errorDiv.firstChild);
167     errorDiv.insertBefore(span, errorDiv.firstChild);
168
169     errorDivInserted = false;
170     for (var i = element.parentNode.childNodes.length - 1; i >= 0; i--) {
171       j = i - 1;
172       if (j >= 0 && element.parentNode.childNodes[j].nodeName == "DIV") {
173         element.parentNode.insertBefore(errorDiv, element.parentNode.childNodes[i]);
174         errorDivInserted = true;
175         break;
176       }
177     }
178     if (!errorDivInserted) {
179       element.parentNode.insertBefore(errorDiv, element.parentNode.firstChild);
180     }
181
182     if (div.className.substr(div.className.length - 6, 6) != " error"
183         && div.className != "error") {
184       div.className += " error";
185     }
186
187     return false;
188   } else {
189     var errorDiv = document.getElementById(elementName + \'_errorDiv\');
190     if (errorDiv) {
191       errorDiv.parentNode.removeChild(errorDiv);
192     }
193     
194     // do not remove the error style from the div tag if there is still an error
195     // message
196     if (div.firstChild.innerHTML != "") {
197       return true;
198     }
199
200     if (div.className.substr(div.className.length - 6, 6) == " error") {
201       div.className = div.className.substr(0, div.className.length - 6);
202     } else if (div.className == "error") {
203       div.className = "";
204     }
205
206     return true;
207   }
208 }';
209         $validateJS = '';
210         foreach ($test as $elementName => $jsArr) {
211             // remove group element part of the element name to avoid JS errors
212             $singleElementName = $elementName;
213             $shortNameForJS = str_replace(array('[', ']'), '__', $elementName);
214             $bracketPos = strpos($elementName, '[');
215             if ($bracketPos !== false) {
216                 $singleElementName = substr($elementName, 0, $bracketPos);
217                 $groupElementName = substr($elementName, $bracketPos + 1, -1);
218             }
219             if ($bracketPos === false || !$this->elementExists($singleElementName)) {
220                 $groupElementName = $elementName;
221                 $singleElementName = $elementName;
222             }
223             $id = str_replace('-', '_', $this->_attributes['id']);
224             $js .= '
225 validate_' . $id . '_' . $shortNameForJS . ' = function(element) {
226   var value = \'\';
227   var errFlag = new Array();
228   var _qfGroups = {};
229   var _qfMsg = \'\';
230   var frm = element.parentNode;
231   while (frm && frm.nodeName != "FORM") {
232     frm = frm.parentNode;
233   }
234 ' . join("\n", $jsArr) . '
235   return qf_errorHandler(element, _qfMsg);
236 }
237 ';
238             unset($element);
239             $element =& $this->getElement($singleElementName);
240             $elementNameForJS = 'frm.elements[\'' . $elementName . '\']';
241             if ($element->getType() === 'group' && $singleElementName === $elementName) {
242                 $elementNameForJS = 'document.getElementById(\'' . $element->_elements[0]->getAttribute('id') . '\')';
243             }
244             $validateJS .= '
245   ret = validate_' . $id . '_' . $shortNameForJS . '('. $elementNameForJS . ') && ret;';
246             if ($element->getType() !== 'group') {  // not a group
247                 $valFunc = 'validate_' . $id . '_' . $shortNameForJS . '(this)';
248                 $onBlur = $element->getAttribute('onBlur');
249                 $onChange = $element->getAttribute('onChange');
250                 $element->updateAttributes(array('onBlur' => $onBlur . $valFunc,
251                                                  'onChange' => $onChange . $valFunc));
252             } else {  // group
253                 $elements =& $element->getElements();
254                 for ($i = 0; $i < count($elements); $i++) {
255                     // $groupElementName is a substring of attribute name of the element
256                     if (strpos($elements[$i]->getAttribute('name'), $groupElementName) === 0) {
257                         $valFunc = 'validate_' . $id . '_' . $shortNameForJS . '(this)';
258                         $onBlur = $elements[$i]->getAttribute('onBlur');
259                         $onChange = $elements[$i]->getAttribute('onChange');
260                         $elements[$i]->updateAttributes(array('onBlur'   => $onBlur . $valFunc,
261                                                               'onChange' => $onChange . $valFunc));
262                     }
263                 }
264             }
265         }
266         $js .= '
267 validate_' . $id . ' = function(frm) {
268   var ret = true;
269 ' . $validateJS . ';
270   return ret;
271 }
272 //--><!]]></script>';
273         return $js;
274     } // end func getValidationScript
275
276     // }}}
277
278     function display() {
279         $this->getValidationScript();
280         return parent::display();
281     }
282 }
283
284 ?>