diff options
author | Barak Korren <[email protected]> | 2013-04-02 20:38:07 +0300 |
---|---|---|
committer | Barak Korren <[email protected]> | 2013-04-02 20:38:07 +0300 |
commit | 58a2577d48790c79adfd44bcfd662c980ce6cfe4 (patch) | |
tree | 523d814ea0b7b6f617fe515b186099c6e83fed72 /lib/dijit/form/_FormSelectWidget.js.uncompressed.js | |
parent | e470a273cf09562fb2f9c0c899002303f19c8d16 (diff) | |
parent | cc332603431102a682feda22b9cf0093a29f0176 (diff) |
Merge branch 'master' of https://github.com/gothfox/Tiny-Tiny-RSS.git
Diffstat (limited to 'lib/dijit/form/_FormSelectWidget.js.uncompressed.js')
-rw-r--r-- | lib/dijit/form/_FormSelectWidget.js.uncompressed.js | 707 |
1 files changed, 0 insertions, 707 deletions
diff --git a/lib/dijit/form/_FormSelectWidget.js.uncompressed.js b/lib/dijit/form/_FormSelectWidget.js.uncompressed.js deleted file mode 100644 index 4a40c51d0..000000000 --- a/lib/dijit/form/_FormSelectWidget.js.uncompressed.js +++ /dev/null @@ -1,707 +0,0 @@ -define("dijit/form/_FormSelectWidget", [ - "dojo/_base/array", // array.filter array.forEach array.map array.some - "dojo/_base/Deferred", - "dojo/aspect", // aspect.after - "dojo/data/util/sorter", // util.sorter.createSortFunction - "dojo/_base/declare", // declare - "dojo/dom", // dom.setSelectable - "dojo/dom-class", // domClass.toggle - "dojo/_base/kernel", // _scopeName - "dojo/_base/lang", // lang.delegate lang.isArray lang.isObject lang.hitch - "dojo/query", // query - "dojo/when", - "dojo/store/util/QueryResults", - "./_FormValueWidget" -], function(array, Deferred, aspect, sorter, declare, dom, domClass, kernel, lang, query, when, - QueryResults, _FormValueWidget){ - -// module: -// dijit/form/_FormSelectWidget - -/*===== -var __SelectOption = { - // 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 -}; -=====*/ - -var _FormSelectWidget = declare("dijit.form._FormSelectWidget", _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: __SelectOption[] - // The set of options for our select item. Roughly corresponds to - // the html `<option>` tag. - options: null, - - // store: dojo/store/api/Store - // A store to use for getting our list of options - rather than reading them - // from the `<option>` html tags. Should support getIdentity(). - // For back-compat store can also be a dojo/data/api/Identity. - 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, - - // labelAttr: String? - // The entries in the drop down list come from this attribute in the dojo.store items. - // If ``store`` is set, labelAttr must be set too, unless store is an old-style - // dojo.data store rather than a new dojo/store. - labelAttr: "", - - // onFetch: Function - // A callback to do with an onFetch - but before any items are actually - // iterated over (i.e. to filter even further 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, - - // onLoadDeferred: [readonly] dojo.Deferred - // This is the `dojo.Deferred` returned by setStore(). - // Calling onLoadDeferred.then() registers your - // callback to be called only once, when the prior setStore completes. - onLoadDeferred: null, - - 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/_FormSelectWidget.__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/_FormSelectWidget.__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/_FormSelectWidget.__SelectOption is passed in which is not a part of the select - - // NOTE: the compare for passing in a dijit/form/_FormSelectWidget.__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; // __SelectOption[] - } - if(lang.isArray(lookupValue)){ - return array.map(lookupValue, "return this.getOptions(item);", this); // __SelectOption[] - } - if(lang.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(!array.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]; // __SelectOption - } - return null; // null - }, - - addOption: function(/*__SelectOption|__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(!lang.isArray(option)){ option = [option]; } - array.forEach(option, function(i){ - if(i && lang.isObject(i)){ - this.options.push(i); - } - }, this); - this._loadChildren(); - }, - - removeOption: function(/*String|__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(!lang.isArray(valueOrIdx)){ valueOrIdx = [valueOrIdx]; } - var oldOpts = this.getOptions(valueOrIdx); - array.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 = array.filter(this.options, function(node){ - return (node.value !== i.value || node.label !== i.label); - }); - this._removeOptionItem(i); - } - }, this); - this._loadChildren(); - }, - - updateOption: function(/*__SelectOption|__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 yield better performance since - // the children will only be loaded once. - if(!lang.isArray(newOption)){ newOption = [newOption]; } - array.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(store, - selectedValue, - 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/store/api/Store - // The dojo.store you would like to use - it MUST implement getIdentity() - // and MAY implement observe(). - // For backwards-compatibility this can also be a data.data store, in which case - // it MUST implement dojo/data/api/Identity, - // and MAY implement dojo/data/api/Notification. - // selectedValue: anything? - // The value that this widget should set itself to *after* the store - // has been loaded - // fetchArgs: Object? - // Hash of parameters to set filter on store, etc. - // - // - query: new value for Select.query, - // - queryOptions: new value for Select.queryOptions, - // - onFetch: callback function for each item in data (Deprecated) - var oStore = this.store; - fetchArgs = fetchArgs || {}; - - if(oStore !== store){ - // Our store has changed, so cancel any listeners on old store (remove for 2.0) - var h; - while((h = this._notifyConnections.pop())){ h.remove(); } - - // For backwards-compatibility, accept dojo.data store in addition to dojo.store.store. Remove in 2.0. - if(!store.get){ - lang.mixin(store, { - _oldAPI: true, - get: function(id){ - // summary: - // Retrieves an object by it's identity. This will trigger a fetchItemByIdentity. - // Like dojo.store.DataStore.get() except returns native item. - var deferred = new Deferred(); - this.fetchItemByIdentity({ - identity: id, - onItem: function(object){ - deferred.resolve(object); - }, - onError: function(error){ - deferred.reject(error); - } - }); - return deferred.promise; - }, - query: function(query, options){ - // summary: - // Queries the store for objects. Like dojo/store/DataStore.query() - // except returned Deferred contains array of native items. - var deferred = new Deferred(function(){ if(fetchHandle.abort){ fetchHandle.abort(); } } ); - deferred.total = new Deferred(); - var fetchHandle = this.fetch(lang.mixin({ - query: query, - onBegin: function(count){ - deferred.total.resolve(count); - }, - onComplete: function(results){ - deferred.resolve(results); - }, - onError: function(error){ - deferred.reject(error); - } - }, options)); - return new QueryResults(deferred); - } - }); - - if(store.getFeatures()["dojo.data.api.Notification"]){ - this._notifyConnections = [ - aspect.after(store, "onNew", lang.hitch(this, "_onNewItem"), true), - aspect.after(store, "onDelete", lang.hitch(this, "_onDeleteItem"), true), - aspect.after(store, "onSet", lang.hitch(this, "_onSetItem"), true) - ]; - } - } - this._set("store", store); // Our store has changed, so update our notifications - } - - // Remove existing options (if there are any) - if(this.options && this.options.length){ - this.removeOption(this.options); - } - - // Cancel listener for updates to old store - if(this._queryRes && this._queryRes.close){ - this._queryRes.close(); - } - - // If user has specified new query and query options along with this new store, then use them. - if(fetchArgs.query){ - this._set("query", fetchArgs.query); - this._set("queryOptions", fetchArgs.queryOptions); - } - - // Add our new options - if(store){ - this._loadingStore = true; - this.onLoadDeferred = new Deferred(); - - // Run query - // Save result in this._queryRes so we can cancel the listeners we register below - this._queryRes = store.query(this.query, this.queryOptions); - when(this._queryRes, lang.hitch(this, function(items){ - - if(this.sortByLabel && !fetchArgs.sort && items.length){ - if(items[0].getValue){ - // Old dojo.data API to access items, remove for 2.0 - items.sort(sorter.createSortFunction([{ - attribute: store.getLabelAttributes(items[0])[0] - }], store)); - }else{ - var labelAttr = this.labelAttr; - items.sort(function(a, b){ - return a[labelAttr] > b[labelAttr] ? 1 : b[labelAttr] > a[labelAttr] ? -1 : 0; - }); - } - } - - if(fetchArgs.onFetch){ - items = fetchArgs.onFetch.call(this, items, fetchArgs); - } - - // TODO: Add these guys as a batch, instead of separately - array.forEach(items, function(i){ - this._addOptionForItem(i); - }, this); - - // Register listener for store updates - if(this._queryRes.observe){ - this._queryRes.observe(lang.hitch(this, function(object, deletedFrom, insertedInto){ - if(deletedFrom == insertedInto){ - this._onSetItem(object); - }else{ - if(deletedFrom != -1){ - this._onDeleteItem(object); - } - if(insertedInto != -1){ - this._onNewItem(object); - } - } - }), true); - } - - // 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.onLoadDeferred.resolve(true); - this.onSetStore(); - }), function(err){ - console.error('dijit.form.Select: ' + err.toString()); - this.onLoadDeferred.reject(err); - }); - } - 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._onChangeActive){ priorityChange = null; } - 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(!lang.isArray(newValue)){ - newValue = [newValue]; - } - array.forEach(newValue, function(i, idx){ - if(!lang.isObject(i)){ - i = i + ""; - } - if(typeof i === "string"){ - newValue[idx] = array.filter(opts, function(node){ - return node.value === i; - })[0] || {value: "", label: ""}; - } - }, this); - - // Make sure some sane default is set - newValue = array.filter(newValue, function(i){ return i && i.value; }); - if(!this.multiple && (!newValue[0] || !newValue[0].value) && opts.length){ - newValue[0] = opts[0]; - } - array.forEach(opts, function(i){ - i.selected = array.some(newValue, function(v){ return v.value === i.value; }); - }); - var val = array.map(newValue, function(i){ return i.value; }), - disp = array.map(newValue, function(i){ return i.label; }); - - if(typeof val == "undefined" || typeof val[0] == "undefined"){ return; } // not fully initialized yet or a failed value lookup - this._setDisplay(this.multiple ? disp : disp[0]); - this.inherited(arguments, [ this.multiple ? val : val[0], priorityChange ]); - this._updateSelection(); - }, - - _getDisplayedValueAttr: function(){ - // summary: - // returns the displayed value of the widget - var val = this.get("value"); - if(!lang.isArray(val)){ - val = [val]; - } - var ret = array.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; } - array.forEach(this._getChildren(), function(child){ - child.destroyRecursive(); - }); - // Add each menu item - array.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(!lang.isArray(val)){ - val = [val]; - } - if(val && val[0]){ - array.forEach(this._getChildren(), function(child){ - var isSelected = array.some(val, function(v){ - return child.option && (v === child.option.value); - }); - domClass.toggle(child.domNode, this.baseClass.replace(/\s+|$/g, "SelectedOption "), isSelected); - child.domNode.setAttribute("aria-selected", isSelected ? "true" : "false"); - }, 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 = array.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 array.map(array.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. - - // remove getLabel() call for 2.0 (it's to support the old dojo.data API) - var store = this.store, - label = (this.labelAttr && this.labelAttr in item) ? item[this.labelAttr] : store.getLabel(item), - value = (label ? store.getIdentity(item) : null); - return {value: value, label: label, item: item}; // __SelectOption - }, - - _addOptionForItem: function(/*item*/ item){ - // summary: - // Creates (and adds) the option for the given item - var store = this.store; - if(store.isItemLoaded && !store.isItemLoaded(item)){ - // We are not loaded - so let's load it and add later. - // Remove for 2.0 (it's the old dojo.data API) - store.loadItem({item: item, onItem: function(i){ - this._addOptionForItem(i); - }, - scope: this}); - return; - } - var newOpt = this._getOptionObjForItem(item); - this.addOption(newOpt); - }, - - constructor: function(params /*===== , srcNodeRef =====*/){ - // summary: - // Create the widget. - // params: Object|null - // Hash of initialization parameters for widget, including scalar values (like title, duration etc.) - // and functions, typically callbacks like onClick. - // The hash can contain any of the widget's properties, excluding read-only properties. - // srcNodeRef: DOMNode|String? - // If a srcNodeRef (DOM node) is specified, replace srcNodeRef with my generated DOM tree - - // 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 = (params || {}).value || null; - this._notifyConnections = []; // remove for 2.0 - }, - - buildRendering: function(){ - this.inherited(arguments); - dom.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. - if(!this.options){ - this.options = - this.srcNodeRef - ? query("> *", this.srcNodeRef).map( - function(node){ - if(node.getAttribute("type") === "separator"){ - return { value: "", label: "", selected: false, disabled: false }; - } - return { - value: (node.getAttribute("data-" + kernel._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"); - - // moved from startup - // Connects in our store, if we have one defined - var store = this.store; - if(store && (store.getIdentity || 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); - } - }, - - startup: function(){ - // summary: - this._loadChildren(); - this.inherited(arguments); - }, - - destroy: function(){ - // summary: - // Clean up our connections - - var h; - while((h = this._notifyConnections.pop())){ h.remove(); } - - // Cancel listener for store updates - if(this._queryRes && this._queryRes.close){ - this._queryRes.close(); - } - - this.inherited(arguments); - }, - - _addOptionItem: function(/*__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(/*__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 - } -}); - -/*===== -_FormSelectWidget.__SelectOption = __SelectOption; -=====*/ - -return _FormSelectWidget; - -}); |