forked from extern/egroupware
Progress on custom fields widgets
This commit is contained in:
parent
d88d25b704
commit
575d21b962
169
etemplate/inc/class.etemplate_widget_customfields.inc.php
Normal file
169
etemplate/inc/class.etemplate_widget_customfields.inc.php
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* EGroupware - eTemplate custom fields 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 2011 Nathan Gray
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Widgets for custom fields and listing custom fields
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class etemplate_widget_customfields extends etemplate_widget_transformer
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allowd types of customfields
|
||||||
|
*
|
||||||
|
* The additionally allowed app-names from the link-class, will be add by the edit-method only,
|
||||||
|
* as the link-class has to be called, which can NOT be instanciated by the constructor, as
|
||||||
|
* we get a loop in the instanciation.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected static $cf_types = array(
|
||||||
|
'text' => 'Text',
|
||||||
|
'float' => 'Float',
|
||||||
|
'label' => 'Label',
|
||||||
|
'select' => 'Selectbox',
|
||||||
|
'ajax_select' => 'Search',
|
||||||
|
'radio' => 'Radiobutton',
|
||||||
|
'checkbox' => 'Checkbox',
|
||||||
|
'date' => 'Date',
|
||||||
|
'date-time'=> 'Date+Time',
|
||||||
|
'select-account' => 'Select account',
|
||||||
|
'button' => 'Button', // button to execute javascript
|
||||||
|
'url' => 'Url',
|
||||||
|
'url-email'=> 'EMail',
|
||||||
|
'url-phone'=> 'Phone number',
|
||||||
|
'htmlarea' => 'Formatted Text (HTML)',
|
||||||
|
'link-entry' => 'Select entry', // should be last type, as the individual apps get added behind
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var $prefix string Prefix for every custiomfield name returned in $content (# for general (admin) customfields)
|
||||||
|
*/
|
||||||
|
protected static $prefix = '#';
|
||||||
|
|
||||||
|
protected $legacy_options = 'sub-type,use-private,field-names';
|
||||||
|
|
||||||
|
protected static $transformation = array(
|
||||||
|
'type' => array(
|
||||||
|
'customfields-types' => array(
|
||||||
|
'type' => 'select',
|
||||||
|
'sel_options' => array()
|
||||||
|
),
|
||||||
|
'customfields-list' => array(
|
||||||
|
'readonly' => true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public function __construct($xml)
|
||||||
|
{
|
||||||
|
parent::__construct($xml);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill type options in self::$request->sel_options to be used on the client
|
||||||
|
*
|
||||||
|
* @param string $cname
|
||||||
|
*/
|
||||||
|
public function beforeSendToClient($cname)
|
||||||
|
{
|
||||||
|
$form_name = self::form_name($cname, $this->id);
|
||||||
|
$app =& $this->getElementAttribute($form_name, 'app');
|
||||||
|
|
||||||
|
if(!$app)
|
||||||
|
{
|
||||||
|
$app =& $this->setElementAttribute($form_name, 'app', $GLOBALS['egw_info']['flags']['currentapp']);
|
||||||
|
$customfields =& $this->setElementAttribute($form_name, 'customfields', config::get_customfields($app));
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we are in the etemplate editor or the app has no cf's, load the cf's from the app the tpl belongs too
|
||||||
|
if ($app && $app != 'stylite' && $app != $GLOBALS['egw_info']['flags']['currentapp'] && (
|
||||||
|
$GLOBALS['egw_info']['flags']['currentapp'] == 'etemplate' || !$this->attrs['customfields'] ||
|
||||||
|
etemplate::$hooked
|
||||||
|
))
|
||||||
|
{
|
||||||
|
// app changed
|
||||||
|
$customfields =& config::get_customfields($app);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter fields
|
||||||
|
if($this->attrs['field-names'])
|
||||||
|
{
|
||||||
|
if($this->attrs['field-names'][0] == '!') {
|
||||||
|
$negate_field_filter = true;
|
||||||
|
$this->attrs['field-names'] = substr($this->attrs['field_names'],1);
|
||||||
|
}
|
||||||
|
$field_filter = explode(',', $this->attrs['field_names']);
|
||||||
|
}
|
||||||
|
$fields = $customfields;
|
||||||
|
foreach((array)$fields as $key => $field)
|
||||||
|
{
|
||||||
|
// remove private or non-private cf's, if only one kind should be displayed
|
||||||
|
if ((string)$this->attrs['use-private'] !== '' && (boolean)$field['private'] != (boolean)$this->attrs['use-private'])
|
||||||
|
{
|
||||||
|
unset($fields[$key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove filtered fields
|
||||||
|
if($field_filter && (!$negate_field_filter && !in_array($key, $field_filter) ||
|
||||||
|
$negate_field_filter && in_array($key, $field_filter)))
|
||||||
|
{
|
||||||
|
unset($fields[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check if name refers to a single custom field --> show only that
|
||||||
|
if (($pos=strpos($form_name,$this->prefix)) !== false && // allow the prefixed name to be an array index too
|
||||||
|
preg_match("/$this->prefix([^\]]+)/",$form_name,$matches) && isset($fields[$name=$matches[1]]))
|
||||||
|
{
|
||||||
|
$fields = array($name => $fields[$name]);
|
||||||
|
$value = array($this->prefix.$name => $value);
|
||||||
|
$singlefield = true;
|
||||||
|
$form_name = substr($form_name,0,-strlen("[$this->prefix$name]"));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($type = $this->type)
|
||||||
|
{
|
||||||
|
case 'customfields-types':
|
||||||
|
foreach(self::$cf_types as $lname => $label)
|
||||||
|
{
|
||||||
|
$sel_options[$lname] = lang($label);
|
||||||
|
$fields_with_vals[]=$lname;
|
||||||
|
}
|
||||||
|
$link_types = egw_link::app_list();
|
||||||
|
ksort($link_types);
|
||||||
|
foreach($link_types as $lname => $label) $sel_options[$lname] = '- '.$label;
|
||||||
|
|
||||||
|
self::$transformation['type'][$type]['sel_options'] = $sel_options;
|
||||||
|
self::$transformation['type'][$type]['no_lang'] = true;
|
||||||
|
return parent::beforeSendToClient($form_name);
|
||||||
|
case 'customfields-list':
|
||||||
|
foreach(array_reverse($fields) as $lname => $field)
|
||||||
|
{
|
||||||
|
if (!empty($this->attrs['sub-type']) && !empty($field['type2']) && strpos(','.$field['type2'].',',','.$type2.',') === false) continue; // not for our content type//
|
||||||
|
if (isset($value[$this->prefix.$lname]) && $value[$this->prefix.$lname] !== '') //break;
|
||||||
|
{
|
||||||
|
$fields_with_vals[]=$lname;
|
||||||
|
}
|
||||||
|
//$stop_at_field = $name;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
foreach(array_reverse($fields) as $lname => $field)
|
||||||
|
{
|
||||||
|
$fields_with_vals[]=$lname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parent::beforeSendToClient($cname);
|
||||||
|
$this->setElementAttribute($form_name, 'fields', $fields_with_vals);
|
||||||
|
}
|
||||||
|
}
|
190
etemplate/js/et2_extension_customfields.js
Normal file
190
etemplate/js/et2_extension_customfields.js
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
/**
|
||||||
|
* eGroupWare eTemplate2 - JS Custom fields 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 2011
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*egw:uses
|
||||||
|
lib/tooltip;
|
||||||
|
jquery.jquery;
|
||||||
|
et2_core_xml;
|
||||||
|
et2_core_DOMWidget;
|
||||||
|
et2_core_inputWidget;
|
||||||
|
*/
|
||||||
|
|
||||||
|
var et2_customfields_list = et2_DOMWidget.extend([et2_IDetachedDOM], {
|
||||||
|
|
||||||
|
attributes: {
|
||||||
|
'customfields': {
|
||||||
|
'name': 'Custom fields',
|
||||||
|
'description': 'Auto filled'
|
||||||
|
},
|
||||||
|
'fields': {
|
||||||
|
'name': 'Custom fields',
|
||||||
|
'description': 'Auto filled'
|
||||||
|
},
|
||||||
|
'value': {
|
||||||
|
'name': 'Custom fields',
|
||||||
|
'description': 'Auto filled'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
prefix: '#',
|
||||||
|
|
||||||
|
init: function() {
|
||||||
|
this._super.apply(this, arguments);
|
||||||
|
|
||||||
|
// Create the table body and the table
|
||||||
|
this.tbody = $j(document.createElement("tbody"));
|
||||||
|
this.table = $j(document.createElement("table"))
|
||||||
|
.addClass("et2_grid");
|
||||||
|
this.table.append(this.tbody);
|
||||||
|
|
||||||
|
this.rows = {};
|
||||||
|
this.widgets = {};
|
||||||
|
this.detachedNodes = [];
|
||||||
|
|
||||||
|
if(this.options && this.options.customfields)
|
||||||
|
{
|
||||||
|
this.loadFields();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function() {
|
||||||
|
this._super.apply(this, arguments);
|
||||||
|
this.rows = null;
|
||||||
|
this.widgets = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
getDOMNode: function(_sender) {
|
||||||
|
// If the parent class functions are asking for the DOM-Node, return the
|
||||||
|
// outer table.
|
||||||
|
if (_sender == this)
|
||||||
|
{
|
||||||
|
return this.table[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether the _sender object exists inside the management array
|
||||||
|
if(this.rows && _sender.id && this.rows[_sender.id])
|
||||||
|
{
|
||||||
|
return this.rows[_sender.id];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
loadFields: function() {
|
||||||
|
if(!this.options || !this.options.customfields) return;
|
||||||
|
if(!this.isInTree()) return;
|
||||||
|
|
||||||
|
// Create the table rows
|
||||||
|
for(var field_name in this.options.customfields)
|
||||||
|
{
|
||||||
|
if(this.rows[field_name]) continue;
|
||||||
|
|
||||||
|
var field = this.options.customfields[field_name];
|
||||||
|
var row = jQuery(document.createElement("tr"))
|
||||||
|
.appendTo(this.tbody);
|
||||||
|
var cf = jQuery(document.createElement("td"))
|
||||||
|
.appendTo(row);
|
||||||
|
var attrs = jQuery.extend(true, {'id': field_name}, field);
|
||||||
|
if(this._type == 'customfields-list') {
|
||||||
|
this.detachedNodes.push(cf[0]);
|
||||||
|
this.rows[field_name] = cf[0];
|
||||||
|
} else {
|
||||||
|
// Label in first column, widget in 2nd
|
||||||
|
cf.text(field.label + "");
|
||||||
|
cf = jQuery(document.createElement("td"))
|
||||||
|
.appendTo(row);
|
||||||
|
this.rows[field_name] = cf[0];
|
||||||
|
}
|
||||||
|
// No label on the widget itself
|
||||||
|
delete(attrs.label);
|
||||||
|
var widget = this.widgets[field_name] = et2_createWidget(field.type, attrs, this);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
transformAttributes: function(_attrs) {
|
||||||
|
this._super.apply(this, arguments);
|
||||||
|
|
||||||
|
if (this.id)
|
||||||
|
{
|
||||||
|
// Set the value for this element
|
||||||
|
var contentMgr = this.getArrayMgr("content");
|
||||||
|
if (contentMgr != null) {
|
||||||
|
var val = contentMgr.getEntry(this.id);
|
||||||
|
if (val !== null)
|
||||||
|
{
|
||||||
|
// Only set the values that match desired custom fields
|
||||||
|
_attrs["value"] = {};
|
||||||
|
for(var key in val)
|
||||||
|
{
|
||||||
|
if(key.indexOf(this.prefix) == 0) {
|
||||||
|
_attrs["value"][key] = val[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//_attrs["value"] = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add in settings that are objects
|
||||||
|
if(!_attrs.customfields)
|
||||||
|
{
|
||||||
|
var data = this.getArrayMgr("modifications").getEntry(this.id);
|
||||||
|
for(var key in data)
|
||||||
|
{
|
||||||
|
if(data[key] instanceof Object && ! _attrs[key]) _attrs[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(this.options && this.options.customfields)
|
||||||
|
{
|
||||||
|
this.loadFields();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
set_value: function(_value) {
|
||||||
|
if(!this.options.customfields) return;
|
||||||
|
for(var field_name in this.options.customfields)
|
||||||
|
{
|
||||||
|
if(!this.widgets[field_name] || !this.widgets[field_name].set_value) continue;
|
||||||
|
this.widgets[field_name].set_value(_value[this.prefix + field_name]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code for implementing et2_IDetachedDOM
|
||||||
|
*/
|
||||||
|
getDetachedAttributes: function(_attrs)
|
||||||
|
{
|
||||||
|
_attrs.push("value", "class");
|
||||||
|
},
|
||||||
|
|
||||||
|
getDetachedNodes: function()
|
||||||
|
{
|
||||||
|
return this.detachedNodes ? this.detachedNodes : [];
|
||||||
|
},
|
||||||
|
|
||||||
|
setDetachedAttributes: function(_nodes, _values)
|
||||||
|
{
|
||||||
|
if (typeof _values["value"] != "undefined")
|
||||||
|
{
|
||||||
|
this.set_value(_values["value"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof _values["class"] != "undefined")
|
||||||
|
{
|
||||||
|
this.set_class(_values["class"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
et2_register_widget(et2_customfields_list, ["customfields", "customfields-list"]);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user