1 <?php 2 /* vim: set expandtab tabstop=4 shiftwidth=4: */ 3 // +----------------------------------------------------------------------+ 4 // | PHP Version 4 | 5 // +----------------------------------------------------------------------+ 6 // | Copyright (c) 1997-2003 The PHP Group | 7 // +----------------------------------------------------------------------+ 8 // | This source file is subject to version 2.0 of the PHP license, | 9 // | that is bundled with this package in the file LICENSE, and is | 10 // | available at through the world-wide-web at | 11 // | http://www.php.net/license/2_02.txt. | 12 // | If you did not receive a copy of the PHP license and are unable to | 13 // | obtain it through the world-wide-web, please send a note to | 14 // | license@php.net so we can mail you a copy immediately. | 15 // +----------------------------------------------------------------------+ 16 // | Author: Matteo Di Giovinazzo <matteodg@infinito.it> | 17 // | | 18 // | For the JavaScript code thanks to Martin Honnen and | 19 // | Nicholas C. Zakas | 20 // | See: | 21 // | http://www.faqts.com/knowledge_base/view.phtml/aid/13562 | 22 // | and | 23 // | http://www.sitepoint.com/article/1220 | 24 // +----------------------------------------------------------------------+ 25 // 26 // $Id$ 27 28 29 require_once("HTML/QuickForm/text.php"); 30 31 32 /** 33 * Class to dynamically create an HTML input text element that 34 * at every keypressed javascript event, check in an array of options 35 * if there's a match and autocomplete the text in case of match. 36 * 37 * Ex: 38 * $autocomplete =& $form->addElement('autocomplete', 'fruit', 'Favourite fruit:'); 39 * $options = array("Apple", "Orange", "Pear", "Strawberry"); 40 * $autocomplete->setOptions($options); 41 * 42 * @author Matteo Di Giovinazzo <matteodg@infinito.it> 43 */ 44 class HTML_QuickForm_autocomplete extends HTML_QuickForm_text 45 { 46 // {{{ properties 47 48 /** 49 * Options for the autocomplete input text element 50 * 51 * @var array 52 * @access private 53 */ 54 var $_options = array(); 55 56 /** 57 * "One-time" javascript (containing functions), see bug #4611 58 * 59 * @var string 60 * @access private 61 */ 62 var $_js = ''; 63 64 // }}} 65 // {{{ constructor 66 67 /** 68 * Class constructor 69 * 70 * @param string $elementName (optional)Input field name attribute 71 * @param string $elementLabel (optional)Input field label in form 72 * @param array $options (optional)Autocomplete options 73 * @param mixed $attributes (optional)Either a typical HTML attribute string 74 * or an associative array. Date format is passed along the attributes. 75 * @access public 76 * @return void 77 */ 78 public function __construct($elementName = null, $elementLabel = null, $options = null, $attributes = null) { 79 parent::__construct($elementName, $elementLabel, $attributes); 80 $this->_persistantFreeze = true; 81 $this->_type = 'autocomplete'; 82 if (isset($options)) { 83 $this->setOptions($options); 84 } 85 } //end constructor 86 87 /** 88 * Old syntax of class constructor. Deprecated in PHP7. 89 * 90 * @deprecated since Moodle 3.1 91 */ 92 public function HTML_QuickForm_autocomplete($elementName = null, $elementLabel = null, $options = null, $attributes = null) { 93 debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER); 94 self::__construct($elementName, $elementLabel, $options, $attributes); 95 } 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 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 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body