1 if(!dojo._hasResource["dijit.form.FilteringSelect"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dijit.form.FilteringSelect"] = true;
3 dojo.provide("dijit.form.FilteringSelect");
5 dojo.require("dijit.form.ComboBox");
8 "dijit.form.FilteringSelect",
9 [dijit.form.MappedTextBox, dijit.form.ComboBoxMixin],
12 // An enhanced version of the HTML SELECT tag, populated dynamically
15 // An enhanced version of the HTML SELECT tag, populated dynamically. It works
16 // very nicely with very large data sets because it can load and page data as needed.
17 // It also resembles ComboBox, but does not allow values outside of the provided ones.
20 // - There is a drop down list of possible values.
21 // - You can only enter a value from the drop down list. (You can't
22 // enter an arbitrary value.)
23 // - The value submitted with the form is the hidden value (ex: CA),
24 // not the displayed value a.k.a. label (ex: California)
26 // Enhancements over plain HTML version:
27 // - If you type in some text then it will filter down the list of
28 // possible values in the drop down list.
29 // - List can be specified either as a static list or via a javascript
30 // function (that can get the list from a server)
33 // Searches pattern match against this field
36 // Optional. The text that actually appears in the drop down.
37 // If not specified, the searchAttr text is used instead.
46 _lastDisplayedValue: "",
52 _callbackSetLabel: function( /*Array*/ result,
53 /*Object*/ dataObject,
54 /*Boolean?*/ priorityChange){
56 // Callback function that dynamically sets the label of the
59 // setValue does a synchronous lookup,
60 // so it calls _callbackSetLabel directly,
61 // and so does not pass dataObject
62 // dataObject==null means do not test the lastQuery, just continue
63 if(dataObject && dataObject.query[this.searchAttr] != this._lastQuery){
67 //#3268: do nothing on bad input
68 //this._setValue("", "");
69 //#3285: change CSS to indicate error
70 if(!this._focused){ this.valueNode.value=""; }
71 dijit.form.TextBox.superclass.setValue.call(this, undefined, !this._focused);
73 this.validate(this._focused);
75 this._setValueFromItem(result[0], priorityChange);
79 _openResultList: function(/*Object*/ results, /*Object*/ dataObject){
80 // #3285: tap into search callback to see if user's query resembles a match
81 if(dataObject.query[this.searchAttr] != this._lastQuery){
84 this._isvalid = results.length != 0; // FIXME: should this be greater-than?
86 dijit.form.ComboBoxMixin.prototype._openResultList.apply(this, arguments);
90 // don't get the textbox value but rather the previously set hidden value
91 return this.valueNode.value;
94 _getValueField:function(){
95 // used for option tag selects
99 _setValue:function( /*String*/ value,
100 /*String*/ displayedValue,
101 /*Boolean?*/ priorityChange){
102 this.valueNode.value = value;
103 dijit.form.FilteringSelect.superclass.setValue.call(this, value, priorityChange, displayedValue);
104 this._lastDisplayedValue = displayedValue;
107 setValue: function(/*String*/ value, /*Boolean?*/ priorityChange){
109 // Sets the value of the select.
110 // Also sets the label to the corresponding value by reverse lookup.
112 //#3347: fetchItemByIdentity if no keyAttr specified
114 var handleFetchByIdentity = function(item, priorityChange){
116 if(self.store.isItemLoaded(item)){
117 self._callbackSetLabel([item], undefined, priorityChange);
119 self.store.loadItem({
121 onItem: function(result, dataObject){
122 self._callbackSetLabel(result, dataObject, priorityChange);
128 // prevent errors from Tooltip not being created yet
129 self.validate(false);
132 this.store.fetchItemByIdentity({
134 onItem: function(item){
135 handleFetchByIdentity(item, priorityChange);
140 _setValueFromItem: function(/*item*/ item, /*Boolean?*/ priorityChange){
142 // Set the displayed valued in the input box, based on a
145 // Users shouldn't call this function; they should be calling
146 // setDisplayedValue() instead
148 this._setValue( this.store.getIdentity(item),
149 this.labelFunc(item, this.store),
153 labelFunc: function(/*item*/ item, /*dojo.data.store*/ store){
154 // summary: Event handler called when the label changes
155 // return: the label that the ComboBox should display
156 return store.getValue(item, this.searchAttr);
159 _doSelect: function(/*Event*/ tgt){
161 // ComboBox's menu callback function
163 // FilteringSelect overrides this to set both the visible and
164 // hidden value from the information stored in the menu
165 this.item = tgt.item;
166 this._setValueFromItem(tgt.item, true);
169 setDisplayedValue:function(/*String*/ label, /*Boolean?*/ priorityChange){
171 // Set textbox to display label. Also performs reverse lookup
172 // to set the hidden value. Used in InlineEditBox
175 var query = dojo.clone(this.query); // #6196: populate query with user-specifics
176 this._lastQuery = query[this.searchAttr] = label;
177 // if the label is not valid, the callback will never set it,
178 // so the last valid value will get the warning textbox set the
179 // textbox value now so that the impending warning will make
181 this.textbox.value = label;
182 this._lastDisplayedValue = label;
187 ignoreCase: this.ignoreCase,
190 onComplete: function(result, dataObject){
191 dojo.hitch(_this, "_callbackSetLabel")(result, dataObject, priorityChange);
193 onError: function(errText){
194 console.error('dijit.form.FilteringSelect: ' + errText);
195 dojo.hitch(_this, "_setValue")(undefined, label, false);
201 _getMenuLabelFromItem:function(/*Item*/ item){
202 // internal function to help ComboBoxMenu figure out what to display
205 html: this.labelType=="html",
206 label: this.store.getValue(item, this.labelAttr)
209 // because this function is called by ComboBoxMenu,
210 // this.inherited tries to find the superclass of ComboBoxMenu
211 return dijit.form.ComboBoxMixin.prototype._getMenuLabelFromItem.apply(this, arguments);
215 postMixInProperties: function(){
216 // FIXME: shouldn't this just be a call to inherited?
217 dijit.form.ComboBoxMixin.prototype.postMixInProperties.apply(this, arguments);
218 dijit.form.MappedTextBox.prototype.postMixInProperties.apply(this, arguments);
221 postCreate: function(){
222 dijit.form.ComboBoxMixin.prototype._postCreate.apply(this, arguments);
223 dijit.form.MappedTextBox.prototype.postCreate.apply(this, arguments);
226 setAttribute: function(/*String*/ attr, /*anything*/ value){
227 dijit.form.MappedTextBox.prototype.setAttribute.apply(this, arguments);
228 dijit.form.ComboBoxMixin.prototype._setAttribute.apply(this, arguments);
232 this.setDisplayedValue(this._lastDisplayedValue);
235 _valueChanged: function(){
236 return this.getDisplayedValue()!=this._lastDisplayedValue;