From e5b1cdcb7011b99fdcbd5244c823536dac5cdf2d Mon Sep 17 00:00:00 2001 From: Christian Binder Date: Sat, 21 Jul 2012 10:50:04 +0000 Subject: [PATCH] next step for et2_widget_itempicker (rudimentary display of search results) --- .../class.etemplate_widget_itempicker.inc.php | 11 +++ etemplate/js/et2_widget_itempicker.js | 94 +++++++++++++++++-- etemplate/templates/default/etemplate2.css | 44 ++++++++- 3 files changed, 139 insertions(+), 10 deletions(-) diff --git a/etemplate/inc/class.etemplate_widget_itempicker.inc.php b/etemplate/inc/class.etemplate_widget_itempicker.inc.php index 5173d2cab6..8adc9ab1e3 100755 --- a/etemplate/inc/class.etemplate_widget_itempicker.inc.php +++ b/etemplate/inc/class.etemplate_widget_itempicker.inc.php @@ -28,6 +28,17 @@ class etemplate_widget_itempicker extends etemplate_widget { parent::__construct($xml); } + + /** + * Find items that match the given parameters + */ + public static function ajax_item_search($app, $type, $pattern, $options=array()) { + $options['type'] = $type ? $type : $options['type']; + $items = egw_link::query($app, $pattern, $options); + + $response = egw_json_response::get(); + $response->data($items); + } } etemplate_widget::registerWidget('etemplate_widget_itempicker', array('itempicker')); \ No newline at end of file diff --git a/etemplate/js/et2_widget_itempicker.js b/etemplate/js/et2_widget_itempicker.js index d2d7a22125..b8d659b8c2 100755 --- a/etemplate/js/et2_widget_itempicker.js +++ b/etemplate/js/et2_widget_itempicker.js @@ -60,6 +60,8 @@ var et2_itempicker = et2_inputWidget.extend({ legacyOptions: ["application"], search_timeout: 200, //ms after change to send query minimum_characters: 2, // Don't send query unless there's at least this many chars + last_search: "", // Remember last search value + current_app: "", // Remember currently chosen application init: function() { this._super.apply(this, arguments); @@ -67,6 +69,7 @@ var et2_itempicker = et2_inputWidget.extend({ this.div = null; this.left = null; this.right = null; + this.right_container = null; this.app_select = null; this.search = null; this.itemlist = null; @@ -75,18 +78,22 @@ var et2_itempicker = et2_inputWidget.extend({ }, createInputWidget: function() { + var _self = this; this.div = $j(document.createElement("div")); this.left = $j(document.createElement("div")); this.right = $j(document.createElement("div")); + this.right_container = $j(document.createElement("div")); this.app_select = $j(document.createElement("ul")); - this.search = $j(document.createElement("div")); + this.search = $j(document.createElement("input")); + this.clear = $j(document.createElement("span")); this.itemlist = $j(document.createElement("div")); // Container elements this.div.addClass("et2_itempicker"); this.left.addClass("et2_itempicker_left"); this.right.addClass("et2_itempicker_right"); + this.right_container.addClass("et2_itempicker_right_container"); // Application select this.app_select.addClass("et2_itempicker_app_select"); @@ -103,23 +110,34 @@ var et2_itempicker = et2_inputWidget.extend({ .click(function() { $j(".et2_itempicker_app_select li").removeClass("selected"); $j(this).addClass("selected"); + _self.current_app = $j(this).attr("id"); }) .append(img); if(item_count == 0) { item.addClass("selected"); // select first item by default + this.current_app = key; } this.app_select.append(item); item_count++; } - if(item_count == 0) - { - this.app_select.hide(); - this.div.addClass("no_app"); - } // Search input field this.search.addClass("et2_itempicker_search"); - //this.search.append(this.createSearchWidget()); + this.search.keyup(function() { + var request = {}; + request.term = $j(this).val(); + _self.query(request); + }); + + // Clear button for search + this.clear + .addClass("ui-icon ui-icon-close") + .click(function(e){ + _self.search.val(""); + _self.itemlist.html(""); + _self.search.focus(); + }) + .hide(); // Itemlist this.itemlist.attr("id", "itempicker_itemlist"); @@ -127,8 +145,10 @@ var et2_itempicker = et2_inputWidget.extend({ // Put everything together this.left.append(this.app_select); - this.right.append(this.search); - this.right.append(this.itemlist); + this.right_container.append(this.search); + this.right_container.append(this.clear); + this.right_container.append(this.itemlist); + this.right.append(this.right_container); this.div.append(this.right); // right before left to have a natural this.div.append(this.left); // z-index for left div over right div @@ -141,6 +161,44 @@ var et2_itempicker = et2_inputWidget.extend({ return this._super.apply(this, arguments); }, + /** + * Ask server for entries matching selected app/type and filtered by search string + */ + query: function(request) { + if(request.term.length < 3) { + return true; + } + // Remember last search + this.last_search = request.term; + + // Allow hook / tie in + if(this.options.query && typeof this.options.query == 'function') + { + if(!this.options.query(request, response)) return false; + } + + //if(request.term in this.cache) { + // return response(this.cache[request.term]); + //} + + this.itemlist.addClass("loading"); + this.clear.show(); + var request = new egw_json_request("etemplate_widget_link::ajax_link_search::etemplate", + [this.current_app, '', request.term, request.options], + this + ); + + request.sendRequest(true, this._results, this); + }, + + /** + * Server found some results + */ + _results: function(data) { + this.itemlist.removeClass("loading"); + this.updateItemList(data); + }, + transformAttributes: function(_attrs) { this._super.apply(this, arguments); @@ -172,6 +230,24 @@ var et2_itempicker = et2_inputWidget.extend({ _attrs["select_options"] = {}; } }, + + updateItemList: function(data) { + var list = $j(document.createElement("ul")); + var item_count = 0; + for(var id in data) { + var item = $j(document.createElement("li")); + item.attr("id", id); + if(item_count%2 == 0) { + item.addClass("row_on"); + } else { + item.addClass("row_off"); + } + item.html(data[id]); + list.append(item); + item_count++; + } + this.itemlist.html(list); + } }); diff --git a/etemplate/templates/default/etemplate2.css b/etemplate/templates/default/etemplate2.css index cc2bcb7c88..edbede21e2 100644 --- a/etemplate/templates/default/etemplate2.css +++ b/etemplate/templates/default/etemplate2.css @@ -802,7 +802,7 @@ div.et2_progress > div { margin: 0; padding: 0; width: 100%; - height: 260px; + height: 256px; } .et2_itempicker_left { display: block; @@ -826,6 +826,13 @@ div.et2_progress > div { background-color: #f9f9f9; } +.et2_itempicker_right_container { + display: block; + position: relative; + width: 100%; + height: 100%; +} + .et2_itempicker_app_select { list-style-type: none; padding: 0; @@ -844,3 +851,38 @@ div.et2_progress > div { border-top-left-radius: 4px; border-bottom-left-radius: 4px; } + +.et2_itempicker_search { + margin: 1em; + margin-bottom: 0; + width: 67%; + padding: 0.2em; +} + +.et2_itempicker_itemlist { + display: block; + border: 1px solid #b6b6b6; + margin: 1em; + margin-bottom: 0; + padding: 0; + height: 67%; + background-color: #ffffff; + overflow: auto; +} + +.et2_itempicker_itemlist ul { + margin: 0; + padding: 0; + list-style-type: none; +} + +.et2_itempicker_itemlist li { + display: block; + margin: 0; + padding: 4px; + color: #284d8a; +} + +.et2_itempicker_itemlist li.row_on { + background-color: #f2f9fe; +}