diff options
Diffstat (limited to 'lib/dijit/form/_FormSelectWidget.js')
-rw-r--r-- | lib/dijit/form/_FormSelectWidget.js | 867 |
1 files changed, 571 insertions, 296 deletions
diff --git a/lib/dijit/form/_FormSelectWidget.js b/lib/dijit/form/_FormSelectWidget.js index 5905c0aef..fbbf7226b 100644 --- a/lib/dijit/form/_FormSelectWidget.js +++ b/lib/dijit/form/_FormSelectWidget.js @@ -1,307 +1,582 @@ /* - 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._FormSelectWidget"]){ -dojo._hasResource["dijit.form._FormSelectWidget"]=true; +if(!dojo._hasResource["dijit.form._FormSelectWidget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.form._FormSelectWidget"] = true; dojo.provide("dijit.form._FormSelectWidget"); dojo.require("dijit.form._FormWidget"); dojo.require("dojo.data.util.sorter"); -dojo.declare("dijit.form._FormSelectWidget",dijit.form._FormValueWidget,{multiple:false,options:null,store:null,query:null,queryOptions:null,onFetch:null,sortByLabel:true,loadChildrenOnOpen:false,getOptions:function(_1){ -var _2=_1,_3=this.options||[],l=_3.length; -if(_2===undefined){ -return _3; -} -if(dojo.isArray(_2)){ -return dojo.map(_2,"return this.getOptions(item);",this); -} -if(dojo.isObject(_1)){ -if(!dojo.some(this.options,function(o,_4){ -if(o===_2||(o.value&&o.value===_2.value)){ -_2=_4; -return true; -} -return false; -})){ -_2=-1; -} -} -if(typeof _2=="string"){ -for(var i=0;i<l;i++){ -if(_3[i].value===_2){ -_2=i; -break; -} -} -} -if(typeof _2=="number"&&_2>=0&&_2<l){ -return this.options[_2]; -} -return null; -},addOption:function(_5){ -if(!dojo.isArray(_5)){ -_5=[_5]; -} -dojo.forEach(_5,function(i){ -if(i&&dojo.isObject(i)){ -this.options.push(i); -} -},this); -this._loadChildren(); -},removeOption:function(_6){ -if(!dojo.isArray(_6)){ -_6=[_6]; -} -var _7=this.getOptions(_6); -dojo.forEach(_7,function(i){ -if(i){ -this.options=dojo.filter(this.options,function(_8,_9){ -return (_8.value!==i.value); -}); -this._removeOptionItem(i); -} -},this); -this._loadChildren(); -},updateOption:function(_a){ -if(!dojo.isArray(_a)){ -_a=[_a]; -} -dojo.forEach(_a,function(i){ -var _b=this.getOptions(i),k; -if(_b){ -for(k in i){ -_b[k]=i[k]; -} -} -},this); -this._loadChildren(); -},setStore:function(_c,_d,_e){ -var _f=this.store; -_e=_e||{}; -if(_f!==_c){ -dojo.forEach(this._notifyConnections||[],dojo.disconnect); -delete this._notifyConnections; -if(_c&&_c.getFeatures()["dojo.data.api.Notification"]){ -this._notifyConnections=[dojo.connect(_c,"onNew",this,"_onNewItem"),dojo.connect(_c,"onDelete",this,"_onDeleteItem"),dojo.connect(_c,"onSet",this,"_onSetItem")]; -} -this.store=_c; -} -this._onChangeActive=false; -if(this.options&&this.options.length){ -this.removeOption(this.options); -} -if(_c){ -var cb=function(_10){ -if(this.sortByLabel&&!_e.sort&&_10.length){ -_10.sort(dojo.data.util.sorter.createSortFunction([{attribute:_c.getLabelAttributes(_10[0])[0]}],_c)); -} -if(_e.onFetch){ -_10=_e.onFetch(_10); -} -dojo.forEach(_10,function(i){ -this._addOptionForItem(i); -},this); -this._loadingStore=false; -this.set("value",(("_pendingValue" in this)?this._pendingValue:_d)); -delete this._pendingValue; -if(!this.loadChildrenOnOpen){ -this._loadChildren(); -}else{ -this._pseudoLoadChildren(_10); -} -this._fetchedWith=_11; -this._lastValueReported=this.multiple?[]:null; -this._onChangeActive=true; -this.onSetStore(); -this._handleOnChange(this.value); -}; -var _11=dojo.mixin({onComplete:cb,scope:this},_e); -this._loadingStore=true; -_c.fetch(_11); -}else{ -delete this._fetchedWith; -} -return _f; -},_setValueAttr:function(_12,_13){ -if(this._loadingStore){ -this._pendingValue=_12; -return; -} -var _14=this.getOptions()||[]; -if(!dojo.isArray(_12)){ -_12=[_12]; -} -dojo.forEach(_12,function(i,idx){ -if(!dojo.isObject(i)){ -i=i+""; -} -if(typeof i==="string"){ -_12[idx]=dojo.filter(_14,function(_15){ -return _15.value===i; -})[0]||{value:"",label:""}; -} -},this); -_12=dojo.filter(_12,function(i){ -return i&&i.value; -}); -if(!this.multiple&&(!_12[0]||!_12[0].value)&&_14.length){ -_12[0]=_14[0]; -} -dojo.forEach(_14,function(i){ -i.selected=dojo.some(_12,function(v){ -return v.value===i.value; -}); -}); -var val=dojo.map(_12,function(i){ -return i.value; -}),_16=dojo.map(_12,function(i){ -return i.label; -}); -this.value=this.multiple?val:val[0]; -this._setDisplay(this.multiple?_16:_16[0]); -this._updateSelection(); -this._handleOnChange(this.value,_13); -},_getDisplayedValueAttr:function(){ -var val=this.get("value"); -if(!dojo.isArray(val)){ -val=[val]; -} -var ret=dojo.map(this.getOptions(val),function(v){ -if(v&&"label" in v){ -return v.label; -}else{ -if(v){ -return v.value; -} -} -return null; -},this); -return this.multiple?ret:ret[0]; -},_getValueDeprecated:false,getValue:function(){ -return this._lastValue; -},undo:function(){ -this._setValueAttr(this._lastValueReported,false); -},_loadChildren:function(){ -if(this._loadingStore){ -return; -} -dojo.forEach(this._getChildren(),function(_17){ -_17.destroyRecursive(); -}); -dojo.forEach(this.options,this._addOptionItem,this); -this._updateSelection(); -},_updateSelection:function(){ -this.value=this._getValueFromOpts(); -var val=this.value; -if(!dojo.isArray(val)){ -val=[val]; -} -if(val&&val[0]){ -dojo.forEach(this._getChildren(),function(_18){ -var _19=dojo.some(val,function(v){ -return _18.option&&(v===_18.option.value); + + +/*===== +dijit.form.__SelectOption = function(){ + // value: String + // The value of the option. Setting to empty (or missing) will + // place a separator at that location + // label: String + // The label for our option. It can contain html tags. + // selected: Boolean + // Whether or not we are a selected option + // disabled: Boolean + // Whether or not this specific option is disabled + this.value = value; + this.label = label; + this.selected = selected; + this.disabled = disabled; +} +=====*/ + +dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, { + // summary: + // Extends _FormValueWidget in order to provide "select-specific" + // values - i.e., those values that are unique to <select> elements. + // This also provides the mechanism for reading the elements from + // a store, if desired. + + // multiple: [const] Boolean + // Whether or not we are multi-valued + multiple: false, + + // options: dijit.form.__SelectOption[] + // The set of options for our select item. Roughly corresponds to + // the html <option> tag. + options: null, + + // store: dojo.data.api.Identity + // A store which, at the very least impelements dojo.data.api.Identity + // to use for getting our list of options - rather than reading them + // from the <option> html tags. + store: null, + + // query: object + // A query to use when fetching items from our store + query: null, + + // queryOptions: object + // Query options to use when fetching from the store + queryOptions: null, + + // onFetch: Function + // A callback to do with an onFetch - but before any items are actually + // iterated over (i.e. to filter even futher what you want to add) + onFetch: null, + + // sortByLabel: Boolean + // Flag to sort the options returned from a store by the label of + // the store. + sortByLabel: true, + + + // loadChildrenOnOpen: Boolean + // By default loadChildren is called when the items are fetched from the + // store. This property allows delaying loadChildren (and the creation + // of the options/menuitems) until the user clicks the button to open the + // dropdown. + loadChildrenOnOpen: false, + + getOptions: function(/*anything*/ valueOrIdx){ + // summary: + // Returns a given option (or options). + // valueOrIdx: + // If passed in as a string, that string is used to look up the option + // in the array of options - based on the value property. + // (See dijit.form.__SelectOption). + // + // If passed in a number, then the option with the given index (0-based) + // within this select will be returned. + // + // If passed in a dijit.form.__SelectOption, the same option will be + // returned if and only if it exists within this select. + // + // If passed an array, then an array will be returned with each element + // in the array being looked up. + // + // If not passed a value, then all options will be returned + // + // returns: + // The option corresponding with the given value or index. null + // is returned if any of the following are true: + // - A string value is passed in which doesn't exist + // - An index is passed in which is outside the bounds of the array of options + // - A dijit.form.__SelectOption is passed in which is not a part of the select + + // NOTE: the compare for passing in a dijit.form.__SelectOption checks + // if the value property matches - NOT if the exact option exists + // NOTE: if passing in an array, null elements will be placed in the returned + // array when a value is not found. + var lookupValue = valueOrIdx, opts = this.options || [], l = opts.length; + + if(lookupValue === undefined){ + return opts; // dijit.form.__SelectOption[] + } + if(dojo.isArray(lookupValue)){ + return dojo.map(lookupValue, "return this.getOptions(item);", this); // dijit.form.__SelectOption[] + } + if(dojo.isObject(valueOrIdx)){ + // We were passed an option - so see if it's in our array (directly), + // and if it's not, try and find it by value. + if(!dojo.some(this.options, function(o, idx){ + if(o === lookupValue || + (o.value && o.value === lookupValue.value)){ + lookupValue = idx; + return true; + } + return false; + })){ + lookupValue = -1; + } + } + if(typeof lookupValue == "string"){ + for(var i=0; i<l; i++){ + if(opts[i].value === lookupValue){ + lookupValue = i; + break; + } + } + } + if(typeof lookupValue == "number" && lookupValue >= 0 && lookupValue < l){ + return this.options[lookupValue] // dijit.form.__SelectOption + } + return null; // null + }, + + addOption: function(/*dijit.form.__SelectOption|dijit.form.__SelectOption[]*/ option){ + // summary: + // Adds an option or options to the end of the select. If value + // of the option is empty or missing, a separator is created instead. + // Passing in an array of options will yield slightly better performance + // since the children are only loaded once. + if(!dojo.isArray(option)){ option = [option]; } + dojo.forEach(option, function(i){ + if(i && dojo.isObject(i)){ + this.options.push(i); + } + }, this); + this._loadChildren(); + }, + + removeOption: function(/*String|dijit.form.__SelectOption|Number|Array*/ valueOrIdx){ + // summary: + // Removes the given option or options. You can remove by string + // (in which case the value is removed), number (in which case the + // index in the options array is removed), or select option (in + // which case, the select option with a matching value is removed). + // You can also pass in an array of those values for a slightly + // better performance since the children are only loaded once. + if(!dojo.isArray(valueOrIdx)){ valueOrIdx = [valueOrIdx]; } + var oldOpts = this.getOptions(valueOrIdx); + dojo.forEach(oldOpts, function(i){ + // We can get null back in our array - if our option was not found. In + // that case, we don't want to blow up... + if(i){ + this.options = dojo.filter(this.options, function(node, idx){ + return (node.value !== i.value || node.label !== i.label); + }); + this._removeOptionItem(i); + } + }, this); + this._loadChildren(); + }, + + updateOption: function(/*dijit.form.__SelectOption|dijit.form.__SelectOption[]*/ newOption){ + // summary: + // Updates the values of the given option. The option to update + // is matched based on the value of the entered option. Passing + // in an array of new options will yeild better performance since + // the children will only be loaded once. + if(!dojo.isArray(newOption)){ newOption = [newOption]; } + dojo.forEach(newOption, function(i){ + var oldOpt = this.getOptions(i), k; + if(oldOpt){ + for(k in i){ oldOpt[k] = i[k]; } + } + }, this); + this._loadChildren(); + }, + + setStore: function(/*dojo.data.api.Identity*/ store, + /*anything?*/ selectedValue, + /*Object?*/ fetchArgs){ + // summary: + // Sets the store you would like to use with this select widget. + // The selected value is the value of the new store to set. This + // function returns the original store, in case you want to reuse + // it or something. + // store: dojo.data.api.Identity + // The store you would like to use - it MUST implement Identity, + // and MAY implement Notification. + // selectedValue: anything? + // The value that this widget should set itself to *after* the store + // has been loaded + // fetchArgs: Object? + // The arguments that will be passed to the store's fetch() function + var oStore = this.store; + fetchArgs = fetchArgs || {}; + if(oStore !== store){ + // Our store has changed, so update our notifications + dojo.forEach(this._notifyConnections || [], dojo.disconnect); + delete this._notifyConnections; + if(store && store.getFeatures()["dojo.data.api.Notification"]){ + this._notifyConnections = [ + dojo.connect(store, "onNew", this, "_onNewItem"), + dojo.connect(store, "onDelete", this, "_onDeleteItem"), + dojo.connect(store, "onSet", this, "_onSetItem") + ]; + } + this._set("store", store); + } + + // Turn off change notifications while we make all these changes + this._onChangeActive = false; + + // Remove existing options (if there are any) + if(this.options && this.options.length){ + this.removeOption(this.options); + } + + // Add our new options + if(store){ + this._loadingStore = true; + store.fetch(dojo.delegate(fetchArgs, { + onComplete: function(items, opts){ + if(this.sortByLabel && !fetchArgs.sort && items.length){ + items.sort(dojo.data.util.sorter.createSortFunction([{ + attribute: store.getLabelAttributes(items[0])[0] + }], store)); + } + + if(fetchArgs.onFetch){ + items = fetchArgs.onFetch.call(this, items, opts); + } + // TODO: Add these guys as a batch, instead of separately + dojo.forEach(items, function(i){ + this._addOptionForItem(i); + }, this); + + // Set our value (which might be undefined), and then tweak + // it to send a change event with the real value + this._loadingStore = false; + this.set("value", "_pendingValue" in this ? this._pendingValue : selectedValue); + delete this._pendingValue; + + if(!this.loadChildrenOnOpen){ + this._loadChildren(); + }else{ + this._pseudoLoadChildren(items); + } + this._fetchedWith = opts; + this._lastValueReported = this.multiple ? [] : null; + this._onChangeActive = true; + this.onSetStore(); + this._handleOnChange(this.value); + }, + scope: this + })); + }else{ + delete this._fetchedWith; + } + return oStore; // dojo.data.api.Identity + }, + + // TODO: implement set() and watch() for store and query, although not sure how to handle + // setting them individually rather than together (as in setStore() above) + + _setValueAttr: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){ + // summary: + // set the value of the widget. + // If a string is passed, then we set our value from looking it up. + if(this._loadingStore){ + // Our store is loading - so save our value, and we'll set it when + // we're done + this._pendingValue = newValue; + return; + } + var opts = this.getOptions() || []; + if(!dojo.isArray(newValue)){ + newValue = [newValue]; + } + dojo.forEach(newValue, function(i, idx){ + if(!dojo.isObject(i)){ + i = i + ""; + } + if(typeof i === "string"){ + newValue[idx] = dojo.filter(opts, function(node){ + return node.value === i; + })[0] || {value: "", label: ""}; + } + }, this); + + // Make sure some sane default is set + newValue = dojo.filter(newValue, function(i){ return i && i.value; }); + if(!this.multiple && (!newValue[0] || !newValue[0].value) && opts.length){ + newValue[0] = opts[0]; + } + dojo.forEach(opts, function(i){ + i.selected = dojo.some(newValue, function(v){ return v.value === i.value; }); + }); + var val = dojo.map(newValue, function(i){ return i.value; }), + disp = dojo.map(newValue, function(i){ return i.label; }); + + this._set("value", this.multiple ? val : val[0]); + this._setDisplay(this.multiple ? disp : disp[0]); + this._updateSelection(); + this._handleOnChange(this.value, priorityChange); + }, + + _getDisplayedValueAttr: function(){ + // summary: + // returns the displayed value of the widget + var val = this.get("value"); + if(!dojo.isArray(val)){ + val = [val]; + } + var ret = dojo.map(this.getOptions(val), function(v){ + if(v && "label" in v){ + return v.label; + }else if(v){ + return v.value; + } + return null; + }, this); + return this.multiple ? ret : ret[0]; + }, + + _loadChildren: function(){ + // summary: + // Loads the children represented by this widget's options. + // reset the menu to make it populatable on the next click + if(this._loadingStore){ return; } + dojo.forEach(this._getChildren(), function(child){ + child.destroyRecursive(); + }); + // Add each menu item + dojo.forEach(this.options, this._addOptionItem, this); + + // Update states + this._updateSelection(); + }, + + _updateSelection: function(){ + // summary: + // Sets the "selected" class on the item for styling purposes + this._set("value", this._getValueFromOpts()); + var val = this.value; + if(!dojo.isArray(val)){ + val = [val]; + } + if(val && val[0]){ + dojo.forEach(this._getChildren(), function(child){ + var isSelected = dojo.some(val, function(v){ + return child.option && (v === child.option.value); + }); + dojo.toggleClass(child.domNode, this.baseClass + "SelectedOption", isSelected); + dijit.setWaiState(child.domNode, "selected", isSelected); + }, this); + } + }, + + _getValueFromOpts: function(){ + // summary: + // Returns the value of the widget by reading the options for + // the selected flag + var opts = this.getOptions() || []; + if(!this.multiple && opts.length){ + // Mirror what a select does - choose the first one + var opt = dojo.filter(opts, function(i){ + return i.selected; + })[0]; + if(opt && opt.value){ + return opt.value + }else{ + opts[0].selected = true; + return opts[0].value; + } + }else if(this.multiple){ + // Set value to be the sum of all selected + return dojo.map(dojo.filter(opts, function(i){ + return i.selected; + }), function(i){ + return i.value; + }) || []; + } + return ""; + }, + + // Internal functions to call when we have store notifications come in + _onNewItem: function(/*item*/ item, /*Object?*/ parentInfo){ + if(!parentInfo || !parentInfo.parent){ + // Only add it if we are top-level + this._addOptionForItem(item); + } + }, + _onDeleteItem: function(/*item*/ item){ + var store = this.store; + this.removeOption(store.getIdentity(item)); + }, + _onSetItem: function(/*item*/ item){ + this.updateOption(this._getOptionObjForItem(item)); + }, + + _getOptionObjForItem: function(item){ + // summary: + // Returns an option object based off the given item. The "value" + // of the option item will be the identity of the item, the "label" + // of the option will be the label of the item. If the item contains + // children, the children value of the item will be set + var store = this.store, label = store.getLabel(item), + value = (label ? store.getIdentity(item) : null); + return {value: value, label: label, item:item}; // dijit.form.__SelectOption + }, + + _addOptionForItem: function(/*item*/ item){ + // summary: + // Creates (and adds) the option for the given item + var store = this.store; + if(!store.isItemLoaded(item)){ + // We are not loaded - so let's load it and add later + store.loadItem({item: item, onComplete: function(i){ + this._addOptionForItem(item); + }, + scope: this}); + return; + } + var newOpt = this._getOptionObjForItem(item); + this.addOption(newOpt); + }, + + constructor: function(/*Object*/ keywordArgs){ + // summary: + // Saves off our value, if we have an initial one set so we + // can use it if we have a store as well (see startup()) + this._oValue = (keywordArgs || {}).value || null; + }, + + buildRendering: function(){ + this.inherited(arguments); + dojo.setSelectable(this.focusNode, false); + }, + + _fillContent: function(){ + // summary: + // Loads our options and sets up our dropdown correctly. We + // don't want any content, so we don't call any inherit chain + // function. + var opts = this.options; + if(!opts){ + opts = this.options = this.srcNodeRef ? dojo.query(">", + this.srcNodeRef).map(function(node){ + if(node.getAttribute("type") === "separator"){ + return { value: "", label: "", selected: false, disabled: false }; + } + return { + value: (node.getAttribute("data-" + dojo._scopeName + "-value") || node.getAttribute("value")), + label: String(node.innerHTML), + // FIXME: disabled and selected are not valid on complex markup children (which is why we're + // looking for data-dojo-value above. perhaps we should data-dojo-props="" this whole thing?) + // decide before 1.6 + selected: node.getAttribute("selected") || false, + disabled: node.getAttribute("disabled") || false + }; + }, this) : []; + } + if(!this.value){ + this._set("value", this._getValueFromOpts()); + }else if(this.multiple && typeof this.value == "string"){ + this_set("value", this.value.split(",")); + } + }, + + postCreate: function(){ + // summary: + // sets up our event handling that we need for functioning + // as a select + this.inherited(arguments); + + // Make our event connections for updating state + this.connect(this, "onChange", "_updateSelection"); + this.connect(this, "startup", "_loadChildren"); + + this._setValueAttr(this.value, null); + }, + + startup: function(){ + // summary: + // Connects in our store, if we have one defined + this.inherited(arguments); + var store = this.store, fetchArgs = {}; + dojo.forEach(["query", "queryOptions", "onFetch"], function(i){ + if(this[i]){ + fetchArgs[i] = this[i]; + } + delete this[i]; + }, this); + if(store && store.getFeatures()["dojo.data.api.Identity"]){ + // Temporarily set our store to null so that it will get set + // and connected appropriately + this.store = null; + this.setStore(store, this._oValue, fetchArgs); + } + }, + + destroy: function(){ + // summary: + // Clean up our connections + dojo.forEach(this._notifyConnections || [], dojo.disconnect); + this.inherited(arguments); + }, + + _addOptionItem: function(/*dijit.form.__SelectOption*/ option){ + // summary: + // User-overridable function which, for the given option, adds an + // item to the select. If the option doesn't have a value, then a + // separator is added in that place. Make sure to store the option + // in the created option widget. + }, + + _removeOptionItem: function(/*dijit.form.__SelectOption*/ option){ + // summary: + // User-overridable function which, for the given option, removes + // its item from the select. + }, + + _setDisplay: function(/*String or String[]*/ newDisplay){ + // summary: + // Overridable function which will set the display for the + // widget. newDisplay is either a string (in the case of + // single selects) or array of strings (in the case of multi-selects) + }, + + _getChildren: function(){ + // summary: + // Overridable function to return the children that this widget contains. + return []; + }, + + _getSelectedOptionsAttr: function(){ + // summary: + // hooks into this.attr to provide a mechanism for getting the + // option items for the current value of the widget. + return this.getOptions(this.get("value")); + }, + + _pseudoLoadChildren: function(/*item[]*/ items){ + // summary: + // a function that will "fake" loading children, if needed, and + // if we have set to not load children until the widget opens. + // items: + // An array of items that will be loaded, when needed + }, + + onSetStore: function(){ + // summary: + // a function that can be connected to in order to receive a + // notification that the store has finished loading and all options + // from that store are available + } }); -dojo.toggleClass(_18.domNode,this.baseClass+"SelectedOption",_19); -dijit.setWaiState(_18.domNode,"selected",_19); -},this); -} -this._handleOnChange(this.value); -},_getValueFromOpts:function(){ -var _1a=this.getOptions()||[]; -if(!this.multiple&&_1a.length){ -var opt=dojo.filter(_1a,function(i){ -return i.selected; -})[0]; -if(opt&&opt.value){ -return opt.value; -}else{ -_1a[0].selected=true; -return _1a[0].value; -} -}else{ -if(this.multiple){ -return dojo.map(dojo.filter(_1a,function(i){ -return i.selected; -}),function(i){ -return i.value; -})||[]; -} -} -return ""; -},_onNewItem:function(_1b,_1c){ -if(!_1c||!_1c.parent){ -this._addOptionForItem(_1b); -} -},_onDeleteItem:function(_1d){ -var _1e=this.store; -this.removeOption(_1e.getIdentity(_1d)); -},_onSetItem:function(_1f){ -this.updateOption(this._getOptionObjForItem(_1f)); -},_getOptionObjForItem:function(_20){ -var _21=this.store,_22=_21.getLabel(_20),_23=(_22?_21.getIdentity(_20):null); -return {value:_23,label:_22,item:_20}; -},_addOptionForItem:function(_24){ -var _25=this.store; -if(!_25.isItemLoaded(_24)){ -_25.loadItem({item:_24,onComplete:function(i){ -this._addOptionForItem(_24); -},scope:this}); -return; -} -var _26=this._getOptionObjForItem(_24); -this.addOption(_26); -},constructor:function(_27){ -this._oValue=(_27||{}).value||null; -},_fillContent:function(){ -var _28=this.options; -if(!_28){ -_28=this.options=this.srcNodeRef?dojo.query(">",this.srcNodeRef).map(function(_29){ -if(_29.getAttribute("type")==="separator"){ -return {value:"",label:"",selected:false,disabled:false}; -} -return {value:_29.getAttribute("value"),label:String(_29.innerHTML),selected:_29.getAttribute("selected")||false,disabled:_29.getAttribute("disabled")||false}; -},this):[]; -} -if(!this.value){ -this.value=this._getValueFromOpts(); -}else{ -if(this.multiple&&typeof this.value=="string"){ -this.value=this.value.split(","); -} -} -},postCreate:function(){ -dojo.setSelectable(this.focusNode,false); -this.inherited(arguments); -this.connect(this,"onChange","_updateSelection"); -this.connect(this,"startup","_loadChildren"); -this._setValueAttr(this.value,null); -},startup:function(){ -this.inherited(arguments); -var _2a=this.store,_2b={}; -dojo.forEach(["query","queryOptions","onFetch"],function(i){ -if(this[i]){ -_2b[i]=this[i]; -} -delete this[i]; -},this); -if(_2a&&_2a.getFeatures()["dojo.data.api.Identity"]){ -this.store=null; -this.setStore(_2a,this._oValue,_2b); -} -},destroy:function(){ -dojo.forEach(this._notifyConnections||[],dojo.disconnect); -this.inherited(arguments); -},_addOptionItem:function(_2c){ -},_removeOptionItem:function(_2d){ -},_setDisplay:function(_2e){ -},_getChildren:function(){ -return []; -},_getSelectedOptionsAttr:function(){ -return this.getOptions(this.get("value")); -},_pseudoLoadChildren:function(_2f){ -},onSetStore:function(){ -}}); + } |