aboutsummaryrefslogtreecommitdiff
path: root/includes/js/dijit/form/FilteringSelect.js
diff options
context:
space:
mode:
Diffstat (limited to 'includes/js/dijit/form/FilteringSelect.js')
-rw-r--r--includes/js/dijit/form/FilteringSelect.js241
1 files changed, 241 insertions, 0 deletions
diff --git a/includes/js/dijit/form/FilteringSelect.js b/includes/js/dijit/form/FilteringSelect.js
new file mode 100644
index 0000000..d1e25c0
--- /dev/null
+++ b/includes/js/dijit/form/FilteringSelect.js
@@ -0,0 +1,241 @@
+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
+ // 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.
+ //
+ // 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,
+
+ _lastDisplayedValue: "",
+
+ isValid:function(){
+ return this._isvalid;
+ },
+
+ _callbackSetLabel: function( /*Array*/ result,
+ /*Object*/ dataObject,
+ /*Boolean?*/ 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._focused){ this.valueNode.value=""; }
+ dijit.form.TextBox.superclass.setValue.call(this, undefined, !this._focused);
+ this._isvalid=false;
+ this.validate(this._focused);
+ }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; // FIXME: should this be greater-than?
+ 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?*/ priorityChange){
+ this.valueNode.value = value;
+ dijit.form.FilteringSelect.superclass.setValue.call(this, value, priorityChange, displayedValue);
+ this._lastDisplayedValue = displayedValue;
+ },
+
+ setValue: function(/*String*/ value, /*Boolean?*/ 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?*/ priorityChange){
+ // summary:
+ // Set the displayed valued in the input box, based on a
+ // selected item.
+ // description:
+ // 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
+ // return: the label that the ComboBox should display
+ return store.getValue(item, this.searchAttr);
+ },
+
+ _doSelect: function(/*Event*/ tgt){
+ // summary:
+ // ComboBox's menu callback function
+ // description:
+ // 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, /*Boolean?*/ priorityChange){
+ // summary:
+ // Set textbox to display label. Also performs reverse lookup
+ // to set the hidden value. Used in InlineEditBox
+
+ if(this.store){
+ var query = dojo.clone(this.query); // #6196: populate query with user-specifics
+ 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;
+ var _this = this;
+ this.store.fetch({
+ query: query,
+ queryOptions: {
+ ignoreCase: this.ignoreCase,
+ deep: true
+ },
+ onComplete: function(result, dataObject){
+ dojo.hitch(_this, "_callbackSetLabel")(result, dataObject, priorityChange);
+ },
+ onError: function(errText){
+ console.error('dijit.form.FilteringSelect: ' + errText);
+ dojo.hitch(_this, "_setValue")(undefined, label, false);
+ }
+ });
+ }
+ },
+
+ _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(){
+ // FIXME: shouldn't this just be a call to inherited?
+ dijit.form.ComboBoxMixin.prototype.postMixInProperties.apply(this, arguments);
+ dijit.form.MappedTextBox.prototype.postMixInProperties.apply(this, arguments);
+ },
+
+ postCreate: function(){
+ dijit.form.ComboBoxMixin.prototype._postCreate.apply(this, arguments);
+ dijit.form.MappedTextBox.prototype.postCreate.apply(this, arguments);
+ },
+
+ setAttribute: function(/*String*/ attr, /*anything*/ value){
+ dijit.form.MappedTextBox.prototype.setAttribute.apply(this, arguments);
+ dijit.form.ComboBoxMixin.prototype._setAttribute.apply(this, arguments);
+ },
+
+ undo: function(){
+ this.setDisplayedValue(this._lastDisplayedValue);
+ },
+
+ _valueChanged: function(){
+ return this.getDisplayedValue()!=this._lastDisplayedValue;
+ }
+ }
+);
+
+}