summaryrefslogtreecommitdiff
path: root/lib/dijit/form/FilteringSelect.js.uncompressed.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dijit/form/FilteringSelect.js.uncompressed.js')
-rw-r--r--lib/dijit/form/FilteringSelect.js.uncompressed.js234
1 files changed, 234 insertions, 0 deletions
diff --git a/lib/dijit/form/FilteringSelect.js.uncompressed.js b/lib/dijit/form/FilteringSelect.js.uncompressed.js
new file mode 100644
index 000000000..84ad938c8
--- /dev/null
+++ b/lib/dijit/form/FilteringSelect.js.uncompressed.js
@@ -0,0 +1,234 @@
+define("dijit/form/FilteringSelect", [
+ "dojo/data/util/filter", // filter.patternToRegExp
+ "dojo/_base/declare", // declare
+ "dojo/_base/lang", // lang.mixin
+ "dojo/when",
+ "./MappedTextBox",
+ "./ComboBoxMixin"
+], function(filter, declare, lang, when, MappedTextBox, ComboBoxMixin){
+
+ // module:
+ // dijit/form/FilteringSelect
+
+ return declare("dijit.form.FilteringSelect", [MappedTextBox, 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*/ query,
+ /*Object*/ options,
+ /*Boolean?*/ priorityChange){
+ // summary:
+ // Callback from dojo.store 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((query && query[this.searchAttr] !== this._lastQuery) || (!query && 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.set("value", '', priorityChange || (priorityChange === undefined && !this.focused), this.textbox.value, null);
+ }else{
+ this.set('item', result[0], priorityChange);
+ }
+ },
+
+ _openResultList: function(/*Object*/ results, /*Object*/ query, /*Object*/ options){
+ // 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(query[this.searchAttr] !== this._lastQuery){
+ return;
+ }
+ this.inherited(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, /*String?*/ displayedValue, /*item?*/ item){
+ // 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; }
+
+ if(item === undefined){
+ if(value === null || value === ''){
+ value = '';
+ if(!lang.isString(displayedValue)){
+ this._setDisplayedValueAttr(displayedValue||'', priorityChange);
+ return;
+ }
+ }
+
+ var self = this;
+ this._lastQuery = value;
+ when(this.store.get(value), function(item){
+ self._callbackSetLabel(item? [item] : [], undefined, undefined, priorityChange);
+ });
+ }else{
+ this.valueNode.value = value;
+ this.inherited(arguments);
+ }
+ },
+
+ _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._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 = lang.clone(this.query); // #6196: populate query with user-specifics
+
+ // Generate query
+ var qs = this._getDisplayQueryString(label), 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;
+
+ // 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 options = {
+ ignoreCase: this.ignoreCase,
+ deep: true
+ };
+ lang.mixin(options, this.fetchProperties);
+ this._fetchHandle = this.store.query(query, options);
+ when(this._fetchHandle, function(result){
+ _this._fetchHandle = null;
+ _this._callbackSetLabel(result || [], query, options, priorityChange);
+ }, function(err){
+ _this._fetchHandle = null;
+ if(!_this._cancelingQuery){ // don't treat canceled query as an error
+ console.error('dijit.form.FilteringSelect: ' + err.toString());
+ }
+ });
+ }
+ },
+
+ undo: function(){
+ this.set('displayedValue', this._lastDisplayedValue);
+ }
+ });
+});