CAutoComplete.php
10.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
<?php
/**
* CAutoComplete class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright © 2008-2011 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
/**
* CAutoComplete generates an auto-complete text field.
*
* CAutoComplete is based on the {@link http://plugins.jquery.com/project/autocompletex jQuery Autocomplete}.
*
* This class is deprecated since Yii 1.1.3. Consider using CJuiAutoComplete.
* There is {@link http://www.learningjquery.com/2010/06/autocomplete-migration-guide a good migration guide from the author of both JavaScript solutions}.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id$
* @package system.web.widgets
* @since 1.0
* @deprecated in 1.1.3
*/
class CAutoComplete extends CInputWidget
{
/**
* @var boolean whether to show the autocomplete using a text area. Defaults to false,
* meaning a text field is used.
*/
public $textArea=false;
/**
* @var array data that would be saved as client-side data to provide candidate selections.
* Each array element can be string or an associative array.
* The {@link url} property will be ignored if this property is set.
* @see url
*/
public $data;
/**
* @var string|array the URL that can return the candidate selections.
* A 'q' GET parameter will be sent with the URL which contains what the user has entered so far.
* If the URL is given as an array, it is considered as a route to a controller action and will
* be used to generate a URL using {@link CController::createUrl};
* If the URL is an empty string, the currently requested URL is used.
* This property will be ignored if {@link data} is set.
* @see data
*/
public $url='';
/**
* @var mixed the CSS file used for the widget. Defaults to null, meaning
* using the default CSS file included together with the widget.
* If false, no CSS file will be used. Otherwise, the specified CSS file
* will be included when using this widget.
*/
public $cssFile;
/**
* @var integer the minimum number of characters a user has to type before
* the autocompleter activates. Defaults to 1.
*/
public $minChars;
/**
* @var integer the delay in milliseconds the autocompleter waits after
* a keystroke to activate itself. Defaults to 400.
*/
public $delay;
/**
* @var integer the number of backend query results to store in cache.
* If set to 1 (the current result), no caching will happen. Must be >= 1. Defaults to 10.
*/
public $cacheLength;
/**
* @var boolean whether or not the autocompleter can use a cache for more
* specific queries. This means that all matches of "foot" are a subset
* of all matches for "foo". Usually this is true, and using this options
* decreases server load and increases performance. Only useful with
* cacheLength settings bigger than one, like 10. Defaults to true.
*/
public $matchSubset;
/**
* @var boolean whether or not the comparison is case sensitive. Important
* only if you use caching. Defaults to false.
*/
public $matchCase;
/**
* @var boolean whether or not the comparison looks inside
* (i.e. does "ba" match "foo bar") the search results. Important only if
* you use caching. Don't mix with autofill. Defaults to false.
*/
public $matchContains;
/**
* @var boolean if set to true, the autocompleter will only allow results that
* are presented by the backend. Note that illegal values result in an empty
* input box. Defaults to false.
*/
public $mustMatch;
/**
* @var boolean if this is set to true, the first autocomplete value will
* be automatically selected on tab/return, even if it has not been handpicked
* by keyboard or mouse action. If there is a handpicked (highlighted) result,
* that result will take precedence. Defaults to true.
*/
public $selectFirst;
/**
* @var array extra parameters for the backend. If you were to specify
* array('bar'=>4), the autocompleter would call the backend with a GET
* parameter 'bar' 4. The param can be a function that is called to calculate
* the param before each request.
*/
public $extraParams;
/**
* @var string a javascript function that provides advanced markup for an item.
* For each row of results, this function will be called. The returned value will
* be displayed inside an LI element in the results list. Autocompleter will
* provide 4 parameters: the results row, the position of the row in the list of
* results (starting at 1), the number of items in the list of results and the search term.
* The default behavior assumes that a single row contains a single value.
*/
public $formatItem;
/**
* @var string a javascript function that can be used to limit the data that autocomplete
* searches for matches. For example, there may be items you want displayed to the user,
* but don't want included in the data that's searched. The function is called with the same arguments
* as {@link formatItem}. Defaults to formatItem.
*/
public $formatMatch;
/**
* @var string a javascript function that provides the formatting for the value to be
* put into the input field. Again three arguments: Data, position (starting with one) and
* total number of data. The default behavior assumes either plain data to use as result
* or uses the same value as provided by formatItem.
*/
public $formatResult;
/**
* @var boolean whether to allow more than one autocompleted-value to enter. Defaults to false.
*/
public $multiple;
/**
* @var string seperator to put between values when using multiple option. Defaults to ", ".
*/
public $multipleSeparator;
/**
* @var integer specify a custom width for the select box. Defaults to the width of the input element.
*/
public $width;
/**
* @var boolean fill the textinput while still selecting a value, replacing the value
* if more is typed or something else is selected. Defaults to false.
*/
public $autoFill;
/**
* @var integer limit the number of items in the select box. Is also sent as
* a "limit" parameter with a remote request. Defaults to 10.
*/
public $max;
/**
* @var boolean|string Whether and how to highlight matches in the select box.
* Set to false to disable. Set to a javascript function to customize.
* The function gets the value as the first argument and the search term as the
* second and must return the formatted value. Defaults to Wraps the search term in a <strong> element.
*/
public $highlight;
/**
* @var boolean whether to scroll when more results than configured via scrollHeight are available. Defaults to true.
*/
public $scroll;
/**
* @var integer height of scrolled autocomplete control in pixels. Defaults to 180.
*/
public $scrollHeight;
/**
* @var string the CSS class for the input element. Defaults to "ac_input".
*/
public $inputClass;
/**
* @var string the CSS class for the dropdown list. Defaults to "ac_results".
*/
public $resultsClass;
/**
* @var string the CSS class used when the data is being loaded from backend. Defaults to "ac_loading".
*/
public $loadingClass;
/**
* @var array additional options that can be passed to the constructor of the autocomplete js object.
* This allows you to override existing functions of the autocomplete js class (e.g. the parse() function)
*
* If you want to provide JavaScript native code, you have to wrap the string with {@link CJavaScriptExpression} otherwise it will
* be enclosed by quotes.
*/
public $options=array();
/**
* @var string the chain of method calls that would be appended at the end of the autocomplete constructor.
* For example, ".result(function(...){})" would cause the specified js function to execute
* when the user selects an option.
*/
public $methodChain;
/**
* Initializes the widget.
* This method registers all needed client scripts and renders
* the autocomplete input.
*/
public function init()
{
list($name,$id)=$this->resolveNameID();
if(isset($this->htmlOptions['id']))
$id=$this->htmlOptions['id'];
else
$this->htmlOptions['id']=$id;
if(isset($this->htmlOptions['name']))
$name=$this->htmlOptions['name'];
$this->registerClientScript();
if($this->hasModel())
{
$field=$this->textArea ? 'activeTextArea' : 'activeTextField';
echo CHtml::$field($this->model,$this->attribute,$this->htmlOptions);
}
else
{
$field=$this->textArea ? 'textArea' : 'textField';
echo CHtml::$field($name,$this->value,$this->htmlOptions);
}
}
/**
* Registers the needed CSS and JavaScript.
*/
public function registerClientScript()
{
$id=$this->htmlOptions['id'];
$acOptions=$this->getClientOptions();
$options=$acOptions===array()?'{}' : CJavaScript::encode($acOptions);
$cs=Yii::app()->getClientScript();
$cs->registerCoreScript('autocomplete');
if($this->data!==null)
$data=CJavaScript::encode($this->data);
else
{
$url=CHtml::normalizeUrl($this->url);
$data='"'.$url.'"';
}
$cs->registerScript('Yii.CAutoComplete#'.$id,"jQuery(\"#{$id}\").legacyautocomplete($data,{$options}){$this->methodChain};");
if($this->cssFile!==false)
self::registerCssFile($this->cssFile);
}
/**
* Registers the needed CSS file.
* @param string $url the CSS URL. If null, a default CSS URL will be used.
*/
public static function registerCssFile($url=null)
{
$cs=Yii::app()->getClientScript();
if($url===null)
$url=$cs->getCoreScriptUrl().'/autocomplete/jquery.autocomplete.css';
$cs->registerCssFile($url);
}
/**
* @return array the javascript options
*/
protected function getClientOptions()
{
static $properties=array(
'minChars', 'delay', 'cacheLength', 'matchSubset',
'matchCase', 'matchContains', 'mustMatch', 'selectFirst',
'extraParams', 'multiple', 'multipleSeparator', 'width',
'autoFill', 'max', 'scroll', 'scrollHeight', 'inputClass',
'resultsClass', 'loadingClass');
static $functions=array('formatItem', 'formatMatch', 'formatResult', 'highlight');
$options=$this->options;
foreach($properties as $property)
{
if($this->$property!==null)
$options[$property]=$this->$property;
}
foreach($functions as $func)
{
if($this->$func!==null)
{
if($this->$func instanceof CJavaScriptExpression)
$options[$func]=$this->$func;
else
$options[$func]=new CJavaScriptExpression($this->$func);
}
}
return $options;
}
}