Subversion Repositories Applications.papyrus

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
320 jpm 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: autocomplete.php,v 1.1 2005-03-30 08:50:33 jpm Exp $
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
    // {{{ constructor
58
 
59
    /**
60
     * Class constructor
61
     *
62
     * @param     string    $elementName    (optional)Input field name attribute
63
     * @param     string    $elementLabel   (optional)Input field label in form
64
     * @param     array     $options        (optional)Autocomplete options
65
     * @param     mixed     $attributes     (optional)Either a typical HTML attribute string
66
     *                                      or an associative array. Date format is passed along the attributes.
67
     * @access    public
68
     * @return    void
69
     */
70
    function HTML_QuickForm_autocomplete($elementName = null, $elementLabel = null, $options = null, $attributes = null)
71
    {
72
        $this->HTML_QuickForm_text($elementName, $elementLabel, $attributes);
73
        $this->_persistantFreeze = true;
74
        $this->_type = 'autocomplete';
75
        if (isset($options)) {
76
            $this->setOptions($options);
77
        }
78
    } //end constructor
79
 
80
    // }}}
81
    // {{{ setOptions()
82
 
83
    /**
84
     * Sets the options for the autocomplete input text element
85
     *
86
     * @param     array    $options    Array of options for the autocomplete input text element
87
     * @access    public
88
     * @return    void
89
     */
90
    function setOptions($options)
91
    {
92
        $this->_options = array_values($options);
93
    } // end func setOptions
94
 
95
    // }}}
96
    // {{{ toHtml()
97
 
98
    /**
99
     * Returns Html for the autocomplete input text element
100
     *
101
     * @access      public
102
     * @return      string
103
     */
104
    function toHtml()
105
    {
106
        // prevent problems with grouped elements
107
        $arrayName = str_replace(array('[', ']'), array('__', ''), $this->getName()) . '_values';
108
 
109
        $this->updateAttributes(array(
110
            'onkeypress' => 'return autocomplete(this, event, ' . $arrayName . ');'
111
        ));
112
        if ($this->_flagFrozen) {
113
            $js = '';
114
        } else {
115
            $js = "<script type=\"text/javascript\">\n//<![CDATA[\n";
116
            if (!defined('HTML_QUICKFORM_AUTOCOMPLETE_EXISTS')) {
117
                $js .= <<<EOS
118
 
119
/* begin javascript for autocomplete */
120
function setSelectionRange(input, selectionStart, selectionEnd) {
121
    if (input.setSelectionRange) {
122
        input.setSelectionRange(selectionStart, selectionEnd);
123
    }
124
    else if (input.createTextRange) {
125
        var range = input.createTextRange();
126
        range.collapse(true);
127
        range.moveEnd("character", selectionEnd);
128
        range.moveStart("character", selectionStart);
129
        range.select();
130
    }
131
    input.focus();
132
}
133
 
134
function setCaretToPosition(input, position) {
135
    setSelectionRange(input, position, position);
136
}
137
 
138
function replaceSelection (input, replaceString) {
139
	var len = replaceString.length;
140
    if (input.setSelectionRange) {
141
        var selectionStart = input.selectionStart;
142
        var selectionEnd = input.selectionEnd;
143
 
144
        input.value = input.value.substring(0, selectionStart) + replaceString + input.value.substring(selectionEnd);
145
		input.selectionStart  = selectionStart + len;
146
		input.selectionEnd  = selectionStart + len;
147
    }
148
    else if (document.selection) {
149
        var range = document.selection.createRange();
150
		var saved_range = range.duplicate();
151
 
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
 
162
 
163
function autocompleteMatch (text, values) {
164
    for (var i = 0; i < values.length; i++) {
165
        if (values[i].toUpperCase().indexOf(text.toUpperCase()) == 0) {
166
            return values[i];
167
        }
168
    }
169
 
170
    return null;
171
}
172
 
173
function autocomplete(textbox, event, values) {
174
    if (textbox.setSelectionRange || textbox.createTextRange) {
175
        switch (event.keyCode) {
176
            case 38:    // up arrow
177
            case 40:    // down arrow
178
            case 37:    // left arrow
179
            case 39:    // right arrow
180
            case 33:    // page up
181
            case 34:    // page down
182
            case 36:    // home
183
            case 35:    // end
184
            case 13:    // enter
185
            case 9:     // tab
186
            case 27:    // esc
187
            case 16:    // shift
188
            case 17:    // ctrl
189
            case 18:    // alt
190
            case 20:    // caps lock
191
            case 8:     // backspace
192
            case 46:    // delete
193
                return true;
194
                break;
195
 
196
            default:
197
                var c = String.fromCharCode(
198
                    (event.charCode == undefined) ? event.keyCode : event.charCode
199
                );
200
                replaceSelection(textbox, c);
201
                sMatch = autocompleteMatch(textbox.value, values);
202
                var len = textbox.value.length;
203
 
204
                if (sMatch != null) {
205
                    textbox.value = sMatch;
206
                    setSelectionRange(textbox, len, textbox.value.length);
207
                }
208
                return false;
209
        }
210
    }
211
    else {
212
        return true;
213
    }
214
}
215
/* end javascript for autocomplete */
216
 
217
EOS;
218
                define('HTML_QUICKFORM_AUTOCOMPLETE_EXISTS', true);
219
            }
220
            $jsEscape = array(
221
                "\r"    => '\r',
222
                "\n"    => '\n',
223
                "\t"    => '\t',
224
                "'"     => "\\'",
225
                '"'     => '\"',
226
                '\\'    => '\\\\'
227
            );
228
 
229
            $js .= 'var ' . $arrayName . " = new Array();\n";
230
            for ($i = 0; $i < count($this->_options); $i++) {
231
                $js .= $arrayName . '[' . $i . "] = '" . strtr($this->_options[$i], $jsEscape) . "';\n";
232
            }
233
            $js .= "//]]>\n</script>";
234
        }
235
        return $js . parent::toHtml();
236
    }// end func toHtml
237
 
238
    // }}}
239
} // end class HTML_QuickForm_autocomplete
240
?>