From 7855944a3ae951168765e4596b82b886755f1cde Mon Sep 17 00:00:00 2001 From: Nathan Gray Date: Mon, 11 Feb 2013 08:10:25 +0000 Subject: [PATCH] Add quick viewer for et2 widgets --- .../inc/class.etemplate_et2_widgets.inc.php | 67 +++++++ etemplate/inc/hook_sidebox_menu.inc.php | 7 +- etemplate/js/widget_browser.js | 185 ++++++++++++++++++ .../templates/default/widget_browser.css | 46 +++++ 4 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 etemplate/inc/class.etemplate_et2_widgets.inc.php create mode 100644 etemplate/js/widget_browser.js create mode 100644 etemplate/templates/default/widget_browser.css diff --git a/etemplate/inc/class.etemplate_et2_widgets.inc.php b/etemplate/inc/class.etemplate_et2_widgets.inc.php new file mode 100644 index 0000000000..de1fe48429 --- /dev/null +++ b/etemplate/inc/class.etemplate_et2_widgets.inc.php @@ -0,0 +1,67 @@ + true + ); + + public static function index($content = array()) + { + $GLOBALS['egw_info']['flags']['currentapp'] = 'etemplate'; + $GLOBALS['egw_info']['flags']['app_header'] = 'et2 Widgets'; + //'js_link_registry' => True, + + // Widget browser code + egw_framework::validate_file('/etemplate/js/widget_browser.js'); + + // Include the etemplate2 javascript code + egw_framework::validate_file('.', 'etemplate2', 'etemplate'); + + egw_framework::includeCSS('/etemplate/templates/default/etemplate2.css'); + + // Include the jQuery-UI CSS - many more complex widgets use it + $theme = 'redmond'; + egw_framework::includeCSS("/phpgwapi/js/jquery/jquery-ui/$theme/jquery-ui-1.8.21.custom.css"); + + egw_framework::includeCSS('etemplate','widget_browser',false); + + // load translations + translation::add_app('etemplate'); + + common::egw_header(); + parse_navbar(); + + echo ' +
+
+ '; + common::egw_footer(); + } +} diff --git a/etemplate/inc/hook_sidebox_menu.inc.php b/etemplate/inc/hook_sidebox_menu.inc.php index 243572a364..aad504eb66 100644 --- a/etemplate/inc/hook_sidebox_menu.inc.php +++ b/etemplate/inc/hook_sidebox_menu.inc.php @@ -1,6 +1,6 @@ $docs.'reference.html', 'target' => 'docs' ), + array( + 'text' => 'eTemplate2 Reference', + 'link' => egw_framework::link('/index.php','menuaction=etemplate.etemplate_et2_widgets.index'), + 'target' => '_blank' + ), array( 'text' => 'eGroupWare '.lang('Documentation'), 'no_lang' => True, diff --git a/etemplate/js/widget_browser.js b/etemplate/js/widget_browser.js new file mode 100644 index 0000000000..ff76631b3d --- /dev/null +++ b/etemplate/js/widget_browser.js @@ -0,0 +1,185 @@ +/** + * EGroupware eTemplate2 widget browser + * View & play with et2 widgets - javascript + * + * @link http://www.egroupware.org + * @author Nathan Gray + * @copyright 2013 Nathan Gray + * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License + * @package etemplate + * @subpackage tools + * @version $Id$ + */ + + +/** + * widget_browser shows a list of widgets, and allows you to view them one at a time. + * You can view and edit defined properties to see the effect. + */ +function widget_browser(list_div, widget_div) +{ + + // Initialize etemplate2 + this.et2 = new etemplate2(widget_div, "etemplate::ajax_process_content"); + + // Normally this would be passed from app + var _data = {} + + // Create the basic widget container and attach it to the DOM + // Not really needed, but let's be consitent with et2 + this.et2.widgetContainer = new et2_container(null); + this.et2.widgetContainer.setApiInstance(egw('etemplate', egw.elemWindow(this.et2.DOMContainer))); + this.et2.widgetContainer.setInstanceManager(this.et2); + this.et2.widgetContainer.setParentDOMNode(this.et2.DOMContainer); + this.et2.widgetContainer.setArrayMgrs(this.et2._createArrayManagers(_data)); + + // Set up UI + this.list_div = $j(list_div); + this.widget_div = $j(widget_div); + this.attribute_list = null; + + // Create and popuplate the widget list + this._init_list(); + +} + +/** + * Read the widget registry and create a list. + * The user can pick a widget, and we'll instanciate it. + */ +widget_browser.prototype._init_list = function() +{ + var self = this; + + // Create list + var list = $j(document.createElement('ul')) + .attr('id', 'widgets') + .click(function(e) {self.select_widget(e);}) + .appendTo(this.list_div); + for(var type in et2_registry) + { + var class_name = et2_registry[type]; + list.append('
  • '+type+'
  • '); + } + + // Build attribute table + attribute_table = $j(document.createElement('table')); + attribute_table.append(''+egw().lang('Name')+""+egw().lang("Data type") + + ""+egw().lang("Value") + ""); + this.attribute_list = $j(document.createElement('tbody')) + .appendTo(attribute_table); + + this.list_div.append( + $j(document.createElement('div')) + .attr('id', 'widget_attributes') + .append(attribute_table) + ); +} + +/** + * User selected a widget from the list + * + * Create an instance of the widget, get its attributes, and display it. + */ +widget_browser.prototype.select_widget = function(e,f) +{ + // UI prettyness - clear selected + $j(e.target).parent().children().removeClass("ui-state-active"); + + // Clear previous widget + if(this.widget) + { + this.widget.free(); + } + + // Get the type of widget + var type = $j(e.target).text(); + if(!type || e.target.nodeName != 'LI') + { + return; + } + + // UI prettyness - show item as selected + $j(e.target).addClass('ui-state-active'); + + // Widget attributes + var attrs = {}; + + + this.widget = et2_createWidget(type, attrs, this.et2.widgetContainer); + this.widget.loadingFinished(); + + // Attribute list + this.attribute_list.empty(); + if(this.widget !== null && this.widget.attributes) + { + for(var attr in this.widget.attributes) + { + if(this.widget.attributes[attr].ignore) continue; + this.create_attribute(attr, this.widget.attributes[attr]) + .appendTo(this.attribute_list); + } + } + +} + + + +/** + * Create the UI (DOM) elements for a single widget attribute + * + * @param name Name of the attribute + * @param settings attribute attributes (Human name, description, etc) + */ +widget_browser.prototype.create_attribute = function(name, settings) +{ + var set_function_name = "set_"+name; + var row = $j(document.createElement("tr")) + .addClass(typeof this.widget[set_function_name] == 'function' ? 'ui-state-default':'ui-state-disabled') + // Human Name + .append($j(document.createElement('td')) + .text(settings.name) + ) + // Data type + .append($j(document.createElement('td')) + .text(settings.type) + ); + // Add attribute name & description as a tooltip + if(settings.description) + { + egw().tooltipBind(row,settings.description); + } + + // Value + var value = $j(document.createElement('td')).appendTo(row); + if(row.hasClass('ui-state-disabled')) + { + // No setter - just use text + value.text(this.widget.options[name]); + return row; + } + + // Setter function - maybe editable? + var self = this; + switch(settings.type) + { + case 'string': + value.append('') + .change(function(e) { + self.widget[set_function_name].apply(self.widget, [$j(e.target).val()]); + }); + break; + case 'boolean': + value.append('') + .change(function(e) { + self.widget[set_function_name].apply(self.widget, [$j(e.target).val()]); + }); + break; + default: + value.text(this.widget.options[name]); + return row; + } + value.val(this.widget.options[name]); + + return row; +} diff --git a/etemplate/templates/default/widget_browser.css b/etemplate/templates/default/widget_browser.css new file mode 100644 index 0000000000..fc1e53eff6 --- /dev/null +++ b/etemplate/templates/default/widget_browser.css @@ -0,0 +1,46 @@ +/** + * CSS for the widget browser + * etemplate.etemplate_et2_widgets.index + */ + +/* Basic layout */ +#widget_list { + position: fixed; + width: 260px; +} +#widget_list ul { + position: fixed; + top: 0px; + overflow-y: scroll; + height: 55%; + width: inherit; + list-style-type: none; + margin: 0; + padding: 0; +} +#widget_attributes { + position: fixed; + bottom: 0px; + height: 44%; + width: inherit; + overflow-y: auto; + margin: 0; + padding: 0; +} +#widget_attributes table{ + width: 100%; +} +#widget_container{ + position: fixed; + left: 260px; + padding: 20px; +} + +/* Nicer looks */ +#widget_list li { + cursor:pointer; + padding: 0.4em; + font-size: 1.4em; + height: 16px; + width: 50%; +}