Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
?>