New tag list widget, supports ajax & static options

This commit is contained in:
Nathan Gray 2013-07-18 15:27:39 +00:00
parent 14ebff54c9
commit 4ae6094d8d
3 changed files with 246 additions and 0 deletions

View File

@ -0,0 +1,54 @@
<?php
/**
* EGroupware - eTemplate serverside of tag list widget
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package etemplate
* @subpackage api
* @link http://www.egroupware.org
* @author Nathan Gray
* @copyright 2013 Nathan Gray
* @version $Id$
*/
/**
* eTemplate tag list widget
*/
class etemplate_widget_taglist extends etemplate_widget
{
/**
* Constructor
*
* Overrides parent to check for $xml first, prevents errors when instanciated without (via AJAX)
*
* @param string|XMLReader $xml string with xml or XMLReader positioned on the element to construct
* @throws egw_exception_wrong_parameter
*/
public function __construct($xml = '')
{
if($xml) {
parent::__construct($xml);
}
}
/**
* The default search goes to the link system
*
* Find entries that match query parameter (from link system) and format them
* as the widget expects, a list of {id: ..., label: ...} objects
*/
public static function ajax_search() {
$app = $_REQUEST['app'];
$query = $_REQUEST['query'];
$options = array();
$links = egw_link::query($app, $query, $options);
$results = array();
foreach($links as $id => $name)
{
$results[] = array('id'=>$id, 'label' => htmlspecialchars($name));
}
header('Content-Type: application/json; charset=utf-8');
echo json_encode($results);
common::egw_exit();
}
}

View File

@ -0,0 +1,191 @@
/**
* EGroupware eTemplate2 - JS Tag list object
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package etemplate
* @subpackage api
* @link http://www.egroupware.org
* @author Nathan Gray
* @copyright Nathan Gray 2013
* @version $Id$
*/
"use strict";
/*egw:uses
et2_core_inputWidget;
/phpgwapi/js/jquery/magicsuggest/src/magicsuggest-1.3.0.js;
*/
/**
* Tag list widget
*
* A cross between auto complete, selectbox and chosen multiselect
*
* Uses xoxco tagsinput library
* @see http://xoxco.com/projects/code/tagsinput/
* @augments et2_inputWidget
*/
var et2_taglist = et2_inputWidget.extend(
{
attributes: {
"empty_label": {
"name": "Empty label",
"type": "string",
"default": "",
"description": "Textual label for when nothing is selected"
},
"select_options": {
"type": "any",
"name": "Select options",
"default": null, //[{id: "a", label: "Alpha"},{id:"b", label: "Beta"}],
"description": "Internaly used to hold the select options."
},
// Value can be CSV String or Array
"value": {
"type": "any"
},
"autocomplete_url": {
"name": "Autocomplete source",
"type": "string",
"default": "etemplate_widget_taglist::ajax_search::etemplate",
"description": "Menuaction (app.class.function) for autocomplete data source. Must return actual JSON, and nothing more."
},
"autocomplete_params": {
"name": "Autocomplete parameters",
"type": "any",
"default": {},
"description": "Extra parameters passed to autocomplete URL"
},
"onAddTag": {
"name": "onAddTag",
"type": "js",
"default": et2_no_init,
"description": "Callback when a tag is added",
},
"onRemoveTag": {
"name": "onRemoveTag",
"type": "js",
"default": et2_no_init,
"description": "Callback when a tag is removed",
},
"onchange": {
"name": "onChange",
"type": "js",
"default": et2_no_init,
"description": "Callback when tags are changed",
},
"width": {
default: "150px"
}
},
/**
* Construtor
*
* @memberOf et2_selectbox
*/
init: function() {
this._super.apply(this, arguments);
// jQuery wrapped DOM node
this.div = jQuery("<div></div>");
// magicSuggest object
this.taglist = null;
this.setDOMNode(this.div[0]);
},
destroy: function() {
if(this.div != null)
{
// Undo the plugin
}
this._super.apply(this, arguments);
},
doLoadingFinished: function() {
this._super.apply(this, arguments);
// Initialize magicSuggest here
if(this.taglist != null) return;
this.taglist = this.div.magicSuggest({
id: this.getInstanceManager().uniqueId + '_' + this.id,
data: this.options.select_options ? this.options.select_options : this.options.autocomplete_url,
dataUrlParams: this.options.autocomplete_params,
method: 'GET',
displayField: "label",
emptyText: this.options.empty_label,
hideTrigger: true,
noSuggestionText: this.egw().lang("No suggestions"),
required: this.options.required
});
return true;
},
set_autocomplete_url: function(source)
{
if(source.indexOf('http') != 0)
{
source = this.egw().ajaxUrl(source);
}
this.options.autocomplete_url = source;
if(this.taglist == null) return;
this.taglist.setData(source);
},
/**
* Set the list of suggested options to a static list.
*
* You can pass either the traditional {id:label, id:label...} or an array of objects,
* and either will be coerced to what is needed.
*
* $param Array _options
*/
set_select_options: function(_options)
{
for (var key in _options)
{
var option = {id: key};
// Translate the options
if(!this.options.no_lang)
{
if (typeof _options[key] === 'object')
{
if(_options[key]["label"]) option["label"] = this.egw().lang(_options[key]["label"]);
if(_options[key]["title"]) option["title"] = this.egw().lang(_options[key]["title"]);
}
else
{
option.label = this.egw().lang(_options[key]);
}
}
this.options.select_options.push(option);
}
if(this.taglist == null) return;
this.taglist.setData(this.options.select_options);
},
set_value: function(value) {
if(this.taglist == null) return;
this.taglist.clear(true);
this.taglist.setValue(value);
},
getValue: function() {
if(this.taglist == null) return null;
return this.taglist.getValue();
}
});
et2_register_widget(et2_taglist, ["taglist"]);
// Require css - merge into etemplate2.css with all other widgets when done
if(typeof egw != 'undefined') egw(window).includeCSS(egw.webserverUrl + "/phpgwapi/js/jquery/magicsuggest/src/magicsuggest-1.3.0.css");

View File

@ -36,6 +36,7 @@
et2_widget_html; et2_widget_html;
et2_widget_htmlarea; et2_widget_htmlarea;
et2_widget_tabs; et2_widget_tabs;
et2_widget_taglist;
et2_widget_tree; et2_widget_tree;
et2_widget_historylog; et2_widget_historylog;
et2_widget_hrule; et2_widget_hrule;