This is a first cut of a new formslib.php a library of classes for creating and secur...
[moodle.git] / lib / pear / HTML / QuickForm / DHTMLRulesTableless.php
1 <?php
2 /**
3  * DHTML replacement for the standard JavaScript alert window for client-side
4  * validation
5  *
6  * PHP versions 4 and 5
7  *
8  * LICENSE: This source file is subject to version 3.01 of the PHP license
9  * that is available through the world-wide-web at the following URI:
10  * http://www.php.net/license/3_01.txt.  If you did not receive a copy of
11  * the PHP License and are unable to obtain it through the web, please
12  * send a note to license@php.net so we can mail you a copy immediately.
13  *
14  * @category   HTML
15  * @package    HTML_QuickForm_DHTMLRulesTableless
16  * @author     Alexey Borzov <borz_off@cs.msu.su>
17  * @author     Adam Daniel <adaniel1@eesus.jnj.com>
18  * @author     Bertrand Mansion <bmansion@mamasam.com>
19  * @author     Justin Patrin <papercrane@gmail.com>
20  * @author     Mark Wiesemann <wiesemann@php.net>
21  * @copyright  2005-2006 The PHP Group
22  * @license    http://www.php.net/license/3_01.txt  PHP License 3.01
23  * @version    CVS: $Id$
24  * @link       http://pear.php.net/package/HTML_QuickForm_DHTMLRulesTableless
25  */
27 require_once 'HTML/QuickForm.php';
29 /**
30  * This is a DHTML replacement for the standard JavaScript alert window for
31  * client-side validation of forms built with HTML_QuickForm
32  *
33  * @category   HTML
34  * @package    HTML_QuickForm_DHTMLRulesTableless
35  * @author     Alexey Borzov <borz_off@cs.msu.su>
36  * @author     Adam Daniel <adaniel1@eesus.jnj.com>
37  * @author     Bertrand Mansion <bmansion@mamasam.com>
38  * @author     Justin Patrin <papercrane@gmail.com>
39  * @author     Mark Wiesemann <wiesemann@php.net>
40  * @license    http://www.php.net/license/3_01.txt  PHP License 3.01
41  * @version    Release: 0.1.2
42  * @link       http://pear.php.net/package/HTML_QuickForm_DHTMLRulesTableless
43  */
44 class HTML_QuickForm_DHTMLRulesTableless extends HTML_QuickForm {
45     // {{{ getValidationScript()
47     /**
48      * Returns the client side validation script
49      *
50      * The code here was copied from HTML_QuickForm and slightly modified to run rules per-element
51      *
52      * @access    public
53      * @return    string    Javascript to perform validation, empty string if no 'client' rules were added
54      */
55     function getValidationScript()
56     {
57         if (empty($this->_rules) || empty($this->_attributes['onsubmit'])) {
58             return '';
59         }
61         include_once('HTML/QuickForm/RuleRegistry.php');
62         $registry =& HTML_QuickForm_RuleRegistry::singleton();
63         $test = array();
64         $js_escape = array(
65             "\r"    => '\r',
66             "\n"    => '\n',
67             "\t"    => '\t',
68             "'"     => "\\'",
69             '"'     => '\"',
70             '\\'    => '\\\\'
71         );
73         foreach ($this->_rules as $elementName => $rules) {
74             foreach ($rules as $rule) {
75                 if ('client' == $rule['validation']) {
76                     unset($element);
78                     $dependent  = isset($rule['dependent']) && is_array($rule['dependent']);
79                     $rule['message'] = strtr($rule['message'], $js_escape);
81                     if (isset($rule['group'])) {
82                         $group    =& $this->getElement($rule['group']);
83                         // No JavaScript validation for frozen elements
84                         if ($group->isFrozen()) {
85                             continue 2;
86                         }
87                         $elements =& $group->getElements();
88                         foreach (array_keys($elements) as $key) {
89                             if ($elementName == $group->getElementName($key)) {
90                                 $element =& $elements[$key];
91                                 break;
92                             }
93                         }
94                     } elseif ($dependent) {
95                         $element   =  array();
96                         $element[] =& $this->getElement($elementName);
97                         foreach ($rule['dependent'] as $idx => $elName) {
98                             $element[] =& $this->getElement($elName);
99                         }
100                     } else {
101                         $element =& $this->getElement($elementName);
102                     }
103                     // No JavaScript validation for frozen elements
104                     if (is_object($element) && $element->isFrozen()) {
105                         continue 2;
106                     } elseif (is_array($element)) {
107                         foreach (array_keys($element) as $key) {
108                             if ($element[$key]->isFrozen()) {
109                                 continue 3;
110                             }
111                         }
112                     }
114                     $test[$elementName][] = $registry->getValidationScript($element, $elementName, $rule);
115                 }
116             }
117         }
118         $js = '
119 <script type="text/javascript">
120 //<![CDATA[
121 function qf_errorHandler(element, _qfMsg) {
122   div = element.parentNode;
123   if (_qfMsg != \'\') {
124     span = document.createElement("span");
125     span.className = "error";
126     span.appendChild(document.createTextNode(_qfMsg.substring(3)));
127     br = document.createElement("br");
129     var errorDiv = document.getElementById(element.name + \'_errorDiv\');
130     if (!errorDiv) {
131       errorDiv = document.createElement("div");
132       errorDiv.id = element.name + \'_errorDiv\';
133     }
134     while (errorDiv.firstChild) {
135       errorDiv.removeChild(errorDiv.firstChild);
136     }
137     
138     errorDiv.insertBefore(br, errorDiv.firstChild);
139     errorDiv.insertBefore(span, errorDiv.firstChild);
140     element.parentNode.insertBefore(errorDiv, element.parentNode.firstChild);
142     if (div.className.substr(div.className.length - 6, 6) != " error"
143         && div.className != "error") {
144       div.className += " error";
145     }
147     return false;
148   } else {
149     var errorDiv = document.getElementById(element.name + \'_errorDiv\');
150     if (errorDiv) {
151       errorDiv.parentNode.removeChild(errorDiv);
152     }
154     if (div.className.substr(div.className.length - 6, 6) == " error") {
155       div.className = div.className.substr(0, div.className.length - 6);
156     } else if (div.className == "error") {
157       div.className = "";
158     }
160     return true;
161   }
162 }';
163         $validateJS = '';
164         foreach ($test as $elementName => $jsArr) {
165             $js .= '
166 function validate_' . $this->_attributes['id'] . '_' . $elementName . '(element) {
167   var value = \'\';
168   var errFlag = new Array();
169   var _qfGroups = {};
170   var _qfMsg = \'\';
171   var frm = element.parentNode;
172   while (frm && frm.nodeName != "FORM") {
173     frm = frm.parentNode;
174   }
175 ' . join("\n", $jsArr) . '
176   return qf_errorHandler(element, _qfMsg);
178 ';
179             $validateJS .= '
180   ret = validate_' . $this->_attributes['id'] . '_' . $elementName.'(frm.elements[\''.$elementName.'\']) && ret;';
181             unset($element);
182             $element =& $this->getElement($elementName);
183             $valFunc = 'validate_' . $this->_attributes['id'] . '_' . $elementName . '(this)';
184             $onBlur = $element->getAttribute('onBlur');
185             $onChange = $element->getAttribute('onChange');
186             $element->updateAttributes(array('onBlur' => $onBlur . $valFunc,
187                                              'onChange' => $onChange . $valFunc));
188         }
189         $js .= '
190 function validate_' . $this->_attributes['id'] . '(frm) {
191   var ret = true;
192 ' . $validateJS . ';
193   return ret;
195 //]]>
196 </script>';
197         return $js;
198     } // end func getValidationScript
200     // }}}
202     function display() {
203         $this->getValidationScript();
204         return parent::display();
205     }
208 ?>