]>
git.wh0rd.org - tt-rss.git/blob - lib/dijit/form/FilteringSelect.js
2 Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
3 Available via Academic Free License >= 2.1 OR the modified BSD license.
4 see: http://dojotoolkit.org/license for details
8 if(!dojo
._hasResource
["dijit.form.FilteringSelect"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
9 dojo
._hasResource
["dijit.form.FilteringSelect"] = true;
10 dojo
.provide("dijit.form.FilteringSelect");
11 dojo
.require("dijit.form.ComboBox");
15 "dijit.form.FilteringSelect",
16 [dijit
.form
.MappedTextBox
, dijit
.form
.ComboBoxMixin
],
19 // An enhanced version of the HTML SELECT tag, populated dynamically
22 // An enhanced version of the HTML SELECT tag, populated dynamically. It works
23 // very nicely with very large data sets because it can load and page data as needed.
24 // It also resembles ComboBox, but does not allow values outside of the provided ones.
25 // If OPTION tags are used as the data provider via markup, then the
26 // OPTION tag's child text node is used as the displayed value when selected
27 // while the OPTION tag's value attribute is used as the widget value on form submit.
28 // To set the default value when using OPTION tags, specify the selected
29 // attribute on 1 of the child OPTION tags.
32 // - There is a drop down list of possible values.
33 // - You can only enter a value from the drop down list. (You can't
34 // enter an arbitrary value.)
35 // - The value submitted with the form is the hidden value (ex: CA),
36 // not the displayed value a.k.a. label (ex: California)
38 // Enhancements over plain HTML version:
39 // - If you type in some text then it will filter down the list of
40 // possible values in the drop down list.
41 // - List can be specified either as a static list or via a javascript
42 // function (that can get the list from a server)
45 // True (default) if user is required to enter a value into this field.
48 _lastDisplayedValue
: "",
50 _isValidSubset: function(){
55 // Overrides ValidationTextBox.isValid()
56 return this.item
|| (!this.required
&& this.get('displayedValue') == ""); // #5974
59 _refreshState: function(){
60 if(!this.searchTimer
){ // state will be refreshed after results are returned
61 this.inherited(arguments
);
65 _callbackSetLabel: function(
67 /*Object*/ dataObject
,
68 /*Boolean?*/ priorityChange
){
70 // Callback from dojo.data after lookup of user entered value finishes
72 // setValue does a synchronous lookup,
73 // so it calls _callbackSetLabel directly,
74 // and so does not pass dataObject
75 // still need to test against _lastQuery in case it came too late
76 if((dataObject
&& dataObject
.query
[this.searchAttr
] != this._lastQuery
) || (!dataObject
&& result
.length
&& this.store
.getIdentity(result
[0]) != this._lastQuery
)){
80 //#3268: don't modify display value on bad input
81 //#3285: change CSS to indicate error
82 this.valueNode
.value
= "";
83 dijit
.form
.TextBox
.superclass
._setValueAttr
.call(this, "", priorityChange
|| (priorityChange
=== undefined && !this._focused
));
84 this._set("item", null);
85 this.validate(this._focused
);
87 this.set('item', result
[0], priorityChange
);
91 _openResultList: function(/*Object*/ results
, /*Object*/ dataObject
){
92 // Callback when a data store query completes.
93 // Overrides ComboBox._openResultList()
95 // #3285: tap into search callback to see if user's query resembles a match
96 if(dataObject
.query
[this.searchAttr
] != this._lastQuery
){
99 dijit
.form
.ComboBoxMixin
.prototype._openResultList
.apply(this, arguments
);
101 if(this.item
=== undefined){ // item == undefined for keyboard search
102 // If the search returned no items that means that the user typed
103 // in something invalid (and they can't make it valid by typing more characters),
104 // so flag the FilteringSelect as being in an invalid state
109 _getValueAttr: function(){
111 // Hook for get('value') to work.
113 // don't get the textbox value but rather the previously set hidden value.
114 // Use this.valueNode.value which isn't always set for other MappedTextBox widgets until blur
115 return this.valueNode
.value
;
118 _getValueField: function(){
119 // Overrides ComboBox._getValueField()
123 _setValueAttr: function(/*String*/ value
, /*Boolean?*/ priorityChange
){
125 // Hook so set('value', value) works.
127 // Sets the value of the select.
128 // Also sets the label to the corresponding value by reverse lookup.
129 if(!this._onChangeActive
){ priorityChange
= null; }
130 this._lastQuery
= value
;
132 if(value
=== null || value
=== ''){
133 this._setDisplayedValueAttr('', priorityChange
);
137 //#3347: fetchItemByIdentity if no keyAttr specified
139 this.store
.fetchItemByIdentity({
141 onItem: function(item
){
142 self
._callbackSetLabel(item
? [item
] : [], undefined, priorityChange
);
147 _setItemAttr: function(/*item*/ item
, /*Boolean?*/ priorityChange
, /*String?*/ displayedValue
){
149 // Set the displayed valued in the input box, and the hidden value
150 // that gets submitted, based on a dojo.data store item.
152 // Users shouldn't call this function; they should be calling
153 // set('item', value)
156 this.inherited(arguments
);
157 this.valueNode
.value
= this.value
;
158 this._lastDisplayedValue
= this.textbox
.value
;
161 _getDisplayQueryString: function(/*String*/ text
){
162 return text
.replace(/([\\\*\?])/g, "\\$1");
165 _setDisplayedValueAttr: function(/*String*/ label
, /*Boolean?*/ priorityChange
){
167 // Hook so set('displayedValue', label) works.
169 // Sets textbox to display label. Also performs reverse lookup
170 // to set the hidden value. label should corresponding to item.searchAttr.
172 if(label
== null){ label
= ''; }
174 // This is called at initialization along with every custom setter.
175 // Usually (or always?) the call can be ignored. If it needs to be
176 // processed then at least make sure that the XHR request doesn't trigger an onChange()
177 // event, even if it returns after creation has finished
179 if(!("displayedValue" in this.params
)){
182 priorityChange
= false;
185 // Do a reverse lookup to map the specified displayedValue to the hidden value.
186 // Note that if there's a custom labelFunc() this code
188 this.closeDropDown();
189 var query
= dojo
.clone(this.query
); // #6196: populate query with user-specifics
190 // escape meta characters of dojo.data.util.filter.patternToRegExp().
191 this._lastQuery
= query
[this.searchAttr
] = this._getDisplayQueryString(label
);
192 // If the label is not valid, the callback will never set it,
193 // so the last valid value will get the warning textbox. Set the
194 // textbox value now so that the impending warning will make
196 this.textbox
.value
= label
;
197 this._lastDisplayedValue
= label
;
198 this._set("displayedValue", label
); // for watch("displayedValue") notification
203 ignoreCase
: this.ignoreCase
,
206 onComplete: function(result
, dataObject
){
207 _this
._fetchHandle
= null;
208 dojo
.hitch(_this
, "_callbackSetLabel")(result
, dataObject
, priorityChange
);
210 onError: function(errText
){
211 _this
._fetchHandle
= null;
212 console
.error('dijit.form.FilteringSelect: ' + errText
);
213 dojo
.hitch(_this
, "_callbackSetLabel")([], undefined, false);
216 dojo
.mixin(fetch
, this.fetchProperties
);
217 this._fetchHandle
= this.store
.fetch(fetch
);
222 this.set('displayedValue', this._lastDisplayedValue
);