From 1d3e69667681ee1cccf13f3519259f506a782e29 Mon Sep 17 00:00:00 2001 From: Nathan Gray Date: Tue, 9 Feb 2016 00:38:09 +0000 Subject: [PATCH] Ajax fetching for chosen taglist style selectboxes - set tags & source attributes --- etemplate/js/et2_widget_selectAccount.js | 4 +- etemplate/js/et2_widget_selectbox.js | 89 ++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/etemplate/js/et2_widget_selectAccount.js b/etemplate/js/et2_widget_selectAccount.js index 4f249ae53f..e513c2c2f2 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') + if(type == 'primary_group' && !this.options.tags) { 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') + if(type == 'primary_group' && !this.options.tags) { // 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 a4a0ad9bd3..dc9276689e 100644 --- a/etemplate/js/et2_widget_selectbox.js +++ b/etemplate/js/et2_widget_selectbox.js @@ -80,6 +80,12 @@ 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": { @@ -408,6 +414,10 @@ 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; }, @@ -742,6 +752,85 @@ 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) {