mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-22 14:41:29 +01:00
Cleanup widget browser
This commit is contained in:
parent
645c3eb3be
commit
b95e9be02a
@ -1,434 +0,0 @@
|
|||||||
/**
|
|
||||||
* EGroupware eTemplate2 widget browser
|
|
||||||
* View & play with et2 widgets - javascript
|
|
||||||
*
|
|
||||||
* @link http://www.egroupware.org
|
|
||||||
* @author Nathan Gray
|
|
||||||
* @author Hadi Nategh
|
|
||||||
* @copyright 2013 Nathan Gray
|
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
|
||||||
* @package etemplate
|
|
||||||
* @subpackage tools
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*egw:uses
|
|
||||||
etemplate2;
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 = jQuery(list_div);
|
|
||||||
this.widget_div = jQuery(widget_div);
|
|
||||||
this.attribute_list = null;
|
|
||||||
|
|
||||||
// Create and popuplate the widget list
|
|
||||||
this._init_list();
|
|
||||||
|
|
||||||
// Build DTD
|
|
||||||
this._init_dtd();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 = jQuery(document.createElement('ul'))
|
|
||||||
.attr('id', 'widgets')
|
|
||||||
.click(function(e) {self.select_widget(e);})
|
|
||||||
.appendTo(this.list_div);
|
|
||||||
|
|
||||||
// Sort the registry
|
|
||||||
var types = [];
|
|
||||||
for(var type in et2_registry)
|
|
||||||
{
|
|
||||||
types.push(type);
|
|
||||||
}
|
|
||||||
types.sort();
|
|
||||||
for(var i = 0; i < types.length; i++)
|
|
||||||
{
|
|
||||||
list.append('<li>'+types[i]+'</li>');
|
|
||||||
this.dump_attributes(types[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build attribute table
|
|
||||||
attribute_table = jQuery(document.createElement('table'));
|
|
||||||
attribute_table.append('<thead class = "ui-widget-header"><td>'+egw().lang('Name')+"</td><td>"+egw().lang("Data type") +
|
|
||||||
"</td><td>"+egw().lang("Value") + "</td></thead>");
|
|
||||||
this.attribute_list = jQuery(document.createElement('tbody'))
|
|
||||||
.appendTo(attribute_table);
|
|
||||||
|
|
||||||
this.list_div.append(
|
|
||||||
jQuery(document.createElement('div'))
|
|
||||||
.attr('id', 'widget_attributes')
|
|
||||||
.append(attribute_table)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
widget_browser.prototype.dump_attributes = function(_type)
|
|
||||||
{
|
|
||||||
console.log(_type);
|
|
||||||
|
|
||||||
try {
|
|
||||||
var attrs = {};
|
|
||||||
window.wb_widget = this.widget = et2_createWidget(_type, attrs, this.et2.widgetContainer);
|
|
||||||
this.widget.loadingFinished();
|
|
||||||
|
|
||||||
if(this.widget !== null && this.widget.attributes)
|
|
||||||
{
|
|
||||||
for(var attr in this.widget.attributes)
|
|
||||||
{
|
|
||||||
console.log(attr, this.widget.attributes[attr]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(e) {
|
|
||||||
console.log('*** '+_type+' error '+(typeof e.message != 'undefined' ? e.message : e));
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
if (this.widget)
|
|
||||||
{
|
|
||||||
this.widget.destroy();
|
|
||||||
delete this.widget;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
jQuery(e.target).parent().children().removeClass("ui-state-active");
|
|
||||||
|
|
||||||
// Clear previous widget
|
|
||||||
if(this.widget)
|
|
||||||
{
|
|
||||||
this.et2.widgetContainer.removeChild(this.widget);
|
|
||||||
this.widget.destroy();
|
|
||||||
this.widget = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the type of widget
|
|
||||||
var type = jQuery(e.target).text();
|
|
||||||
if(!type || e.target.nodeName != 'LI')
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// UI prettyness - show item as selected
|
|
||||||
jQuery(e.target).addClass('ui-state-active');
|
|
||||||
|
|
||||||
// Widget attributes
|
|
||||||
var attrs = {};
|
|
||||||
|
|
||||||
|
|
||||||
window.wb_widget = 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 = jQuery(document.createElement("tr"))
|
|
||||||
.addClass(typeof this.widget[set_function_name] == 'function' ? 'ui-state-default':'ui-state-disabled')
|
|
||||||
// Human Name
|
|
||||||
.append(jQuery(document.createElement('td'))
|
|
||||||
.text(settings.name)
|
|
||||||
)
|
|
||||||
// Data type
|
|
||||||
.append(jQuery(document.createElement('td'))
|
|
||||||
.text(settings.type)
|
|
||||||
);
|
|
||||||
// Add attribute name & description as a tooltip
|
|
||||||
if(settings.description)
|
|
||||||
{
|
|
||||||
egw().tooltipBind(row,settings.description);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value
|
|
||||||
var value = jQuery(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;
|
|
||||||
var input = null;
|
|
||||||
switch(settings.type)
|
|
||||||
{
|
|
||||||
case 'string':
|
|
||||||
input = jQuery('<input/>')
|
|
||||||
.change(function(e) {
|
|
||||||
self.widget[set_function_name].apply(self.widget, [jQuery(e.target).val()]);
|
|
||||||
});
|
|
||||||
input.val(this.widget.options[name]);
|
|
||||||
break;
|
|
||||||
case 'boolean':
|
|
||||||
input = jQuery('<input type="checkbox"/>')
|
|
||||||
.attr("checked", this.widget.options[name])
|
|
||||||
.change(function(e) {
|
|
||||||
self.widget[set_function_name].apply(self.widget, [e.target.checked]);
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
value.text(this.widget.options[name]);
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
input.appendTo(value);
|
|
||||||
|
|
||||||
return row;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialise the DTD generator
|
|
||||||
*/
|
|
||||||
widget_browser.prototype._init_dtd = function ()
|
|
||||||
{
|
|
||||||
//Contains all widgets
|
|
||||||
this.widgets = [];
|
|
||||||
|
|
||||||
//Contains not readonly widgets
|
|
||||||
this.dtd_widgets = [];
|
|
||||||
|
|
||||||
//Contians readonly widgets
|
|
||||||
this.dtd_widgets_ro = [];
|
|
||||||
|
|
||||||
// Contains the whole DTD string
|
|
||||||
this.dtd = "";
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
// Create DTD Generator button and bind click handler on it
|
|
||||||
var dtd_btn = jQuery(document.createElement('button'))
|
|
||||||
.attr({id:'dtd_btn', title:'Generates Document Type Definition (DTD) for all widgets'})
|
|
||||||
.click(function(){
|
|
||||||
self._dtd_builder();
|
|
||||||
})
|
|
||||||
.addClass('dtd_btn')
|
|
||||||
.appendTo('body');
|
|
||||||
dtd_btn.text('DTD Generator');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Iterates over all et2_widget to build DTD tags
|
|
||||||
* and display them as string
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
widget_browser.prototype._dtd_builder = function()
|
|
||||||
{
|
|
||||||
var dtdContentW = "";
|
|
||||||
var i = 0;
|
|
||||||
for (var widget_type in et2_registry)
|
|
||||||
{
|
|
||||||
var attrs = {};
|
|
||||||
|
|
||||||
// creating a dialog popups an empty dialog,
|
|
||||||
// which we don't want therefore
|
|
||||||
// we eliminate dialog tag from dtd ATM.
|
|
||||||
if (widget_type.match(/dialog/,'i')) continue;
|
|
||||||
|
|
||||||
if (!widget_type.match(/nextmatch/,'i'))
|
|
||||||
{
|
|
||||||
|
|
||||||
this.widgets[i] = et2_createWidget(widget_type ,attrs, this.et2.widgetContainer)
|
|
||||||
if (widget_type.match(/_ro/,'i'))
|
|
||||||
{
|
|
||||||
this.dtd_widgets_ro.push( widget_type.replace('_ro',''));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.dtd_widgets.push(widget_type);
|
|
||||||
dtdContentW += this._dtd_widgets(widget_type, this.widgets[i])
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// DTD Final Content
|
|
||||||
this.dtd = this._dtd_header() + dtdContentW;
|
|
||||||
|
|
||||||
//Display DTD resault and UI to copy/download them
|
|
||||||
et2_createWidget("dialog", {
|
|
||||||
callback: function() {},
|
|
||||||
title: egw.lang('DTD Result'),
|
|
||||||
buttons:et2_dialog.BUTTONS_OK,
|
|
||||||
value: {
|
|
||||||
content: {
|
|
||||||
value: this.dtd,
|
|
||||||
message: egw.lang('DTD Content')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
template: egw.webserverUrl+'/api/templates/default/dtd.xet',
|
|
||||||
modal:true,
|
|
||||||
resizable:false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds some specific header DTD tags (e.g. ENTITY)
|
|
||||||
*
|
|
||||||
* @returns {String} returns dtd header tags as string
|
|
||||||
*/
|
|
||||||
widget_browser.prototype._dtd_header = function ()
|
|
||||||
{
|
|
||||||
var dtd = '';
|
|
||||||
dtd = '<!ENTITY % Widgets "' + this.dtd_widgets.join('|') + '">\r\n';
|
|
||||||
dtd += '<!ELEMENT overlay (%Widgets;)*>\r\n';
|
|
||||||
return dtd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds DTD ELEMENTS and teir ATTRLIST for given widget
|
|
||||||
*
|
|
||||||
* @param {string} _type widget type
|
|
||||||
* @param {object} _widget widget object
|
|
||||||
* @returns {String} returns generated dtd tags in string
|
|
||||||
*/
|
|
||||||
widget_browser.prototype._dtd_widgets = function (_type, _widget)
|
|
||||||
{
|
|
||||||
var dtd = '';
|
|
||||||
switch (_type)
|
|
||||||
{
|
|
||||||
// Special handling for menulist widget as it has a complicated structure
|
|
||||||
case 'menulist':
|
|
||||||
dtd = '<!ELEMENT menulist (menupopup)>\r\n';
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Special handling for grid widget as it has a complicated structure
|
|
||||||
case 'grid':
|
|
||||||
dtd += '<!ELEMENT grid (columns,rows)>\r\n';
|
|
||||||
dtd += '<!ELEMENT columns (column)*>\r\n\
|
|
||||||
<!ELEMENT column EMPTY >\n\
|
|
||||||
<!ATTLIST column\n\
|
|
||||||
disabled CDATA #IMPLIED\n\
|
|
||||||
class CDATA #IMPLIED\n\
|
|
||||||
width CDATA #IMPLIED>\n\
|
|
||||||
<!ELEMENT rows (row)*>\n\
|
|
||||||
<!ELEMENT row (%Widgets;)>\n\
|
|
||||||
<!ATTLIST row\n\
|
|
||||||
class CDATA #IMPLIED\n\
|
|
||||||
height CDATA #IMPLIED\n\
|
|
||||||
valign CDATA #IMPLIED\n\
|
|
||||||
disabled CDATA #IMPLIED\n\
|
|
||||||
part CDATA #IMPLIED\n\
|
|
||||||
>\r\n';
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Special handling for tabbox widget as it has a complicated structure
|
|
||||||
case 'tabbox':
|
|
||||||
dtd += '<!ELEMENT tabbox (tabs,tabpanels)>\r\n';
|
|
||||||
dtd += '<!ELEMENT tabs (tab)>\r\n';
|
|
||||||
dtd += '<!ELEMENT tabpanels (template)>\r\n';
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Widget which can be a parent
|
|
||||||
case 'vbox':
|
|
||||||
case 'hbox':
|
|
||||||
case 'box':
|
|
||||||
case 'groupbox':
|
|
||||||
case 'template':
|
|
||||||
dtd = '<!ELEMENT '+ _type + ' (%Widgets;)*>\r\n';
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Other widgets which only can be used as child
|
|
||||||
default:
|
|
||||||
dtd = '<!ELEMENT '+ _type + ' EMPTY>\r\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
dtd +='<!ATTLIST ' + _type + '\r\n';
|
|
||||||
for(var attr in _widget.attributes)
|
|
||||||
{
|
|
||||||
//DTD attribute helper object
|
|
||||||
var dtdAttrObj = {attrType:'CDATA',attrVal:'', attrReq:' #IMPLIED'};
|
|
||||||
|
|
||||||
//if(_widget.attributes[attr].ignore) continue;
|
|
||||||
switch (_widget.attributes[attr].type)
|
|
||||||
{
|
|
||||||
case 'boolean':
|
|
||||||
dtdAttrObj.attrType = ' (true|false)';
|
|
||||||
dtdAttrObj.attrVal = ' "' + _widget.attributes[attr].default + '"';
|
|
||||||
dtdAttrObj.attrReq = '';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
dtdAttrObj.attrType = ' CDATA';
|
|
||||||
|
|
||||||
if (_widget.attributes[attr].default !="" &&
|
|
||||||
typeof _widget.attributes[attr].default != 'undefined' &&
|
|
||||||
!jQuery.isEmptyObject(_widget.attributes[attr].default))
|
|
||||||
{
|
|
||||||
dtdAttrObj.attrReq = '';
|
|
||||||
dtdAttrObj.attrVal = ' "' + _widget.attributes[attr].default + '"';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dtdAttrObj.attrVal = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
dtd += attr + dtdAttrObj.attrType +
|
|
||||||
(dtdAttrObj.attrVal !=""?dtdAttrObj.attrVal:'') +
|
|
||||||
dtdAttrObj.attrReq +'\r\n';
|
|
||||||
}
|
|
||||||
dtd += '>\r\n';
|
|
||||||
return dtd;
|
|
||||||
}
|
|
||||||
|
|
||||||
egw_LAB.wait(function() {
|
|
||||||
var wb = new widget_browser(
|
|
||||||
document.getElementById("widget_list"),
|
|
||||||
document.getElementById("widget_container")
|
|
||||||
);
|
|
||||||
});
|
|
@ -1,58 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* EGroupware eTemplate2 widget browser
|
|
||||||
*
|
|
||||||
* @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$
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace EGroupware\Api\Etemplate;
|
|
||||||
|
|
||||||
use EGroupware\Api;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* eTemplate2 widget browser
|
|
||||||
*
|
|
||||||
* View & play with et2 widgets. Most of the good stuff happens
|
|
||||||
* on the client side via js, this is the server side.
|
|
||||||
*/
|
|
||||||
class WidgetBrowser
|
|
||||||
{
|
|
||||||
|
|
||||||
public $public_functions = array(
|
|
||||||
'index' => true
|
|
||||||
);
|
|
||||||
|
|
||||||
public static function index()
|
|
||||||
{
|
|
||||||
$GLOBALS['egw_info']['flags']['currentapp'] = 'etemplate';
|
|
||||||
$GLOBALS['egw_info']['flags']['app_header'] = 'et2 Widgets';
|
|
||||||
//'js_link_registry' => True,
|
|
||||||
|
|
||||||
// Widget browser code
|
|
||||||
Api\Framework::includeJS('/api/js/etemplate/widget_browser.js');
|
|
||||||
|
|
||||||
// Include the etemplate2 javascript code
|
|
||||||
Api\Framework::includeJS('.', 'etemplate2', 'etemplate');
|
|
||||||
|
|
||||||
// Include the jQuery-UI CSS - many more complex widgets use it
|
|
||||||
$theme = 'redmond';
|
|
||||||
Api\Framework::includeCSS("/vendor/bower-asset/jquery-ui/themes/$theme/jquery-ui-1.10.3.custom.css");
|
|
||||||
|
|
||||||
Api\Framework::includeCSS('/api/templates/default/etemplate2.css');
|
|
||||||
|
|
||||||
Api\Framework::includeCSS('api','widget_browser',false);
|
|
||||||
|
|
||||||
// load translations
|
|
||||||
Api\Translation::add_app('etemplate');
|
|
||||||
|
|
||||||
$GLOBALS['egw']->framework->render('
|
|
||||||
<div id="widget_list"></div>
|
|
||||||
<div id="widget_container"></div>');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
/**
|
|
||||||
* CSS for the widget browser
|
|
||||||
* Api\Etemplate\WidgetBrowser.php
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
/* DTD Generator Button*/
|
|
||||||
.dtd_btn{
|
|
||||||
width: 100px;
|
|
||||||
height: 35px;
|
|
||||||
float: right;
|
|
||||||
box-shadow: 1px 1px 1px 1px gray;
|
|
||||||
border: white solid 1px;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user