Subversion Repositories Applications.papyrus

Rev

Blame | Last modification | View Log | RSS feed

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],
        {
                /*
                 * summary
                 *      Enhanced version of HTML's <select> tag.
                 *
                 *      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)
                 */

                // searchAttr: String
                //              Searches pattern match against this field

                // labelAttr: String
                //              Optional.  The text that actually appears in the drop down.
                //              If not specified, the searchAttr text is used instead.
                labelAttr: "",

                // labelType: String
                //              "html" or "text"
                labelType: "text",

                _isvalid:true,

                isValid:function(){
                        return this._isvalid;
                },

                _callbackSetLabel: function(/*Array*/ result, /*Object*/ dataObject, /*Boolean, optional*/ priorityChange){
                        // summary
                        //      Callback function that dynamically sets the label of the ComboBox

                        // setValue does a synchronous lookup,
                        // so it calls _callbackSetLabel directly,
                        // and so does not pass dataObject
                        // dataObject==null means do not test the lastQuery, just continue
                        if(dataObject&&dataObject.query[this.searchAttr]!=this._lastQuery){return;}
                        if(!result.length){
                                //#3268: do nothing on bad input
                                //this._setValue("", "");
                                //#3285: change CSS to indicate error
                                if(!this._hasFocus){ this.valueNode.value=""; }
                                dijit.form.TextBox.superclass.setValue.call(this, undefined, !this._hasFocus);
                                this._isvalid=false;
                                this.validate(this._hasFocus);
                        }else{
                                this._setValueFromItem(result[0], priorityChange);
                        }
                },

                _openResultList: function(/*Object*/ results, /*Object*/ dataObject){
                        // #3285: tap into search callback to see if user's query resembles a match
                        if(dataObject.query[this.searchAttr]!=this._lastQuery){return;}
                        this._isvalid=results.length!=0;
                        this.validate(true);
                        dijit.form.ComboBoxMixin.prototype._openResultList.apply(this, arguments);
                },

                getValue:function(){
                        // don't get the textbox value but rather the previously set hidden value
                        return this.valueNode.value;
                },

                _getValueField:function(){
                        // used for option tag selects
                        return "value";
                },

                _setValue:function(/*String*/ value, /*String*/ displayedValue, /*Boolean, optional*/ priorityChange){
                        this.valueNode.value = value;
                        dijit.form.FilteringSelect.superclass.setValue.call(this, value, priorityChange, displayedValue);
                        this._lastDisplayedValue = displayedValue;
                },

                setValue: function(/*String*/ value, /*Boolean, optional*/ priorityChange){
                        // summary
                        //      Sets the value of the select.
                        //      Also sets the label to the corresponding value by reverse lookup.

                        //#3347: fetchItemByIdentity if no keyAttr specified
                        var self=this;
                        var handleFetchByIdentity = function(item, priorityChange){
                                if(item){
                                        if(self.store.isItemLoaded(item)){
                                                self._callbackSetLabel([item], undefined, priorityChange);
                                        }else{
                                                self.store.loadItem({item:item, onItem: function(result, dataObject){self._callbackSetLabel(result, dataObject, priorityChange)}});
                                        }
                                }else{
                                        self._isvalid=false;
                                        // prevent errors from Tooltip not being created yet
                                        self.validate(false);
                                }
                        }
                        this.store.fetchItemByIdentity({identity: value, onItem: function(item){handleFetchByIdentity(item, priorityChange)}});
                },

                _setValueFromItem: function(/*item*/ item, /*Boolean, optional*/ priorityChange){
                        // summary
                        //      Set the displayed valued in the input box, based on a selected item.
                        //      Users shouldn't call this function; they should be calling setDisplayedValue() instead
                        this._isvalid=true;
                        this._setValue(this.store.getIdentity(item), this.labelFunc(item, this.store), priorityChange);
                },

                labelFunc: function(/*item*/ item, /*dojo.data.store*/ store){
                        // summary: Event handler called when the label changes
                        // returns the label that the ComboBox should display
                        return store.getValue(item, this.searchAttr);
                },

                onkeyup: function(/*Event*/ evt){
                        // summary: internal function
                        // FilteringSelect needs to wait for the complete label before committing to a reverse lookup
                        //this.setDisplayedValue(this.textbox.value);
                },

                _doSelect: function(/*Event*/ tgt){
                        // summary:
                        //      ComboBox's menu callback function
                        //      FilteringSelect overrides this to set both the visible and hidden value from the information stored in the menu
                        this.item = tgt.item;
                        this._setValueFromItem(tgt.item, true);
                },

                setDisplayedValue:function(/*String*/ label){
                        // summary:
                        //      Set textbox to display label
                        //      Also performs reverse lookup to set the hidden value
                        //      Used in InlineEditBox

                        if(this.store){
                                var query={};
                                this._lastQuery=query[this.searchAttr]=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.store.fetch({query:query, queryOptions:{ignoreCase:this.ignoreCase, deep:true}, onComplete: dojo.hitch(this, this._callbackSetLabel)});
                        }
                },

                _getMenuLabelFromItem:function(/*Item*/ item){
                        // internal function to help ComboBoxMenu figure out what to display
                        if(this.labelAttr){return {html:this.labelType=="html", label:this.store.getValue(item, this.labelAttr)};}
                        else{
                                // because this function is called by ComboBoxMenu, this.inherited tries to find the superclass of ComboBoxMenu
                                return dijit.form.ComboBoxMixin.prototype._getMenuLabelFromItem.apply(this, arguments);
                        }
                },

                postMixInProperties: function(){
                        dijit.form.ComboBoxMixin.prototype.postMixInProperties.apply(this, arguments);
                        dijit.form.MappedTextBox.prototype.postMixInProperties.apply(this, arguments);
                }
        }
);

}