PageRenderTime 49ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/campsite/src/include/pear/HTML/QuickForm/autocomplete.php

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