]> git.pond.sub.org Git - eow/blob - static/dojo-release-1.1.1/dijit/form/FilteringSelect.js
add Dojo 1.1.1
[eow] / static / dojo-release-1.1.1 / dijit / form / FilteringSelect.js
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");
4
5 dojo.require("dijit.form.ComboBox");
6
7 dojo.declare(
8         "dijit.form.FilteringSelect",
9         [dijit.form.MappedTextBox, dijit.form.ComboBoxMixin],
10         {
11                 // summary
12                 // An enhanced version of the HTML SELECT tag, populated dynamically
13                 //
14                 // description
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.
18                 //  
19                 // Similar features:
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)
25                 // 
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)
31                 //
32                 // searchAttr: String
33                 //              Searches pattern match against this field
34                 //
35                 // labelAttr: String
36                 //              Optional.  The text that actually appears in the drop down.
37                 //              If not specified, the searchAttr text is used instead.
38                 labelAttr: "",
39
40                 // labelType: String
41                 //              "html" or "text"
42                 labelType: "text",
43
44                 _isvalid:true,
45
46                 _lastDisplayedValue: "",
47
48                 isValid:function(){
49                         return this._isvalid;
50                 },
51
52                 _callbackSetLabel: function(    /*Array*/ result, 
53                                                 /*Object*/ dataObject, 
54                                                 /*Boolean?*/ priorityChange){
55                         // summary:
56                         //              Callback function that dynamically sets the label of the
57                         //              ComboBox
58
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){
64                                 return;
65                         }
66                         if(!result.length){
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);
72                                 this._isvalid=false;
73                                 this.validate(this._focused);
74                         }else{
75                                 this._setValueFromItem(result[0], priorityChange);
76                         }
77                 },
78
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){
82                                 return;
83                         }
84                         this._isvalid = results.length != 0; // FIXME: should this be greater-than?
85                         this.validate(true);
86                         dijit.form.ComboBoxMixin.prototype._openResultList.apply(this, arguments);
87                 },
88
89                 getValue:function(){
90                         // don't get the textbox value but rather the previously set hidden value
91                         return this.valueNode.value;
92                 },
93
94                 _getValueField:function(){
95                         // used for option tag selects
96                         return "value";
97                 },
98
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;
105                 },
106
107                 setValue: function(/*String*/ value, /*Boolean?*/ priorityChange){
108                         // summary
109                         //      Sets the value of the select.
110                         //      Also sets the label to the corresponding value by reverse lookup.
111
112                         //#3347: fetchItemByIdentity if no keyAttr specified
113                         var self=this;
114                         var handleFetchByIdentity = function(item, priorityChange){
115                                 if(item){
116                                         if(self.store.isItemLoaded(item)){
117                                                 self._callbackSetLabel([item], undefined, priorityChange);
118                                         }else{
119                                                 self.store.loadItem({
120                                                         item: item, 
121                                                         onItem: function(result, dataObject){
122                                                                 self._callbackSetLabel(result, dataObject, priorityChange);
123                                                         }
124                                                 });
125                                         }
126                                 }else{
127                                         self._isvalid=false;
128                                         // prevent errors from Tooltip not being created yet
129                                         self.validate(false);
130                                 }
131                         }
132                         this.store.fetchItemByIdentity({
133                                 identity: value, 
134                                 onItem: function(item){
135                                         handleFetchByIdentity(item, priorityChange);
136                                 }
137                         });
138                 },
139
140                 _setValueFromItem: function(/*item*/ item, /*Boolean?*/ priorityChange){
141                         //      summary:
142                         //              Set the displayed valued in the input box, based on a
143                         //              selected item.
144                         //      description:
145                         //              Users shouldn't call this function; they should be calling
146                         //              setDisplayedValue() instead
147                         this._isvalid=true;
148                         this._setValue( this.store.getIdentity(item), 
149                                                         this.labelFunc(item, this.store), 
150                                                         priorityChange);
151                 },
152
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);
157                 },
158
159                 _doSelect: function(/*Event*/ tgt){
160                         // summary:
161                         //              ComboBox's menu callback function
162                         //      description:
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);
167                 },
168
169                 setDisplayedValue:function(/*String*/ label, /*Boolean?*/ priorityChange){
170                         // summary:
171                         //              Set textbox to display label. Also performs reverse lookup
172                         //              to set the hidden value. Used in InlineEditBox
173
174                         if(this.store){
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
180                                 // sense to the user
181                                 this.textbox.value = label;
182                                 this._lastDisplayedValue = label;
183                                 var _this = this;
184                                 this.store.fetch({
185                                         query: query, 
186                                         queryOptions: {
187                                                 ignoreCase: this.ignoreCase, 
188                                                 deep: true
189                                         }, 
190                                         onComplete: function(result, dataObject){
191                                                         dojo.hitch(_this, "_callbackSetLabel")(result, dataObject, priorityChange);
192                                         },
193                                         onError: function(errText){
194                                                 console.error('dijit.form.FilteringSelect: ' + errText);
195                                                 dojo.hitch(_this, "_setValue")(undefined, label, false);
196                                         }
197                                 });
198                         }
199                 },
200
201                 _getMenuLabelFromItem:function(/*Item*/ item){
202                         // internal function to help ComboBoxMenu figure out what to display
203                         if(this.labelAttr){
204                                 return {
205                                         html: this.labelType=="html", 
206                                         label: this.store.getValue(item, this.labelAttr)
207                                 };
208                         }else{
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);
212                         }
213                 },
214
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);
219                 },
220
221                 postCreate: function(){
222                         dijit.form.ComboBoxMixin.prototype._postCreate.apply(this, arguments);
223                         dijit.form.MappedTextBox.prototype.postCreate.apply(this, arguments);
224                 },
225                 
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);
229                 },
230
231                 undo: function(){
232                         this.setDisplayedValue(this._lastDisplayedValue);
233                 },
234
235                 _valueChanged: function(){
236                         return this.getDisplayedValue()!=this._lastDisplayedValue;
237                 }
238         }
239 );
240
241 }