diff --git a/etemplate/inc/class.etemplate_widget_menupopup.inc.php b/etemplate/inc/class.etemplate_widget_menupopup.inc.php index 350991dadc..193c06be0c 100644 --- a/etemplate/inc/class.etemplate_widget_menupopup.inc.php +++ b/etemplate/inc/class.etemplate_widget_menupopup.inc.php @@ -17,6 +17,12 @@ */ class etemplate_widget_menupopup extends etemplate_widget { + + /** + * If the selectbox has this many rows, give it a search box automatically + */ + const SEARCH_ROW_LIMIT = 20; + /** * @var array */ @@ -142,6 +148,7 @@ class etemplate_widget_menupopup extends etemplate_widget } } + // Make sure  s, etc. are properly encoded when sent, and not double-encoded $options = (self::$request->sel_options[$form_name] ? $form_name : $this->id); if(is_array(self::$request->sel_options[$options])) @@ -157,6 +164,12 @@ class etemplate_widget_menupopup extends etemplate_widget $label['label'] = html_entity_decode($label['label'], ENT_NOQUOTES,'utf-8'); } } + + // Turn on search, if there's a lot of rows + if(count(self::$request->sel_options[$options]) >= self::SEARCH_ROW_LIMIT) + { + self::setElementAttribute($form_name, "search", true); + } } } diff --git a/etemplate/js/et2_widget_selectbox.js b/etemplate/js/et2_widget_selectbox.js index 525407f554..02a33a5be1 100644 --- a/etemplate/js/et2_widget_selectbox.js +++ b/etemplate/js/et2_widget_selectbox.js @@ -15,6 +15,7 @@ /*egw:uses jquery.jquery; + /phpgwapi/js/jquery/chosen/chosen.jquery.js; et2_core_xml; et2_core_DOMWidget; et2_core_inputWidget; @@ -53,8 +54,24 @@ var et2_selectbox = et2_inputWidget.extend({ "default": true, "description": "For multi-selects, put the selected options at the top of the list when first loaded" }, + + // Chosen options + "search": { + "name": "Search", + "type": "boolean", + "default": false, + "description": "For single selects, add a search box to the drop-down list" + }, + "tags": { + "name": "Tag style", + "type": "boolean", + "default": false, + "description": "For multi-selects, displays selected as a list of tags instead of a big list" + }, + + // Value can be string or integer "value": { - "type": "any" // Can be string or integer + "type": "any" }, // Type specific legacy options. Avoid using. "other": { @@ -97,7 +114,14 @@ var et2_selectbox = et2_inputWidget.extend({ if(this.options.rows > 1) { this.options.multiple = true; - this.createMultiSelect(); + if(this.options.tags) + { + this.createInputWidget(); + } + else + { + this.createMultiSelect(); + } } else { @@ -372,6 +396,24 @@ var et2_selectbox = et2_inputWidget.extend({ this.setDOMNode(node[0]); }, + doLoadingFinished: function() { + this._super.apply(this, arguments); + + // Turn on tags, if desired + if(this.input != null && (this.options.search || this.options.tags) && !this.options.disabled) + { + if(this.options.empty_label) + { + this.input.attr("data-placeholder", this.options.empty_label); + } + this.input.css("width","100%") + .chosen({ + }) + .change(this.onchange); + } + return true; + }, + loadFromXML: function(_node) { // Handle special case where legacy option for empty label is used (conflicts with rows), and rows is set as an attribute var legacy; @@ -401,6 +443,12 @@ var et2_selectbox = et2_inputWidget.extend({ { _value = _value.split(','); } + if(this.options.tags) + { + this.input.val(_value); + this.input.trigger("liszt:updated"); + return; + } if(this.input == null) { return this.set_multi_value(_value);