]> git.openstreetmap.org Git - chef.git/blob - cookbooks/dmca/files/default/html/HTML/QuickForm/autocomplete.php
Merge remote-tracking branch 'github/pull/426'
[chef.git] / cookbooks / dmca / files / default / html / HTML / QuickForm / autocomplete.php
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
4 /**
5  * HTML class for an autocomplete element
6  *
7  * PHP versions 4 and 5
8  *
9  * LICENSE: This source file is subject to version 3.01 of the PHP license
10  * that is available through the world-wide-web at the following URI:
11  * http://www.php.net/license/3_01.txt If you did not receive a copy of
12  * the PHP License and are unable to obtain it through the web, please
13  * send a note to license@php.net so we can mail you a copy immediately.
14  *
15  * @category    HTML
16  * @package     HTML_QuickForm
17  * @author      Matteo Di Giovinazzo <matteodg@infinito.it>
18  * @copyright   2001-2011 The PHP Group
19  * @license     http://www.php.net/license/3_01.txt PHP License 3.01
20  * @version     CVS: $Id$
21  * @link        http://pear.php.net/package/HTML_QuickForm
22  */
23
24 /**
25  * HTML class for a text field
26  */
27 require_once 'HTML/QuickForm/text.php';
28
29 /**
30  * HTML class for an autocomplete element
31  *
32  * Creates an HTML input text element that
33  * at every keypressed javascript event checks in an array of options
34  * if there's a match and autocompletes the text in case of match.
35  *
36  * For the JavaScript code thanks to Martin Honnen and Nicholas C. Zakas
37  * See {@link http://www.faqts.com/knowledge_base/view.phtml/aid/13562} and
38  * {@link http://www.sitepoint.com/article/1220}
39  *
40  * Example:
41  * <code>
42  * $autocomplete =& $form->addElement('autocomplete', 'fruit', 'Favourite fruit:');
43  * $options = array("Apple", "Orange", "Pear", "Strawberry");
44  * $autocomplete->setOptions($options);
45  * </code>
46  *
47  * @category    HTML
48  * @package     HTML_QuickForm
49  * @author      Matteo Di Giovinazzo <matteodg@infinito.it>
50  * @version     Release: 3.2.16
51  * @since       3.2
52  */
53 class HTML_QuickForm_autocomplete extends HTML_QuickForm_text
54 {
55     // {{{ properties
56
57     /**
58      * Options for the autocomplete input text element
59      *
60      * @var       array
61      * @access    private
62      */
63     var $_options = array();
64
65     /**
66      * "One-time" javascript (containing functions), see bug #4611
67      *
68      * @var     string
69      * @access  private
70      */
71     var $_js = '';
72
73     // }}}
74     // {{{ constructor
75
76     /**
77      * Class constructor
78      *
79      * @param     string    $elementName    (optional)Input field name attribute
80      * @param     string    $elementLabel   (optional)Input field label in form
81      * @param     array     $options        (optional)Autocomplete options
82      * @param     mixed     $attributes     (optional)Either a typical HTML attribute string
83      *                                      or an associative array. Date format is passed along the attributes.
84      * @access    public
85      * @return    void
86      */
87     function HTML_QuickForm_autocomplete($elementName = null, $elementLabel = null, $options = null, $attributes = null)
88     {
89         $this->HTML_QuickForm_text($elementName, $elementLabel, $attributes);
90         $this->_persistantFreeze = true;
91         $this->_type = 'autocomplete';
92         if (isset($options)) {
93             $this->setOptions($options);
94         }
95     } //end constructor
96
97     // }}}
98     // {{{ setOptions()
99
100     /**
101      * Sets the options for the autocomplete input text element
102      *
103      * @param     array    $options    Array of options for the autocomplete input text element
104      * @access    public
105      * @return    void
106      */
107     function setOptions($options)
108     {
109         $this->_options = array_values($options);
110     } // end func setOptions
111
112     // }}}
113     // {{{ toHtml()
114
115     /**
116      * Returns Html for the autocomplete input text element
117      *
118      * @access      public
119      * @return      string
120      */
121     function toHtml()
122     {
123         // prevent problems with grouped elements
124         $arrayName = str_replace(array('[', ']'), array('__', ''), $this->getName()) . '_values';
125
126         $this->updateAttributes(array(
127             'onkeypress' => 'return window.autocomplete(this, event, ' . $arrayName . ');'
128         ));
129         if ($this->_flagFrozen) {
130             $js = '';
131         } else {
132             $js = "<script type=\"text/javascript\">\n//<![CDATA[\n";
133             if (!defined('HTML_QUICKFORM_AUTOCOMPLETE_EXISTS')) {
134                 $this->_js .= <<<EOS
135
136 /* begin javascript for autocomplete */
137 function setSelectionRange(input, selectionStart, selectionEnd) {
138     if (input.setSelectionRange) {
139         input.setSelectionRange(selectionStart, selectionEnd);
140     }
141     else if (input.createTextRange) {
142         var range = input.createTextRange();
143         range.collapse(true);
144         range.moveEnd("character", selectionEnd);
145         range.moveStart("character", selectionStart);
146         range.select();
147     }
148     input.focus();
149 }
150
151 function setCaretToPosition(input, position) {
152     setSelectionRange(input, position, position);
153 }
154
155 function replaceSelection (input, replaceString) {
156         var len = replaceString.length;
157     if (input.setSelectionRange) {
158         var selectionStart = input.selectionStart;
159         var selectionEnd = input.selectionEnd;
160
161         input.value = input.value.substring(0, selectionStart) + replaceString + input.value.substring(selectionEnd);
162                 input.selectionStart  = selectionStart + len;
163                 input.selectionEnd  = selectionStart + len;
164     }
165     else if (document.selection) {
166         var range = document.selection.createRange();
167                 var saved_range = range.duplicate();
168
169         if (range.parentElement() == input) {
170             range.text = replaceString;
171                         range.moveEnd("character", saved_range.selectionStart + len);
172                         range.moveStart("character", saved_range.selectionStart + len);
173                         range.select();
174         }
175     }
176     input.focus();
177 }
178
179
180 function autocompleteMatch (text, values) {
181     for (var i = 0; i < values.length; i++) {
182         if (values[i].toUpperCase().indexOf(text.toUpperCase()) == 0) {
183             return values[i];
184         }
185     }
186
187     return null;
188 }
189
190 function autocomplete(textbox, event, values) {
191     if (textbox.setSelectionRange || textbox.createTextRange) {
192         switch (event.keyCode) {
193             case 38:    // up arrow
194             case 40:    // down arrow
195             case 37:    // left arrow
196             case 39:    // right arrow
197             case 33:    // page up
198             case 34:    // page down
199             case 36:    // home
200             case 35:    // end
201             case 13:    // enter
202             case 9:     // tab
203             case 27:    // esc
204             case 16:    // shift
205             case 17:    // ctrl
206             case 18:    // alt
207             case 20:    // caps lock
208             case 8:     // backspace
209             case 46:    // delete
210                 return true;
211                 break;
212
213             default:
214                 var c = String.fromCharCode(
215                     (event.charCode == undefined) ? event.keyCode : event.charCode
216                 );
217                 replaceSelection(textbox, c);
218                 sMatch = autocompleteMatch(textbox.value, values);
219                 var len = textbox.value.length;
220
221                 if (sMatch != null) {
222                     textbox.value = sMatch;
223                     setSelectionRange(textbox, len, textbox.value.length);
224                 }
225                 return false;
226         }
227     }
228     else {
229         return true;
230     }
231 }
232 /* end javascript for autocomplete */
233
234 EOS;
235                 define('HTML_QUICKFORM_AUTOCOMPLETE_EXISTS', true);
236             }
237             $jsEscape = array(
238                 "\r"    => '\r',
239                 "\n"    => '\n',
240                 "\t"    => '\t',
241                 "'"     => "\\'",
242                 '"'     => '\"',
243                 '\\'    => '\\\\'
244             );
245
246             $js .= $this->_js;
247             $js .= 'var ' . $arrayName . " = new Array();\n";
248             for ($i = 0; $i < count($this->_options); $i++) {
249                 $js .= $arrayName . '[' . $i . "] = '" . strtr($this->_options[$i], $jsEscape) . "';\n";
250             }
251             $js .= "//]]>\n</script>";
252         }
253         return $js . parent::toHtml();
254     }// end func toHtml
255
256     // }}}
257 } // end class HTML_QuickForm_autocomplete
258 ?>