2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
5 * HTML class for an autocomplete element
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.
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
21 * @link http://pear.php.net/package/HTML_QuickForm
25 * HTML class for a text field
27 require_once 'HTML/QuickForm/text.php';
30 * HTML class for an autocomplete element
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.
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}
42 * $autocomplete =& $form->addElement('autocomplete', 'fruit', 'Favourite fruit:');
43 * $options = array("Apple", "Orange", "Pear", "Strawberry");
44 * $autocomplete->setOptions($options);
48 * @package HTML_QuickForm
49 * @author Matteo Di Giovinazzo <matteodg@infinito.it>
50 * @version Release: 3.2.16
53 class HTML_QuickForm_autocomplete extends HTML_QuickForm_text
58 * Options for the autocomplete input text element
63 var $_options = array();
66 * "One-time" javascript (containing functions), see bug #4611
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.
87 function HTML_QuickForm_autocomplete($elementName = null, $elementLabel = null, $options = null, $attributes = null)
89 $this->HTML_QuickForm_text($elementName, $elementLabel, $attributes);
90 $this->_persistantFreeze = true;
91 $this->_type = 'autocomplete';
92 if (isset($options)) {
93 $this->setOptions($options);
101 * Sets the options for the autocomplete input text element
103 * @param array $options Array of options for the autocomplete input text element
107 function setOptions($options)
109 $this->_options = array_values($options);
110 } // end func setOptions
116 * Returns Html for the autocomplete input text element
123 // prevent problems with grouped elements
124 $arrayName = str_replace(array('[', ']'), array('__', ''), $this->getName()) . '_values';
126 $this->updateAttributes(array(
127 'onkeypress' => 'return window.autocomplete(this, event, ' . $arrayName . ');'
129 if ($this->_flagFrozen) {
132 $js = "<script type=\"text/javascript\">\n//<![CDATA[\n";
133 if (!defined('HTML_QUICKFORM_AUTOCOMPLETE_EXISTS')) {
136 /* begin javascript for autocomplete */
137 function setSelectionRange(input, selectionStart, selectionEnd) {
138 if (input.setSelectionRange) {
139 input.setSelectionRange(selectionStart, selectionEnd);
141 else if (input.createTextRange) {
142 var range = input.createTextRange();
143 range.collapse(true);
144 range.moveEnd("character", selectionEnd);
145 range.moveStart("character", selectionStart);
151 function setCaretToPosition(input, position) {
152 setSelectionRange(input, position, position);
155 function replaceSelection (input, replaceString) {
156 var len = replaceString.length;
157 if (input.setSelectionRange) {
158 var selectionStart = input.selectionStart;
159 var selectionEnd = input.selectionEnd;
161 input.value = input.value.substring(0, selectionStart) + replaceString + input.value.substring(selectionEnd);
162 input.selectionStart = selectionStart + len;
163 input.selectionEnd = selectionStart + len;
165 else if (document.selection) {
166 var range = document.selection.createRange();
167 var saved_range = range.duplicate();
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);
180 function autocompleteMatch (text, values) {
181 for (var i = 0; i < values.length; i++) {
182 if (values[i].toUpperCase().indexOf(text.toUpperCase()) == 0) {
190 function autocomplete(textbox, event, values) {
191 if (textbox.setSelectionRange || textbox.createTextRange) {
192 switch (event.keyCode) {
194 case 40: // down arrow
195 case 37: // left arrow
196 case 39: // right arrow
198 case 34: // page down
207 case 20: // caps lock
214 var c = String.fromCharCode(
215 (event.charCode == undefined) ? event.keyCode : event.charCode
217 replaceSelection(textbox, c);
218 sMatch = autocompleteMatch(textbox.value, values);
219 var len = textbox.value.length;
221 if (sMatch != null) {
222 textbox.value = sMatch;
223 setSelectionRange(textbox, len, textbox.value.length);
232 /* end javascript for autocomplete */
235 define('HTML_QUICKFORM_AUTOCOMPLETE_EXISTS', true);
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";
251 $js .= "//]]>\n</script>";
253 return $js . parent::toHtml();
257 } // end class HTML_QuickForm_autocomplete