diff options
author | Andrew Dolgov <[email protected]> | 2012-08-14 18:59:10 +0400 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2012-08-14 18:59:18 +0400 |
commit | 1354d17270961fff662d40f90521223f8fd0d73b (patch) | |
tree | e9266be71587e47c800303446e968a6d3565e2cf /lib/dijit/form/_AutoCompleterMixin.js.uncompressed.js | |
parent | d04f8c826f5283765f52cf6b98b42a1ed8f2d6bc (diff) |
update dojo to 1.7.3
Diffstat (limited to 'lib/dijit/form/_AutoCompleterMixin.js.uncompressed.js')
-rw-r--r-- | lib/dijit/form/_AutoCompleterMixin.js.uncompressed.js | 765 |
1 files changed, 765 insertions, 0 deletions
diff --git a/lib/dijit/form/_AutoCompleterMixin.js.uncompressed.js b/lib/dijit/form/_AutoCompleterMixin.js.uncompressed.js new file mode 100644 index 000000000..57cbb27b6 --- /dev/null +++ b/lib/dijit/form/_AutoCompleterMixin.js.uncompressed.js @@ -0,0 +1,765 @@ +define("dijit/form/_AutoCompleterMixin", [ + "dojo/_base/connect", // keys keys.SHIFT + "dojo/data/util/filter", // patternToRegExp + "dojo/_base/declare", // declare + "dojo/_base/Deferred", // Deferred.when + "dojo/dom-attr", // domAttr.get + "dojo/_base/event", // event.stop + "dojo/keys", + "dojo/_base/lang", // lang.clone lang.hitch + "dojo/query", // query + "dojo/regexp", // regexp.escapeString + "dojo/_base/sniff", // has("ie") + "dojo/string", // string.substitute + "dojo/_base/window", // win.doc.selection.createRange + "./DataList", + "../registry", // registry.byId + "./_TextBoxMixin" // defines _TextBoxMixin.selectInputText +], function(connect, filter, declare, Deferred, domAttr, event, keys, lang, query, regexp, has, string, win, + DataList, registry, _TextBoxMixin){ + + // module: + // dijit/form/_AutoCompleterMixin + // summary: + // A mixin that implements the base functionality for `dijit.form.ComboBox`/`dijit.form.FilteringSelect` + + + return declare("dijit.form._AutoCompleterMixin", null, { + // summary: + // A mixin that implements the base functionality for `dijit.form.ComboBox`/`dijit.form.FilteringSelect` + // description: + // All widgets that mix in dijit.form._AutoCompleterMixin must extend `dijit.form._FormValueWidget`. + // tags: + // protected + + // item: Object + // This is the item returned by the dojo.data.store implementation that + // provides the data for this ComboBox, it's the currently selected item. + item: null, + + // pageSize: Integer + // Argument to data provider. + // Specifies number of search results per page (before hitting "next" button) + pageSize: Infinity, + + // store: [const] dojo.store.api.Store + // Reference to data provider object used by this ComboBox + store: null, + + // fetchProperties: Object + // Mixin to the store's fetch. + // For example, to set the sort order of the ComboBox menu, pass: + // | { sort: [{attribute:"name",descending: true}] } + // To override the default queryOptions so that deep=false, do: + // | { queryOptions: {ignoreCase: true, deep: false} } + fetchProperties:{}, + + // query: Object + // A query that can be passed to 'store' to initially filter the items, + // before doing further filtering based on `searchAttr` and the key. + // Any reference to the `searchAttr` is ignored. + query: {}, + + // autoComplete: Boolean + // If user types in a partial string, and then tab out of the `<input>` box, + // automatically copy the first entry displayed in the drop down list to + // the `<input>` field + autoComplete: true, + + // highlightMatch: String + // One of: "first", "all" or "none". + // + // If the ComboBox/FilteringSelect opens with the search results and the searched + // string can be found, it will be highlighted. If set to "all" + // then will probably want to change `queryExpr` parameter to '*${0}*' + // + // Highlighting is only performed when `labelType` is "text", so as to not + // interfere with any HTML markup an HTML label might contain. + highlightMatch: "first", + + // searchDelay: Integer + // Delay in milliseconds between when user types something and we start + // searching based on that value + searchDelay: 100, + + // searchAttr: String + // Search for items in the data store where this attribute (in the item) + // matches what the user typed + searchAttr: "name", + + // labelAttr: String? + // The entries in the drop down list come from this attribute in the + // dojo.data items. + // If not specified, the searchAttr attribute is used instead. + labelAttr: "", + + // labelType: String + // Specifies how to interpret the labelAttr in the data store items. + // Can be "html" or "text". + labelType: "text", + + // queryExpr: String + // This specifies what query ComboBox/FilteringSelect sends to the data store, + // based on what the user has typed. Changing this expression will modify + // whether the drop down shows only exact matches, a "starting with" match, + // etc. Use it in conjunction with highlightMatch. + // dojo.data query expression pattern. + // `${0}` will be substituted for the user text. + // `*` is used for wildcards. + // `${0}*` means "starts with", `*${0}*` means "contains", `${0}` means "is" + queryExpr: "${0}*", + + // ignoreCase: Boolean + // Set true if the ComboBox/FilteringSelect should ignore case when matching possible items + ignoreCase: true, + + // Flags to _HasDropDown to limit height of drop down to make it fit in viewport + maxHeight: -1, + + // For backwards compatibility let onClick events propagate, even clicks on the down arrow button + _stopClickEvents: false, + + _getCaretPos: function(/*DomNode*/ element){ + // khtml 3.5.2 has selection* methods as does webkit nightlies from 2005-06-22 + var pos = 0; + if(typeof(element.selectionStart) == "number"){ + // FIXME: this is totally borked on Moz < 1.3. Any recourse? + pos = element.selectionStart; + }else if(has("ie")){ + // in the case of a mouse click in a popup being handled, + // then the win.doc.selection is not the textarea, but the popup + // var r = win.doc.selection.createRange(); + // hack to get IE 6 to play nice. What a POS browser. + var tr = win.doc.selection.createRange().duplicate(); + var ntr = element.createTextRange(); + tr.move("character",0); + ntr.move("character",0); + try{ + // If control doesn't have focus, you get an exception. + // Seems to happen on reverse-tab, but can also happen on tab (seems to be a race condition - only happens sometimes). + // There appears to be no workaround for this - googled for quite a while. + ntr.setEndPoint("EndToEnd", tr); + pos = String(ntr.text).replace(/\r/g,"").length; + }catch(e){ + // If focus has shifted, 0 is fine for caret pos. + } + } + return pos; + }, + + _setCaretPos: function(/*DomNode*/ element, /*Number*/ location){ + location = parseInt(location); + _TextBoxMixin.selectInputText(element, location, location); + }, + + _setDisabledAttr: function(/*Boolean*/ value){ + // Additional code to set disabled state of ComboBox node. + // Overrides _FormValueWidget._setDisabledAttr() or ValidationTextBox._setDisabledAttr(). + this.inherited(arguments); + this.domNode.setAttribute("aria-disabled", value); + }, + + _abortQuery: function(){ + // stop in-progress query + if(this.searchTimer){ + clearTimeout(this.searchTimer); + this.searchTimer = null; + } + if(this._fetchHandle){ + if(this._fetchHandle.cancel){ + this._cancelingQuery = true; + this._fetchHandle.cancel(); + this._cancelingQuery = false; + } + this._fetchHandle = null; + } + }, + + _onInput: function(/*Event*/ evt){ + // summary: + // Handles paste events + this.inherited(arguments); + if(evt.charOrCode == 229){ // IME or cut/paste event + this._onKey(evt); + } + }, + + _onKey: function(/*Event*/ evt){ + // summary: + // Handles keyboard events + + if(this.disabled || this.readOnly){ return; } + var key = evt.charOrCode; + + // except for cutting/pasting case - ctrl + x/v + if(evt.altKey || ((evt.ctrlKey || evt.metaKey) && (key != 'x' && key != 'v')) || key == keys.SHIFT){ + return; // throw out weird key combinations and spurious events + } + + var doSearch = false; + var pw = this.dropDown; + var highlighted = null; + this._prev_key_backspace = false; + this._abortQuery(); + + // _HasDropDown will do some of the work: + // 1. when drop down is not yet shown: + // - if user presses the down arrow key, call loadDropDown() + // 2. when drop down is already displayed: + // - on ESC key, call closeDropDown() + // - otherwise, call dropDown.handleKey() to process the keystroke + this.inherited(arguments); + + if(this._opened){ + highlighted = pw.getHighlightedOption(); + } + switch(key){ + case keys.PAGE_DOWN: + case keys.DOWN_ARROW: + case keys.PAGE_UP: + case keys.UP_ARROW: + // Keystroke caused ComboBox_menu to move to a different item. + // Copy new item to <input> box. + if(this._opened){ + this._announceOption(highlighted); + } + event.stop(evt); + break; + + case keys.ENTER: + // prevent submitting form if user presses enter. Also + // prevent accepting the value if either Next or Previous + // are selected + if(highlighted){ + // only stop event on prev/next + if(highlighted == pw.nextButton){ + this._nextSearch(1); + event.stop(evt); + break; + }else if(highlighted == pw.previousButton){ + this._nextSearch(-1); + event.stop(evt); + break; + } + }else{ + // Update 'value' (ex: KY) according to currently displayed text + this._setBlurValue(); // set value if needed + this._setCaretPos(this.focusNode, this.focusNode.value.length); // move cursor to end and cancel highlighting + } + // default case: + // if enter pressed while drop down is open, or for FilteringSelect, + // if we are in the middle of a query to convert a directly typed in value to an item, + // prevent submit + if(this._opened || this._fetchHandle){ + event.stop(evt); + } + // fall through + + case keys.TAB: + var newvalue = this.get('displayedValue'); + // if the user had More Choices selected fall into the + // _onBlur handler + if(pw && ( + newvalue == pw._messages["previousMessage"] || + newvalue == pw._messages["nextMessage"]) + ){ + break; + } + if(highlighted){ + this._selectOption(highlighted); + } + // fall through + + case keys.ESCAPE: + if(this._opened){ + this._lastQuery = null; // in case results come back later + this.closeDropDown(); + } + break; + + case ' ': + if(highlighted){ + // user is effectively clicking a choice in the drop down menu + event.stop(evt); + this._selectOption(highlighted); + this.closeDropDown(); + }else{ + // user typed a space into the input box, treat as normal character + doSearch = true; + } + break; + + case keys.DELETE: + case keys.BACKSPACE: + this._prev_key_backspace = true; + doSearch = true; + break; + + default: + // Non char keys (F1-F12 etc..) shouldn't open list. + // Ascii characters and IME input (Chinese, Japanese etc.) should. + //IME input produces keycode == 229. + doSearch = typeof key == 'string' || key == 229; + } + if(doSearch){ + // need to wait a tad before start search so that the event + // bubbles through DOM and we have value visible + this.item = undefined; // undefined means item needs to be set + this.searchTimer = setTimeout(lang.hitch(this, "_startSearchFromInput"),1); + } + }, + + _autoCompleteText: function(/*String*/ text){ + // summary: + // Fill in the textbox with the first item from the drop down + // list, and highlight the characters that were + // auto-completed. For example, if user typed "CA" and the + // drop down list appeared, the textbox would be changed to + // "California" and "ifornia" would be highlighted. + + var fn = this.focusNode; + + // IE7: clear selection so next highlight works all the time + _TextBoxMixin.selectInputText(fn, fn.value.length); + // does text autoComplete the value in the textbox? + var caseFilter = this.ignoreCase? 'toLowerCase' : 'substr'; + if(text[caseFilter](0).indexOf(this.focusNode.value[caseFilter](0)) == 0){ + var cpos = this.autoComplete ? this._getCaretPos(fn) : fn.value.length; + // only try to extend if we added the last character at the end of the input + if((cpos+1) > fn.value.length){ + // only add to input node as we would overwrite Capitalisation of chars + // actually, that is ok + fn.value = text;//.substr(cpos); + // visually highlight the autocompleted characters + _TextBoxMixin.selectInputText(fn, cpos); + } + }else{ + // text does not autoComplete; replace the whole value and highlight + fn.value = text; + _TextBoxMixin.selectInputText(fn); + } + }, + + _openResultList: function(/*Object*/ results, /*Object*/ query, /*Object*/ options){ + // summary: + // Callback when a search completes. + // description: + // 1. generates drop-down list and calls _showResultList() to display it + // 2. if this result list is from user pressing "more choices"/"previous choices" + // then tell screen reader to announce new option + this._fetchHandle = null; + if( this.disabled || + this.readOnly || + (query[this.searchAttr] !== this._lastQuery) // TODO: better way to avoid getting unwanted notify + ){ + return; + } + var wasSelected = this.dropDown.getHighlightedOption(); + this.dropDown.clearResultList(); + if(!results.length && options.start == 0){ // if no results and not just the previous choices button + this.closeDropDown(); + return; + } + + // Fill in the textbox with the first item from the drop down list, + // and highlight the characters that were auto-completed. For + // example, if user typed "CA" and the drop down list appeared, the + // textbox would be changed to "California" and "ifornia" would be + // highlighted. + + var nodes = this.dropDown.createOptions( + results, + options, + lang.hitch(this, "_getMenuLabelFromItem") + ); + + // show our list (only if we have content, else nothing) + this._showResultList(); + + // #4091: + // tell the screen reader that the paging callback finished by + // shouting the next choice + if(options.direction){ + if(1 == options.direction){ + this.dropDown.highlightFirstOption(); + }else if(-1 == options.direction){ + this.dropDown.highlightLastOption(); + } + if(wasSelected){ + this._announceOption(this.dropDown.getHighlightedOption()); + } + }else if(this.autoComplete && !this._prev_key_backspace + // when the user clicks the arrow button to show the full list, + // startSearch looks for "*". + // it does not make sense to autocomplete + // if they are just previewing the options available. + && !/^[*]+$/.test(query[this.searchAttr].toString())){ + this._announceOption(nodes[1]); // 1st real item + } + }, + + _showResultList: function(){ + // summary: + // Display the drop down if not already displayed, or if it is displayed, then + // reposition it if necessary (reposition may be necessary if drop down's height changed). + this.closeDropDown(true); + this.openDropDown(); + this.domNode.setAttribute("aria-expanded", "true"); + }, + + loadDropDown: function(/*Function*/ /*===== callback =====*/){ + // Overrides _HasDropDown.loadDropDown(). + // This is called when user has pressed button icon or pressed the down arrow key + // to open the drop down. + + this._startSearchAll(); + }, + + isLoaded: function(){ + // signal to _HasDropDown that it needs to call loadDropDown() to load the + // drop down asynchronously before displaying it + return false; + }, + + closeDropDown: function(){ + // Overrides _HasDropDown.closeDropDown(). Closes the drop down (assuming that it's open). + // This method is the callback when the user types ESC or clicking + // the button icon while the drop down is open. It's also called by other code. + this._abortQuery(); + if(this._opened){ + this.inherited(arguments); + this.domNode.setAttribute("aria-expanded", "false"); + this.focusNode.removeAttribute("aria-activedescendant"); + } + }, + + _setBlurValue: function(){ + // if the user clicks away from the textbox OR tabs away, set the + // value to the textbox value + // #4617: + // if value is now more choices or previous choices, revert + // the value + var newvalue = this.get('displayedValue'); + var pw = this.dropDown; + if(pw && ( + newvalue == pw._messages["previousMessage"] || + newvalue == pw._messages["nextMessage"] + ) + ){ + this._setValueAttr(this._lastValueReported, true); + }else if(typeof this.item == "undefined"){ + // Update 'value' (ex: KY) according to currently displayed text + this.item = null; + this.set('displayedValue', newvalue); + }else{ + if(this.value != this._lastValueReported){ + this._handleOnChange(this.value, true); + } + this._refreshState(); + } + }, + + _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 + var value = ''; + if(item){ + if(!displayedValue){ + displayedValue = this.store._oldAPI ? // remove getValue() for 2.0 (old dojo.data API) + this.store.getValue(item, this.searchAttr) : item[this.searchAttr]; + } + value = this._getValueField() != this.searchAttr ? this.store.getIdentity(item) : displayedValue; + } + this.set('value', value, priorityChange, displayedValue, item); + }, + + _announceOption: function(/*Node*/ node){ + // summary: + // a11y code that puts the highlighted option in the textbox. + // This way screen readers will know what is happening in the + // menu. + + if(!node){ + return; + } + // pull the text value from the item attached to the DOM node + var newValue; + if(node == this.dropDown.nextButton || + node == this.dropDown.previousButton){ + newValue = node.innerHTML; + this.item = undefined; + this.value = ''; + }else{ + newValue = (this.store._oldAPI ? // remove getValue() for 2.0 (old dojo.data API) + this.store.getValue(node.item, this.searchAttr) : node.item[this.searchAttr]).toString(); + this.set('item', node.item, false, newValue); + } + // get the text that the user manually entered (cut off autocompleted text) + this.focusNode.value = this.focusNode.value.substring(0, this._lastInput.length); + // set up ARIA activedescendant + this.focusNode.setAttribute("aria-activedescendant", domAttr.get(node, "id")); + // autocomplete the rest of the option to announce change + this._autoCompleteText(newValue); + }, + + _selectOption: function(/*DomNode*/ target){ + // summary: + // Menu callback function, called when an item in the menu is selected. + this.closeDropDown(); + if(target){ + this._announceOption(target); + } + this._setCaretPos(this.focusNode, this.focusNode.value.length); + this._handleOnChange(this.value, true); + }, + + _startSearchAll: function(){ + this._startSearch(''); + }, + + _startSearchFromInput: function(){ + this._startSearch(this.focusNode.value.replace(/([\\\*\?])/g, "\\$1")); + }, + + _getQueryString: function(/*String*/ text){ + return string.substitute(this.queryExpr, [text]); + }, + + _startSearch: function(/*String*/ key){ + // summary: + // Starts a search for elements matching key (key=="" means to return all items), + // and calls _openResultList() when the search completes, to display the results. + if(!this.dropDown){ + var popupId = this.id + "_popup", + dropDownConstructor = lang.isString(this.dropDownClass) ? + lang.getObject(this.dropDownClass, false) : this.dropDownClass; + this.dropDown = new dropDownConstructor({ + onChange: lang.hitch(this, this._selectOption), + id: popupId, + dir: this.dir, + textDir: this.textDir + }); + this.focusNode.removeAttribute("aria-activedescendant"); + this.textbox.setAttribute("aria-owns",popupId); // associate popup with textbox + } + this._lastInput = key; // Store exactly what was entered by the user. + + // Setup parameters to be passed to store.query(). + // Create a new query to prevent accidentally querying for a hidden + // value from FilteringSelect's keyField + var query = lang.clone(this.query); // #5970 + var options = { + start: 0, + count: this.pageSize, + queryOptions: { // remove for 2.0 + ignoreCase: this.ignoreCase, + deep: true + } + }; + lang.mixin(options, this.fetchProperties); + + // Generate query + var qs = this._getQueryString(key), q; + if(this.store._oldAPI){ + // remove this branch for 2.0 + q = qs; + }else{ + // Query on searchAttr is a regex for benefit of dojo.store.Memory, + // but with a toString() method to help dojo.store.JsonRest. + // Search string like "Co*" converted to regex like /^Co.*$/i. + q = filter.patternToRegExp(qs, this.ignoreCase); + q.toString = function(){ return qs; }; + } + this._lastQuery = query[this.searchAttr] = q; + + // Function to run the query, wait for the results, and then call _openResultList() + var _this = this, + startQuery = function(){ + var resPromise = _this._fetchHandle = _this.store.query(query, options); + Deferred.when(resPromise, function(res){ + _this._fetchHandle = null; + res.total = resPromise.total; + _this._openResultList(res, query, options); + }, function(err){ + _this._fetchHandle = null; + if(!_this._cancelingQuery){ // don't treat canceled query as an error + console.error(_this.declaredClass + ' ' + err.toString()); + _this.closeDropDown(); + } + }); + }; + + // #5970: set _lastQuery, *then* start the timeout + // otherwise, if the user types and the last query returns before the timeout, + // _lastQuery won't be set and their input gets rewritten + + this.searchTimer = setTimeout(lang.hitch(this, function(query, _this){ + this.searchTimer = null; + + startQuery(); + + // Setup method to handle clicking next/previous buttons to page through results + this._nextSearch = this.dropDown.onPage = function(direction){ + options.start += options.count * direction; + // tell callback the direction of the paging so the screen + // reader knows which menu option to shout + options.direction = direction; + startQuery(); + _this.focus(); + }; + }, query, this), this.searchDelay); + }, + + _getValueField: function(){ + // summary: + // Helper for postMixInProperties() to set this.value based on data inlined into the markup. + // Returns the attribute name in the item (in dijit.form._ComboBoxDataStore) to use as the value. + return this.searchAttr; + }, + + //////////// INITIALIZATION METHODS /////////////////////////////////////// + + constructor: function(){ + this.query={}; + this.fetchProperties={}; + }, + + postMixInProperties: function(){ + if(!this.store){ + var srcNodeRef = this.srcNodeRef; + var list = this.list; + if(list){ + this.store = registry.byId(list); + }else{ + // if user didn't specify store, then assume there are option tags + this.store = new DataList({}, srcNodeRef); + } + + // if there is no value set and there is an option list, set + // the value to the first value to be consistent with native Select + // Firefox and Safari set value + // IE6 and Opera set selectedIndex, which is automatically set + // by the selected attribute of an option tag + // IE6 does not set value, Opera sets value = selectedIndex + if(!("value" in this.params)){ + var item = (this.item = this.store.fetchSelectedItem()); + if(item){ + var valueField = this._getValueField(); + // remove getValue() for 2.0 (old dojo.data API) + this.value = this.store._oldAPI ? this.store.getValue(item, valueField) : item[valueField]; + } + } + } + + this.inherited(arguments); + }, + + postCreate: function(){ + // summary: + // Subclasses must call this method from their postCreate() methods + // tags: + // protected + + // find any associated label element and add to ComboBox node. + var label=query('label[for="'+this.id+'"]'); + if(label.length){ + label[0].id = (this.id+"_label"); + this.domNode.setAttribute("aria-labelledby", label[0].id); + + } + this.inherited(arguments); + }, + + _getMenuLabelFromItem: function(/*Item*/ item){ + var label = this.labelFunc(item, this.store), + labelType = this.labelType; + // If labelType is not "text" we don't want to screw any markup ot whatever. + if(this.highlightMatch != "none" && this.labelType == "text" && this._lastInput){ + label = this.doHighlight(label, this._escapeHtml(this._lastInput)); + labelType = "html"; + } + return {html: labelType == "html", label: label}; + }, + + doHighlight: function(/*String*/ label, /*String*/ find){ + // summary: + // Highlights the string entered by the user in the menu. By default this + // highlights the first occurrence found. Override this method + // to implement your custom highlighting. + // tags: + // protected + + var + // Add (g)lobal modifier when this.highlightMatch == "all" and (i)gnorecase when this.ignoreCase == true + modifiers = (this.ignoreCase ? "i" : "") + (this.highlightMatch == "all" ? "g" : ""), + i = this.queryExpr.indexOf("${0}"); + find = regexp.escapeString(find); // escape regexp special chars + return this._escapeHtml(label).replace( + // prepend ^ when this.queryExpr == "${0}*" and append $ when this.queryExpr == "*${0}" + new RegExp((i == 0 ? "^" : "") + "("+ find +")" + (i == (this.queryExpr.length - 4) ? "$" : ""), modifiers), + '<span class="dijitComboBoxHighlightMatch">$1</span>' + ); // returns String, (almost) valid HTML (entities encoded) + }, + + _escapeHtml: function(/*String*/ str){ + // TODO Should become dojo.html.entities(), when exists use instead + // summary: + // Adds escape sequences for special characters in XML: &<>"' + str = String(str).replace(/&/gm, "&").replace(/</gm, "<") + .replace(/>/gm, ">").replace(/"/gm, """); //balance" + return str; // string + }, + + reset: function(){ + // Overrides the _FormWidget.reset(). + // Additionally reset the .item (to clean up). + this.item = null; + this.inherited(arguments); + }, + + labelFunc: function(/*item*/ item, /*dojo.store.api.Store*/ store){ + // summary: + // Computes the label to display based on the dojo.data store item. + // returns: + // The label that the ComboBox should display + // tags: + // private + + // Use toString() because XMLStore returns an XMLItem whereas this + // method is expected to return a String (#9354). + // Remove getValue() for 2.0 (old dojo.data API) + return (store._oldAPI ? store.getValue(item, this.labelAttr || this.searchAttr) : + item[this.labelAttr || this.searchAttr]).toString(); // String + }, + + _setValueAttr: function(/*String*/ value, /*Boolean?*/ priorityChange, /*String?*/ displayedValue, /*item?*/ item){ + // summary: + // Hook so set('value', value) works. + // description: + // Sets the value of the select. + this._set("item", item||null); // value not looked up in store + if(!value){ value = ''; } // null translates to blank + this.inherited(arguments); + }, + _setTextDirAttr: function(/*String*/ textDir){ + // summary: + // Setter for textDir, needed for the dropDown's textDir update. + // description: + // Users shouldn't call this function; they should be calling + // set('textDir', value) + // tags: + // private + this.inherited(arguments); + // update the drop down also (_ComboBoxMenuMixin) + if(this.dropDown){ + this.dropDown._set("textDir", textDir); + } + } + }); +}); |