summaryrefslogtreecommitdiff
path: root/lib/dijit/form/FilteringSelect.js
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2011-11-08 20:40:44 +0400
committerAndrew Dolgov <[email protected]>2011-11-08 20:40:44 +0400
commit81bea17aefb26859f825b9293c7c99192874806e (patch)
treefb244408ca271affa2899adb634788802c9a89d8 /lib/dijit/form/FilteringSelect.js
parent870a70e109ac9e80a88047044530de53d0404ec7 (diff)
upgrade Dojo to 1.6.1
Diffstat (limited to 'lib/dijit/form/FilteringSelect.js')
-rw-r--r--lib/dijit/form/FilteringSelect.js301
1 files changed, 218 insertions, 83 deletions
diff --git a/lib/dijit/form/FilteringSelect.js b/lib/dijit/form/FilteringSelect.js
index 08703226c..81b44ff3b 100644
--- a/lib/dijit/form/FilteringSelect.js
+++ b/lib/dijit/form/FilteringSelect.js
@@ -1,92 +1,227 @@
/*
- Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
-if(!dojo._hasResource["dijit.form.FilteringSelect"]){
-dojo._hasResource["dijit.form.FilteringSelect"]=true;
+if(!dojo._hasResource["dijit.form.FilteringSelect"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.FilteringSelect"] = true;
dojo.provide("dijit.form.FilteringSelect");
dojo.require("dijit.form.ComboBox");
-dojo.declare("dijit.form.FilteringSelect",[dijit.form.MappedTextBox,dijit.form.ComboBoxMixin],{_isvalid:true,required:true,_lastDisplayedValue:"",isValid:function(){
-return this._isvalid||(!this.required&&this.get("displayedValue")=="");
-},_refreshState:function(){
-if(!this.searchTimer){
-this.inherited(arguments);
-}
-},_callbackSetLabel:function(_1,_2,_3){
-if((_2&&_2.query[this.searchAttr]!=this._lastQuery)||(!_2&&_1.length&&this.store.getIdentity(_1[0])!=this._lastQuery)){
-return;
-}
-if(!_1.length){
-this.valueNode.value="";
-dijit.form.TextBox.superclass._setValueAttr.call(this,"",_3||(_3===undefined&&!this._focused));
-this._isvalid=false;
-this.validate(this._focused);
-this.item=null;
-}else{
-this.set("item",_1[0],_3);
-}
-},_openResultList:function(_4,_5){
-if(_5.query[this.searchAttr]!=this._lastQuery){
-return;
-}
-if(this.item===undefined){
-this._isvalid=_4.length!=0||this._maxOptions!=0;
-this.validate(true);
-}
-dijit.form.ComboBoxMixin.prototype._openResultList.apply(this,arguments);
-},_getValueAttr:function(){
-return this.valueNode.value;
-},_getValueField:function(){
-return "value";
-},_setValueAttr:function(_6,_7){
-if(!this._onChangeActive){
-_7=null;
-}
-this._lastQuery=_6;
-if(_6===null||_6===""){
-this._setDisplayedValueAttr("",_7);
-return;
-}
-var _8=this;
-this.store.fetchItemByIdentity({identity:_6,onItem:function(_9){
-_8._callbackSetLabel(_9?[_9]:[],undefined,_7);
-}});
-},_setItemAttr:function(_a,_b,_c){
-this._isvalid=true;
-this.inherited(arguments);
-this.valueNode.value=this.value;
-this._lastDisplayedValue=this.textbox.value;
-},_getDisplayQueryString:function(_d){
-return _d.replace(/([\\\*\?])/g,"\\$1");
-},_setDisplayedValueAttr:function(_e,_f){
-if(!this._created){
-_f=false;
-}
-if(this.store){
-this._hideResultList();
-var _10=dojo.clone(this.query);
-this._lastQuery=_10[this.searchAttr]=this._getDisplayQueryString(_e);
-this.textbox.value=_e;
-this._lastDisplayedValue=_e;
-var _11=this;
-var _12={query:_10,queryOptions:{ignoreCase:this.ignoreCase,deep:true},onComplete:function(_13,_14){
-_11._fetchHandle=null;
-dojo.hitch(_11,"_callbackSetLabel")(_13,_14,_f);
-},onError:function(_15){
-_11._fetchHandle=null;
-console.error("dijit.form.FilteringSelect: "+_15);
-dojo.hitch(_11,"_callbackSetLabel")([],undefined,false);
-}};
-dojo.mixin(_12,this.fetchProperties);
-this._fetchHandle=this.store.fetch(_12);
-}
-},postMixInProperties:function(){
-this.inherited(arguments);
-this._isvalid=!this.required;
-},undo:function(){
-this.set("displayedValue",this._lastDisplayedValue);
-}});
+
+
+dojo.declare(
+ "dijit.form.FilteringSelect",
+ [dijit.form.MappedTextBox, dijit.form.ComboBoxMixin],
+ {
+ // summary:
+ // An enhanced version of the HTML SELECT tag, populated dynamically
+ //
+ // description:
+ // An enhanced version of the HTML SELECT tag, populated dynamically. It works
+ // very nicely with very large data sets because it can load and page data as needed.
+ // It also resembles ComboBox, but does not allow values outside of the provided ones.
+ // If OPTION tags are used as the data provider via markup, then the
+ // OPTION tag's child text node is used as the displayed value when selected
+ // while the OPTION tag's value attribute is used as the widget value on form submit.
+ // To set the default value when using OPTION tags, specify the selected
+ // attribute on 1 of the child OPTION tags.
+ //
+ // Similar features:
+ // - There is a drop down list of possible values.
+ // - You can only enter a value from the drop down list. (You can't
+ // enter an arbitrary value.)
+ // - The value submitted with the form is the hidden value (ex: CA),
+ // not the displayed value a.k.a. label (ex: California)
+ //
+ // Enhancements over plain HTML version:
+ // - If you type in some text then it will filter down the list of
+ // possible values in the drop down list.
+ // - List can be specified either as a static list or via a javascript
+ // function (that can get the list from a server)
+
+ // required: Boolean
+ // True (default) if user is required to enter a value into this field.
+ required: true,
+
+ _lastDisplayedValue: "",
+
+ _isValidSubset: function(){
+ return this._opened;
+ },
+
+ isValid: function(){
+ // Overrides ValidationTextBox.isValid()
+ return this.item || (!this.required && this.get('displayedValue') == ""); // #5974
+ },
+
+ _refreshState: function(){
+ if(!this.searchTimer){ // state will be refreshed after results are returned
+ this.inherited(arguments);
+ }
+ },
+
+ _callbackSetLabel: function(
+ /*Array*/ result,
+ /*Object*/ dataObject,
+ /*Boolean?*/ priorityChange){
+ // summary:
+ // Callback from dojo.data after lookup of user entered value finishes
+
+ // setValue does a synchronous lookup,
+ // so it calls _callbackSetLabel directly,
+ // and so does not pass dataObject
+ // still need to test against _lastQuery in case it came too late
+ if((dataObject && dataObject.query[this.searchAttr] != this._lastQuery) || (!dataObject && result.length && this.store.getIdentity(result[0]) != this._lastQuery)){
+ return;
+ }
+ if(!result.length){
+ //#3268: don't modify display value on bad input
+ //#3285: change CSS to indicate error
+ this.valueNode.value = "";
+ dijit.form.TextBox.superclass._setValueAttr.call(this, "", priorityChange || (priorityChange === undefined && !this._focused));
+ this._set("item", null);
+ this.validate(this._focused);
+ }else{
+ this.set('item', result[0], priorityChange);
+ }
+ },
+
+ _openResultList: function(/*Object*/ results, /*Object*/ dataObject){
+ // Callback when a data store query completes.
+ // Overrides ComboBox._openResultList()
+
+ // #3285: tap into search callback to see if user's query resembles a match
+ if(dataObject.query[this.searchAttr] != this._lastQuery){
+ return;
+ }
+ dijit.form.ComboBoxMixin.prototype._openResultList.apply(this, arguments);
+
+ if(this.item === undefined){ // item == undefined for keyboard search
+ // If the search returned no items that means that the user typed
+ // in something invalid (and they can't make it valid by typing more characters),
+ // so flag the FilteringSelect as being in an invalid state
+ this.validate(true);
+ }
+ },
+
+ _getValueAttr: function(){
+ // summary:
+ // Hook for get('value') to work.
+
+ // don't get the textbox value but rather the previously set hidden value.
+ // Use this.valueNode.value which isn't always set for other MappedTextBox widgets until blur
+ return this.valueNode.value;
+ },
+
+ _getValueField: function(){
+ // Overrides ComboBox._getValueField()
+ return "value";
+ },
+
+ _setValueAttr: function(/*String*/ value, /*Boolean?*/ priorityChange){
+ // summary:
+ // Hook so set('value', value) works.
+ // description:
+ // Sets the value of the select.
+ // Also sets the label to the corresponding value by reverse lookup.
+ if(!this._onChangeActive){ priorityChange = null; }
+ this._lastQuery = value;
+
+ if(value === null || value === ''){
+ this._setDisplayedValueAttr('', priorityChange);
+ return;
+ }
+
+ //#3347: fetchItemByIdentity if no keyAttr specified
+ var self = this;
+ this.store.fetchItemByIdentity({
+ identity: value,
+ onItem: function(item){
+ self._callbackSetLabel(item? [item] : [], undefined, priorityChange);
+ }
+ });
+ },
+
+ _setItemAttr: function(/*item*/ item, /*Boolean?*/ priorityChange, /*String?*/ displayedValue){
+ // summary:
+ // Set the displayed valued in the input box, and the hidden value
+ // that gets submitted, based on a dojo.data store item.
+ // description:
+ // Users shouldn't call this function; they should be calling
+ // set('item', value)
+ // tags:
+ // private
+ this.inherited(arguments);
+ this.valueNode.value = this.value;
+ this._lastDisplayedValue = this.textbox.value;
+ },
+
+ _getDisplayQueryString: function(/*String*/ text){
+ return text.replace(/([\\\*\?])/g, "\\$1");
+ },
+
+ _setDisplayedValueAttr: function(/*String*/ label, /*Boolean?*/ priorityChange){
+ // summary:
+ // Hook so set('displayedValue', label) works.
+ // description:
+ // Sets textbox to display label. Also performs reverse lookup
+ // to set the hidden value. label should corresponding to item.searchAttr.
+
+ if(label == null){ label = ''; }
+
+ // This is called at initialization along with every custom setter.
+ // Usually (or always?) the call can be ignored. If it needs to be
+ // processed then at least make sure that the XHR request doesn't trigger an onChange()
+ // event, even if it returns after creation has finished
+ if(!this._created){
+ if(!("displayedValue" in this.params)){
+ return;
+ }
+ priorityChange = false;
+ }
+
+ // Do a reverse lookup to map the specified displayedValue to the hidden value.
+ // Note that if there's a custom labelFunc() this code
+ if(this.store){
+ this.closeDropDown();
+ var query = dojo.clone(this.query); // #6196: populate query with user-specifics
+ // escape meta characters of dojo.data.util.filter.patternToRegExp().
+ this._lastQuery = query[this.searchAttr] = this._getDisplayQueryString(label);
+ // If the label is not valid, the callback will never set it,
+ // so the last valid value will get the warning textbox. Set the
+ // textbox value now so that the impending warning will make
+ // sense to the user
+ this.textbox.value = label;
+ this._lastDisplayedValue = label;
+ this._set("displayedValue", label); // for watch("displayedValue") notification
+ var _this = this;
+ var fetch = {
+ query: query,
+ queryOptions: {
+ ignoreCase: this.ignoreCase,
+ deep: true
+ },
+ onComplete: function(result, dataObject){
+ _this._fetchHandle = null;
+ dojo.hitch(_this, "_callbackSetLabel")(result, dataObject, priorityChange);
+ },
+ onError: function(errText){
+ _this._fetchHandle = null;
+ console.error('dijit.form.FilteringSelect: ' + errText);
+ dojo.hitch(_this, "_callbackSetLabel")([], undefined, false);
+ }
+ };
+ dojo.mixin(fetch, this.fetchProperties);
+ this._fetchHandle = this.store.fetch(fetch);
+ }
+ },
+
+ undo: function(){
+ this.set('displayedValue', this._lastDisplayedValue);
+ }
+ }
+);
+
}