diff --git a/etemplate/js/et2_widget_selectAccount.js b/etemplate/js/et2_widget_selectAccount.js index e513c2c2f2..4f249ae53f 100644 --- a/etemplate/js/et2_widget_selectAccount.js +++ b/etemplate/js/et2_widget_selectAccount.js @@ -126,7 +126,7 @@ var et2_selectAccount = et2_selectbox.extend( this._super.apply(this, arguments); // Add search button - if(type == 'primary_group' && !this.options.tags) + if(type == 'primary_group') { var button = jQuery(document.createElement("span")) .addClass("et2_clickable") @@ -165,7 +165,7 @@ var et2_selectAccount = et2_selectbox.extend( this.options.select_options = this._get_accounts(); - if(type == 'primary_group' && !this.options.tags) + if(type == 'primary_group') { // Allow search 'inside' this widget this.supportedWidgetClasses = [et2_link_entry]; diff --git a/etemplate/js/et2_widget_selectbox.js b/etemplate/js/et2_widget_selectbox.js index dc9276689e..a4a0ad9bd3 100644 --- a/etemplate/js/et2_widget_selectbox.js +++ b/etemplate/js/et2_widget_selectbox.js @@ -80,12 +80,6 @@ var et2_selectbox = et2_inputWidget.extend( "default": false, "description": "For multi-selects, displays selected as a list of tags instead of a big list" }, - "source": { - "name": "AJAX data source", - "type": "any", - "default": et2_no_init, - "description": "Fetch options as needed from the server" - }, // Value can be string or integer "value": { @@ -414,10 +408,6 @@ var et2_selectbox = et2_inputWidget.extend( this.set_tags(this.options.tags, this.options.width); - if(this.options.source) - { - this.set_source(this.options.source); - } return true; }, @@ -752,85 +742,6 @@ var et2_selectbox = et2_inputWidget.extend( if(this.value || this.options.empty_label) this.set_value(this.value); }, - /** - * Set a ajax source for options. Works best with search or tags options - * to enable Chosen. - */ - set_source: function(_url) { - - if(!this.input) return false; - - // Can't actually do this until attached, loadingFinished should call again - if(!this.isAttached()) return; - - - var widget = this; - var search = this.input.next() - .find('.search-field > input, .chzn-search > input'); - var timeout = null; - - if(!_url || !search || search && search.autocomplete('instance')) - { - search.autocomplete('destroy'); - return; - } - - this.options.source = _url; - - search.on('keyup', function(e) { - var term = search.val().trim() || ''; - if(term.length < 2) - { - return false; - } - if(timeout) - { - window.clearTimeout(timeout); - } - timeout = window.setTimeout(function() - { - timeout = null; - search.parent().addClass('loading'); - widget.egw().json(widget.options.source,term, widget._ajax_fetch,widget, false,widget).sendRequest(); - },200); - }); - - }, - - /* - * Fetch options via AJAX for use in tag lists - * @param {type} data - * @returns {undefined} - */ - _ajax_fetch: function _ajax_fetch(data) { - var found = false; - var search = this.input.next() - .find('.search-field > input, .chzn-search > input'); - - for(var i = 0; i < data.length; i++) - { - if(data[i] && typeof data[i].value === 'string' && typeof data[i].label === 'string') - { - var option = data[i]; - if(jQuery("option[value='"+option.value+"']", this.input).length === 0) - { - found = true; - this._appendOptionElement(option.value, option.label,option.title); - } - } - } - search.parent() - .removeClass('loading'); - if(found) - { - var term = search.val(); - this.input.trigger('liszt:close'); - this.input.trigger("liszt:updated"); - // Updating clears the search term, restore it - search.val(term); - } - }, - getValue: function() { if(this.input == null) { diff --git a/etemplate/js/et2_widget_taglist.js b/etemplate/js/et2_widget_taglist.js index 0a41da1b17..328c7de8db 100644 --- a/etemplate/js/et2_widget_taglist.js +++ b/etemplate/js/et2_widget_taglist.js @@ -171,8 +171,8 @@ var et2_taglist = et2_selectbox.extend( var options = jQuery.extend( { // magisuggest can NOT work setting an empty autocomplete url, it will then call page url! // --> setting an empty options list instead - data: this.options.select_options && !jQuery.isEmptyObject(this.options.select_options) || !this.options.autocomplete_url ? - this._options2data(this.options.select_options || {}) : this.options.autocomplete_url, + data: this.options.select_options && !jQuery.isEmptyObject(this.options.select_options) ? + this.options.select_options || {} : this.options.autocomplete_url, dataUrlParams: this.options.autocomplete_params, method: 'GET', displayField: "label", @@ -191,11 +191,19 @@ var et2_taglist = et2_selectbox.extend( maxSelection: this.options.maxSelection, maxSelectionRenderer: jQuery.proxy(function(v) { this.egw().lang('You can not choose more then %1 item(s)!', v); }, this), width: this.options.width, // propagate width - highlight: false // otherwise renderer have to return strings + highlight: false, // otherwise renderer have to return strings, + value: this.options.value }, this.lib_options); this.taglist = this.taglist.magicSuggest(options); - this.set_value(this.options.value); + // AJAX _and_ select options - use custom function + if(this.options.autocomplete_url && !jQuery.isEmptyObject(this.options.select_options)) + { + var widget = this; + this.taglist.setData(function(query) { + return widget._data.call(widget,query) + }); + } // Display / hide a loading icon while fetching $j(this.taglist) @@ -207,9 +215,9 @@ var et2_taglist = et2_selectbox.extend( $j(this.getDOMNode()).unbind('change.et2_inputWidget'); // onChange - if(this.options.onchange && typeof this.options.onchange == 'function') + if(this.options.onchange && typeof this.onchange === 'function') { - $j(this.taglist).on("selectionchange", this.options.onchange); + $j(this.taglist).on("selectionchange", this.onchange); } // onClick - pass more than baseWidget, so unbind it to avoid double callback @@ -248,6 +256,7 @@ var et2_taglist = et2_selectbox.extend( if (typeof options[id] == 'object') { jQuery.extend(option, options[id]); + if(option.value) option.id = option.value } else { @@ -258,6 +267,23 @@ var et2_taglist = et2_selectbox.extend( return data; }, + /** + * Custom data function to return local options if there is nothing + * typed, or query via AJAX if user typed something + * + * @returns {Array} + */ + _data: function(query) { + if(query.trim() ==='' || !this.options.autocomplete_url) + { + return this.options.select_options; + } + else + { + return this.options.autocomplete_url; + } + }, + /** * Set all options from current static select_options list */ @@ -294,7 +320,11 @@ var et2_taglist = et2_selectbox.extend( // do NOT set an empty autocomplete_url, magicsuggest would use page url instead! if(this.taglist == null || !source) return; - this.taglist.setData(source); + + var widget = this; + this.taglist.setData(function(query) { + return widget._data.call(widget,query) + }); } }, @@ -305,10 +335,13 @@ var et2_taglist = et2_selectbox.extend( */ set_select_options: function(_options) { - this.options.select_options = _options; - + this.options.select_options = this._options2data(_options); + if(this.taglist == null) return; - this.taglist.setData(this._options2data(this.options.select_options)); + var widget = this; + this.taglist.setData(function(query) { + return widget._data.call(widget,query) + }); }, set_disabled: function(disabled) @@ -332,7 +365,8 @@ var et2_taglist = et2_selectbox.extend( this.taglist.clear(true); if(!value) return; - var values = jQuery.isArray(value) ? value : [value]; + var values = jQuery.isArray(value) ? jQuery.extend([],value) : [value]; + var result = []; for(var i=0; i < values.length; ++i) { var v = values[i]; @@ -340,26 +374,30 @@ var et2_taglist = et2_selectbox.extend( { // alread in correct format } - else if (this.options.select_options && typeof this.options.select_options[v] == 'undefined' || typeof v == 'string') + else if (this.options.select_options && + (result = $j.grep(this.options.select_options, function(e) { + return e.id == v; + })) + ) { // Options should have been provided, but they weren't // This can happen for ajax source with an existing value if(this.options.select_options == null) { - this.options.select_options = {}; + this.options.select_options = []; } - values[i] = { + values[i] = result[0] ? result[0] : { id: v, label: v }; } - else(this.options.select_options) + else { if (typeof values[i].id == 'undefined') { values[i] = { id: v, - label: this.options.select_options[v] + label: v }; } } @@ -423,7 +461,14 @@ var et2_taglist_account = et2_taglist.extend( */ set_account_type: function(value) { + if(value != this.options.account_type) + { + this.options.select_options = []; + } this.options.autocomplete_params.account_type = this.options.account_type = value; + + this.options.select_options = this._get_accounts(); + if(this.taglist != null) { // Update taglist too, since it already copied the params @@ -431,6 +476,51 @@ var et2_taglist_account = et2_taglist.extend( } }, + /** + * Get account info for select options from common client-side account cache + * + * @return {Array} select options + */ + _get_accounts: function() + { + if (!jQuery.isArray(this.options.select_options)) + { + var options = jQuery.extend({}, this.options.select_options); + this.options.select_options = []; + for(var key in options) + { + if (typeof options[key] == 'object') + { + if (typeof(options[key].key) == 'undefined') + { + options[key].value = key; + } + this.options.select_options.push(options[key]); + } + else + { + this.options.select_options.push({value: key, label: options[key]}); + } + } + } + var type = this.egw().preference('account_selection', 'common'); + var accounts = []; + // for primary_group we only display owngroups == own memberships, not other groups + if (type == 'primary_group' && this.options.account_type != 'accounts') + { + if (this.options.account_type == 'both') + { + accounts = this.egw().accounts('accounts'); + } + accounts = accounts.concat(this.egw().accounts('owngroups')); + } + else + { + accounts = this.egw().accounts(this.options.account_type); + } + return this.options.select_options.concat(accounts); + }, + int_reg_exp: /^-?[0-9]+$/, /** @@ -442,7 +532,7 @@ var et2_taglist_account = et2_taglist.extend( { if(!value) return this._super.call(this, value); - var values = jQuery.isArray(value) ? value : [value]; + var values = jQuery.isArray(value) ? jQuery.extend([], value) : [value]; for(var i=0; i < values.length; ++i) { var v = values[i];