[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Fmsystem-commits] [9631] phpgwapi : uicommon
From: |
Sigurd Nes |
Subject: |
[Fmsystem-commits] [9631] phpgwapi : uicommon |
Date: |
Tue, 19 Jun 2012 14:06:11 +0000 |
Revision: 9631
http://svn.sv.gnu.org/viewvc/?view=rev&root=fmsystem&revision=9631
Author: sigurdne
Date: 2012-06-19 14:06:11 +0000 (Tue, 19 Jun 2012)
Log Message:
-----------
phpgwapi : uicommon
Modified Paths:
--------------
trunk/phpgwapi/inc/class.uicommon.inc.php
Added Paths:
-----------
trunk/phpgwapi/js/yahoo/common.js
trunk/phpgwapi/js/yahoo/datatable.js
trunk/phpgwapi/templates/base/datatable_common.xsl
Modified: trunk/phpgwapi/inc/class.uicommon.inc.php
===================================================================
--- trunk/phpgwapi/inc/class.uicommon.inc.php 2012-06-19 14:04:56 UTC (rev
9630)
+++ trunk/phpgwapi/inc/class.uicommon.inc.php 2012-06-19 14:06:11 UTC (rev
9631)
@@ -77,7 +77,6 @@
self::add_stylesheet('phpgwapi/js/yahoo/paginator/assets/skins/sam/paginator.css');
self::add_stylesheet('phpgwapi/js/yahoo/treeview/assets/skins/sam/treeview.css');
//self::add_stylesheet('controller/templates/base/css/base.css');
- self::add_javascript('controller', 'yahoo',
'common.js');
$this->tmpl_search_path = array();
array_push($this->tmpl_search_path, PHPGW_SERVER_ROOT .
'/phpgwapi/templates/base');
array_push($this->tmpl_search_path, PHPGW_SERVER_ROOT .
'/phpgwapi/templates/' . $GLOBALS['phpgw_info']['server']['template_set']);
@@ -90,6 +89,8 @@
phpgwapi_yui::load_widget('autocomplete');
phpgwapi_yui::load_widget('animation');
+ self::add_javascript('phpgwapi', 'yahoo', 'common.js');
+
$this->url_prefix = str_replace('_', '.',
get_class($this));
$this->dateFormat =
$GLOBALS['phpgw_info']['user']['preferences']['common']['dateformat'];
Added: trunk/phpgwapi/js/yahoo/common.js
===================================================================
--- trunk/phpgwapi/js/yahoo/common.js (rev 0)
+++ trunk/phpgwapi/js/yahoo/common.js 2012-06-19 14:06:11 UTC (rev 9631)
@@ -0,0 +1,777 @@
+/*$Id: yui_booking_i18n.xsl 8267 2011-12-11 12:27:18Z sigurdne $*/
+YAHOO.namespace('portico');
+
+YAHOO.portico.js_alias_method_chain = function(constructor_func, func_name,
new_feature_name, feature_impl_func) {
+ constructor_func.prototype[func_name+'_without_'+new_feature_name] =
constructor_func.prototype[func_name];
+ constructor_func.prototype[func_name+'_with_'+new_feature_name] =
feature_impl_func;
+ constructor_func.prototype[func_name] =
constructor_func.prototype[func_name+'_with_'+new_feature_name];
+};
+
+YAHOO.portico.lang = function(section, config) {
+ config = config || {};
+ if (YAHOO && YAHOO.portico && YAHOO.portico.i18n &&
YAHOO.portico.i18n[section]) {
+ YAHOO.portico.i18n[section](config);
+ }
+ return config;
+};
+
+/** Hook widgets to translations **/
+YAHOO.portico.js_alias_method_chain(YAHOO.widget.Calendar, 'init', 'i18n',
function(id, container, config) {
+ YAHOO.portico.lang('Calendar', config);
+ return this.init_without_i18n(id, container, config);
+});
+
+YAHOO.portico.js_alias_method_chain(YAHOO.widget.DataTable, '_initConfigs',
'i18n', function(config) {
+ YAHOO.portico.lang('DataTable', config);
+ return this._initConfigs_without_i18n(config);
+});
+
+function y2k(number) { return (number < 1000) ? number + 1900 : number; }
+YAHOO.portico.weeknumber = function(when) {
+ var year = when.getFullYear();
+ var month = when.getMonth();
+ var day = when.getDate();
+
+ var newYear = new Date(year,0,1);
+ var modDay = newYear.getDay();
+ if (modDay == 0) modDay=6; else modDay--;
+
+ var daynum = ((Date.UTC(y2k(year),when.getMonth(),when.getDate(),0,0,0)
- Date.UTC(y2k(year),0,1,0,0,0)) /1000/60/60/24) + 1;
+
+ if (modDay < 4 ) {
+ var weeknum = Math.floor((daynum+modDay-1)/7)+1;
+ } else {
+ var weeknum = Math.floor((daynum+modDay-1)/7);
+ if (weeknum == 0) {
+ year--;
+ var prevNewYear = new Date(year,0,1);
+ var prevmodDay = prevNewYear.getDay();
+ if (prevmodDay == 0) prevmodDay = 6; else prevmodDay--;
+ if (prevmodDay < 4) weeknum = 53; else weeknum = 52;
+ }
+ }
+ return + weeknum;
+}
+
+parseISO8601 = function (string) {
+ var regexp = "(([0-9]{4})(-([0-9]{1,2})(-([0-9]{1,2}))))?(
)?(([0-9]{1,2}):([0-9]{1,2}))?";
+ var d = string.match(new RegExp(regexp));
+ var year = d[2] ? (d[2] * 1) : 0;
+ date = new Date(year, (d[4]||1)-1, d[6]||0);
+ if(d[9])
+ date.setHours(d[9]);
+ if(d[10])
+ date.setMinutes(d[10]);
+ return date;
+};
+
+YAHOO.portico.serializeForm = function(formID) {
+ var form = YAHOO.util.Dom.get(formID);
+ var values = [];
+ for(var i=0; i < form.elements.length; i++) {
+ var e = form.elements[i];
+ if(e.type=='checkbox' || e.type=='radio') {
+ if(e.checked) {
+ values.push(e.name + '=' +
encodeURIComponent(e.value));
+ }
+ }
+ else if(e.name) {
+ values.push(e.name + '=' + encodeURIComponent(e.value));
+ }
+ }
+ return values.join('&');
+};
+
+YAHOO.portico.fillForm = function(formID, params) {
+ var form = YAHOO.util.Dom.get(formID);
+ var values = [];
+ for(var i=0; i < form.elements.length; i++) {
+ var e = form.elements[i];
+ if((e.type=='checkbox' || e.type=='radio') && params[e.name]) {
+ e.checked = true;
+ }
+ else if(e.name && params[e.name] != undefined) {
+ e.value = params[e.name];
+ if(e._update) { // Is this connected to a date picker?
+ e._update();
+ }
+ }
+ }
+ return values.join('&');
+};
+
+YAHOO.portico.parseQS = function(qs) {
+ qs = qs.replace(/\+/g, ' ');
+ var args = qs.split('&');
+ var params = {};
+ for (var i = 0; i < args.length; i++) {
+ var pair = args[i].split('=');
+ var name = decodeURIComponent(pair[0]);
+ var value = (pair.length==2) ? decodeURIComponent(pair[1]) :
name;
+ params[name] = value;
+ }
+ return params;
+}
+
+YAHOO.portico.formatLink = function(elCell, oRecord, oColumn, oData) {
+ var name = oRecord.getData(oColumn.key);
+ var link = oRecord.getData('link');
+ elCell.innerHTML = '<a href="' + link + '">' + name + '</a>';
+};
+
+YAHOO.portico.formatGenericLink = function(elCell, oRecord, oColumn, oData)
+{
+ var data = oRecord.getData(oColumn.key);
+ //console.log(data['href']);
+ var link = data['href'];
+ var name = data['label'];
+
+ elCell.innerHTML = '<a href="' + link + '">' + name + '</a>';
+};
+
+/*
+YAHOO.portico.formatGenericLink = function() {
+ var links = [];
+ var nOfLinks = arguments.length;
+
+ for (var i=0; i < nOfLinks; i++) { links[i] = arguments[i]; }
+
+ return function(elCell, oRecord, oColumn, oData)
+ {
+ var nOfLinks = links.length;
+ var data = oRecord.getData(oColumn.key);
+
+ var linksHtml = '';
+ if (nOfLinks > 0) {
+ //Use specified link names
+ for (var i=0; i < nOfLinks; i++) {
+ if (data[i])
+ {
+ linksHtml += '<div><a href="' + data[i]
+ '">' + links[i] + '</a></div>';
+ }
+ }
+ } else {
+ //Get label from embedded data
+ if (data['href'] != undefined && data['label'] !=
undefined) {
+ linksHtml += '<div><a href="' + data['href'] +
'">' + data['label'] + '</a></div>';
+ } else if(data['href'] == undefined && data['label'] !=
undefined) {
+ linksHtml += '<div>'+data['label']+'</div>';
+ }
+ }
+
+ elCell.innerHTML = linksHtml;
+ };
+};
+*/
+YAHOO.portico.autocompleteHelper = function(url, field, hidden, container,
label_attr) {
+ label_attr = label_attr || 'name';
+ var myDataSource = new YAHOO.util.DataSource(url);
+ myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
+ myDataSource.connXhrMode = "queueRequests";
+ myDataSource.responseSchema = {
+ resultsList: "ResultSet.Result",
+ fields: [label_attr, 'id']
+ };
+ myDataSource.maxCacheEntries = 5;
+ var ac = new YAHOO.widget.AutoComplete(field, container, myDataSource);
+ ac.queryQuestionMark = false;
+ ac.resultTypeList = false;
+ ac.forceSelection = true;
+ ac.itemSelectEvent.subscribe(function(sType, aArgs) {
+ YAHOO.util.Dom.get(hidden).value = aArgs[2].id;
+ });
+ return ac;
+};
+
+YAHOO.portico.setupInlineTablePaginator = function(container) {
+ var paginatorConfig = {
+ rowsPerPage: 10,
+ alwaysVisible: false,
+ template: "{PreviousPageLink}
<strong>{CurrentPageReport}</strong> {NextPageLink}",
+ pageReportTemplate: "Showing items {startRecord} - {endRecord}
of {totalRecords}",
+ containers: [YAHOO.util.Dom.get(container)]
+ };
+
+ YAHOO.portico.lang('setupPaginator', paginatorConfig);
+ var pag = new YAHOO.widget.Paginator(paginatorConfig);
+ pag.render();
+ return pag;
+};
+
+YAHOO.portico.inlineTableHelper = function(container, url, colDefs, options,
disablePagination) {
+ var Dom = YAHOO.util.Dom;
+
+ var container = Dom.get(container);
+ if(!disablePagination) {
+ var paginatorContainer =
container.appendChild(document.createElement('div'));
+ var dataTableContainer =
container.appendChild(document.createElement('div'));
+ }
+ else {
+ dataTableContainer = container;
+ }
+ options = options || {};
+ options.dynamicData = true;
+
+ if(!disablePagination) {
+ options.paginator =
YAHOO.portico.setupInlineTablePaginator(paginatorContainer);
+ url += '&results=' + options.paginator.getRowsPerPage() + '&';
+ }
+ var myDataSource = new YAHOO.util.DataSource(url);
+ myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
+ myDataSource.connXhrMode = "queueRequests";
+ myDataSource.responseSchema = {
+ resultsList: "ResultSet.Result",
+ metaFields : { totalResultsAvailable:
"ResultSet.totalResultsAvailable", actions: 'Actions' }
+ };
+
+ var myDataTable = new YAHOO.widget.DataTable(dataTableContainer,
colDefs, myDataSource, options);
+
+ myDataTable.handleDataReturnPayload = function(oRequest, oResponse,
oPayload) {
+ oPayload.totalRecords = oResponse.meta.totalResultsAvailable;
+ return oPayload;
+ }
+
+ myDataTable.doBeforeLoadData = function(nothing, data) {
+ if (!data.meta.actions) return data;
+
+ actions = data.meta.actions;
+
+ for (var key in actions) {
+ var actionLink = document.createElement('a');
+ actionLink.href = actions[key].href.replace(/&/gi,
'&');
+ actionLink.innerHTML = actions[key].text;
+ YAHOO.util.Dom.insertAfter(actionLink, container);
+ };
+
+ return data;
+ };
+ return {dataTable: myDataTable, dataSource: myDataSource};
+};
+
+YAHOO.portico.inlineImages = function(container, url, options)
+{
+ options = options || {};
+ var myDataSource = new YAHOO.util.DataSource(url);
+ myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
+ myDataSource.connXhrMode = "queueRequests";
+ myDataSource.responseSchema = {
+ resultsList: "ResultSet.Result",
+ metaFields : { totalResultsAvailable:
"ResultSet.totalResultsAvailable", actions: 'Actions' }
+ };
+
+ myDataSource.sendRequest('', {success: function(sRequest, oResponse,
oPayload) {
+ var dlImages = new
YAHOO.util.Element(document.createElement('dl'));
+ dlImages.addClass('proplist images');
+
+ var displayContainer = false;
+
+ for(var key in oResponse.results) {
+ displayContainer = true;
+ var imgEl =
dlImages.appendChild(document.createElement('dd')).appendChild(document.createElement('img'));
+ var captionEl =
dlImages.appendChild(document.createElement('dt'));
+ imgEl.src =
oResponse.results[key].src.replace(/&/gi, '&');
+
captionEl.appendChild(document.createTextNode(oResponse.results[key].description));
+ }
+
+ if (displayContainer)
+ {
+ new YAHOO.util.Element(container).appendChild(dlImages);
+ } else {
+ new YAHOO.util.Element(container).setStyle('display',
'none');
+ }
+ }});
+};
+
+YAHOO.portico.radioTableHelper = function(container, url, name, selection) {
+ return YAHOO.portico.checkboxTableHelper(container, url, name,
selection, {type: 'radio'});
+};
+
+YAHOO.portico.checkboxTableHelper = function(container, url, name, selection,
options) {
+ options = YAHOO.lang.isObject(options) ? options : {};
+
+ options = YAHOO.lang.merge(
+ {type: 'checkbox', selectionFieldOptions: {}, nameFieldOptions:
{}, defaultChecked: false},
+ options
+ );
+
+ var type = options['type'] || 'checkbox';
+ selection = selection || [];
+ var myDataSource = new YAHOO.util.DataSource(url);
+ myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
+ myDataSource.connXhrMode = "queueRequests";
+ myDataSource.responseSchema = {
+ resultsList: "ResultSet.Result",
+ metaFields : { totalResultsAvailable:
"ResultSet.totalResultsAvailable" }
+ };
+
+ var lang = {LBL_NAME: 'Name'};
+ YAHOO.portico.lang('common', lang);
+
+ var changeListener = false;
+
+ if (options.onSelectionChanged) {
+ changeListener = function(e) {
+ var selectedItems = [];
+ var items =
YAHOO.util.Dom.getElementsBy(function(i){return i.checked;}, 'input',
container);
+
+ YAHOO.util.Dom.batch(items, function(e, selectedItems) {
+ selectedItems.push(e.value);
+ }, selectedItems);
+
+ options.onSelectionChanged(selectedItems);
+ };
+ }
+
+ var checkboxFormatter = function(elCell, oRecord, oColumn, oData) {
+ var checked = false;
+ var newInput;
+ for(var i=0; i < selection.length; i++) {
+ if (selection[i] == oData) {
+ checked = true;
+ break;
+ }
+ }
+
+ newInput = document.createElement('input');
+ newInput.setAttribute('type', type);
+ newInput.setAttribute('name', name);
+ newInput.setAttribute('value', oData);
+ if (checked || options.defaultChecked) {
+ newInput.setAttribute('checked', 'checked');
+ newInput.setAttribute('defaultChecked', true); //Needed
for IE compatibility
+ }
+
+ if (changeListener != false) {
+ //Using 'click' event on IE as the change event does
not work as expected there.
+ YAHOO.util.Event.addListener(newInput, (YAHOO.env.ua.ie
> 0 ? 'click' : 'change'), changeListener);
+ }
+
+ elCell.appendChild(newInput);
+
+ };
+ var colDefs = [
+ YAHOO.lang.merge({key: "id", formatter: checkboxFormatter,
label: ''}, options.selectionFieldOptions),
+ YAHOO.lang.merge({key: "name", label: lang['LBL_NAME'],
sortable: true}, options.nameFieldOptions)
+ ];
+
+ if (options['additional_fields'] &&
YAHOO.lang.isArray(options['additional_fields'])) {
+ for (var i=0; i < options['additional_fields'].length; i++) {
+ colDefs.push(options['additional_fields'][i]);
+ }
+ }
+
+ var myDataTable = new YAHOO.widget.DataTable(container, colDefs,
myDataSource, {
+ sortedBy: {key: 'name', dir: YAHOO.widget.DataTable.CLASS_ASC}
+ });
+};
+
+YAHOO.portico.setupDatePickers = function() {
+ YAHOO.util.Dom.getElementsByClassName('date-picker', null, null,
YAHOO.portico.setupDatePickerHelper, [true, false]);
+ YAHOO.util.Dom.getElementsByClassName('time-picker', null, null,
YAHOO.portico.setupDatePickerHelper, [false, true]);
+ YAHOO.util.Dom.getElementsByClassName('datetime-picker', null, null,
YAHOO.portico.setupDatePickerHelper, [true, true]);
+};
+
+YAHOO.portico.setupDatePickerHelper = function(field, args) {
+ if (!YAHOO.portico.setupDatePickerHelper.groups) {
+ YAHOO.portico.setupDatePickerHelper.groups = {};
+ }
+
+ var groups = YAHOO.portico.setupDatePickerHelper.groups;
+ var Dom = YAHOO.util.Dom;
+
+ if(field._converted)
+ return;
+ field._converted = true;
+ var date = args[0];
+ var time = args[1];
+ var Dom = YAHOO.util.Dom;
+ var Event = YAHOO.util.Event;
+ var oCalendarMenu = new YAHOO.widget.Overlay(Dom.generateId(), {
visible: false});
+ var oButton = new YAHOO.widget.Button({type: "menu", id:
Dom.generateId(), menu: oCalendarMenu, container: field});
+
+ oButton.with_time = time;
+ oButton.with_date = date;
+
+ var lang = {LBL_CHOOSE_DATE: 'Choose a date'};
+ YAHOO.portico.lang('setupDatePickerHelper', lang);
+
+ oButton._calendarMenu = oCalendarMenu;
+ oButton._input = field._input = Dom.getElementsBy(function(){return
true;}, 'input', field)[0];
+
+ oButton.hasDateSection = function() { return this.with_date; };
+ oButton.hasTimeSection = function() { return this.with_time; };
+
+ oButton.fireUpdateEvent = function() {
+ if (oButton.on_update) {
+ oButton.on_update.func.call(oButton.on_update.context,
oButton);
+ }
+ };
+
+ oButton.on("appendTo", function () {
+ this._calendarMenu.setBody(" ");
+ this._calendarMenu.body.id = Dom.generateId();
+ });
+ if(!date)
+ oButton.setStyle('display', 'none');
+ //oButton._input.setAttribute('type', 'hidden');
+ oButton._input.style.display = 'none';
+ if(oButton._input.value)
+ oButton._date = parseISO8601(oButton._input.value);
+ else
+ oButton._date = new Date(1, 1, 1);
+ oButton._input._update = function() {
+ if(oButton._input.value)
+ oButton._date = parseISO8601(oButton._input.value);
+ else
+ oButton._date = new Date(1, 1, 1);
+ oButton._update(false);
+ };
+ oButton._update = function(fire_update_event) {
+ var year = this._date.getFullYear();
+ var month = this._date.getMonth() + 1;
+ var day = this._date.getDate();
+ var hours = this._date.getHours();
+ var minutes = this._date.getMinutes();
+ var month = month < 10 ? '0' + month : '' + month;
+ var day = day < 10 ? '0' + day : '' + day;
+ var hours = hours < 10 ? '0' + hours : '' + hours;
+ var minutes = minutes < 10 ? '0' + minutes : '' + minutes;
+ var dateValue = year + '-' + month + '-' + day;
+ var timeValue = hours + ':' + minutes;
+ if(year == 1901) {
+ this.set('label', lang.LBL_CHOOSE_DATE);
+ } else {
+ this.set('label', dateValue);
+ }
+ if(time) {
+ this._hours.set('value', parseInt(hours, 10));
+ this._minutes.set('value', parseInt(minutes, 10));
+ this._hours.update();
+ this._minutes.update();
+ }
+ if(year != 1901 && date && time)
+ this._input.value = dateValue + ' ' + timeValue;
+ else if (year != 1901 && date)
+ this._input.value = dateValue;
+ else if(!date && time)
+ this._input.value = timeValue;
+
+ if (fire_update_event) {
+ oButton.fireUpdateEvent();
+ }
+ };
+
+ oButton.getDate = function() {
+ return this._date;
+ };
+
+ oButton.on("click", function () {
+ YAHOO.widget.DateMath.WEEK_ONE_JAN_DATE = 4;
+ var oCalendar = new YAHOO.widget.Calendar(Dom.generateId(),
this._calendarMenu.body.id, {START_WEEKDAY: 1,SHOW_WEEK_HEADER:true});
+ oCalendar._button = this;
+ if(this._date.getFullYear() == 1901) {
+ var d = new Date();
+ oCalendar.cfg.setProperty("pagedate", (d.getMonth()+1)
+ "/" + d.getFullYear());
+ } else {
+ oCalendar.select(this._date);
+ oCalendar.cfg.setProperty("pagedate",
(this._date.getMonth()+1) + "/" + this._date.getFullYear());
+ }
+
+ oCalendar.render();
+ // Hide date picker on ESC
+ Event.on(this._calendarMenu.element, "keydown", function
(p_oEvent) {
+ if (Event.getCharCode(p_oEvent) === 27) {
+ this._calendarMenu.hide();
+ this.focus();
+ }
+ }, null, this);
+ oCalendar.selectEvent.subscribe(function (p_sType, p_aArgs) {
+ if (p_aArgs) {
+ var aDate = p_aArgs[0][0];
+ this._date.setFullYear(aDate[0]);
+ this._date.setMonth(aDate[1]-1);
+ this._date.setDate(aDate[2]);
+ this._update(true);
+ //this._input.value = value;
+ }
+ this._calendarMenu.hide();
+ }, this, true);
+ });
+ if(time) {
+ oButton._hours = new YAHOO.portico.InputNumberRange({min: 0,
max:23});
+ oButton._minutes = new YAHOO.portico.InputNumberRange({min: 0,
max:59});
+
+ oButton._hours.on('updateEvent', function() {
+ oButton._date.setHours(this.get('value'));
+ oButton._update(true);
+ });
+
+ oButton._minutes.on('updateEvent', function() {
+ oButton._date.setMinutes(this.get('value'));
+ oButton._update(true);
+ });
+
+ oButton.on("appendTo", function () {
+ var timePicker =
Dom.get(field).appendChild(document.createElement('span'));
+ Dom.addClass(timePicker, 'time-picker-inputs');
+ timePicker.appendChild(document.createTextNode(' '));
+ oButton._hours.render(timePicker);
+ timePicker.appendChild(document.createTextNode(' : '));
+ oButton._minutes.render(timePicker);
+ oButton._update(false);
+ });
+ }
+ oButton._update(false);
+
+ var id = Dom.getAttribute(oButton._input, 'id');
+ var matches = /^([a-zA-Z][\w0-9\-_.:]+)_(from|to)$/.exec(id);
+
+ var group_name = matches ? matches[1] : false;
+ var from_to = matches ? matches[2] : false;
+
+ if (group_name && from_to && oButton.hasDateSection()) {
+ if (!groups[group_name]) { groups[group_name] = {}; }
+
+ groups[group_name][from_to] = oButton;
+
+ if (groups[group_name]['from'] && groups[group_name]['to']) {
+ groups[group_name]['from'].on_update = {
+ context: groups[group_name]['to'],
+ func: function(fromDateButton) {
+ var fromDate = fromDateButton.getDate();
+ var currentYear =
this._date.getFullYear();
+
+ if (this._date.getFullYear() == 1901) {
+
this._date.setFullYear(fromDate.getFullYear());
+
this._date.setMonth(fromDate.getMonth());
+
this._date.setDate(fromDate.getDate());
+ } else if (fromDate.getFullYear() <=
this._date.getFullYear() && fromDate.getMonth() <= this._date.getMonth() &&
fromDate.getDate() <= this._date.getDate()) {
+ //this._date.
+ }
+
+ this._update(false);
+ }
+ };
+
+ delete groups[group_name];
+ }
+ }
+};
+
+// Executed on all booking.uicommon-based pages
+YAHOO.util.Event.addListener(window, "load", function() {
+ YAHOO.portico.setupDatePickers();
+});
+var showIfNotEmpty = function(event, fieldname) {
+ if (document.getElementById(fieldname).value.length > 1) {
+ YAHOO.util.Dom.replaceClass(fieldname + "_edit", "hideit",
"showit");
+ } else {
+ YAHOO.util.Dom.replaceClass(fieldname + "_edit", "showit",
"hideit");
+ }
+};
+
+YAHOO.portico.rtfEditorHelper = function(textarea_id, options) {
+ options = YAHOO.lang.merge({width:522, height:300}, (options || {}));
+ var descEdit = new YAHOO.widget.SimpleEditor(textarea_id, {
+ height: options.height+'px',
+ width: options.width+'px',
+ dompath: true,
+ animate: true,
+ handleSubmit: true
+ });
+ descEdit.render();
+ return descEdit;
+};
+
+YAHOO.portico.postToUrl = function(path, params, method) {
+ method = method || "post"; // Set method to post by default, if not
specified.
+ var form = document.createElement("form");
+ form.setAttribute("method", method);
+ form.setAttribute("action", path);
+
+ for(var key in params) {
+ var hiddenField = document.createElement("input");
+ hiddenField.setAttribute("type", "hidden");
+ hiddenField.setAttribute("name", params[key][0]);
+ hiddenField.setAttribute("value", params[key][1]);
+ form.appendChild(hiddenField);
+ }
+ document.body.appendChild(form); // Not entirely sure if this is
necessary
+ form.submit();
+};
+
+(function(){
+ var Dom = YAHOO.util.Dom,
+ Event = YAHOO.util.Event,
+ Panel = YAHOO.widget.Panel,
+ Lang = YAHOO.lang;
+
+ var CSS_PREFIX = 'booking_number_range_';
+
+ var InputNumberRange = function(oConfigs) {
+ InputNumberRange.superclass.constructor.call(this,
document.createElement('span'), oConfigs);
+ this.createEvent('updateEvent');
+ this.refresh(['id'],true);
+ };
+
+ YAHOO.portico.InputNumberRange = InputNumberRange;
+
+ Lang.extend(InputNumberRange, YAHOO.util.Element, {
+ initAttributes: function (oConfigs) {
+ InputNumberRange.superclass.initAttributes.call(this,
oConfigs);
+
+ var container = this.get('element');
+
+ this.setAttributeConfig('inputEl', {
+ readOnly: true,
+ value:
container.appendChild(document.createElement('span'))
+ });
+
+ this.setAttributeConfig('id', {
+ writeOnce: true,
+ validator: function (value) {
+ return
/^[a-zA-Z][\w0-9\-_.:]*$/.test(value);
+ },
+ value: Dom.generateId(),
+ method: function (value) {
+ this.get('inputEl').id = value;
+ }
+ });
+
+ this.setAttributeConfig('value', {
+ value: 0,
+ validator: Lang.isNumber
+ });
+
+ this.setAttributeConfig('input', {
+ value: null
+ });
+
+ this.setAttributeConfig('min', {
+ validator: Lang.isNumber,
+ value: 100
+ });
+
+ this.setAttributeConfig('max', {
+ validator: Lang.isNumber,
+ value: 0
+ });
+
+ this.setAttributeConfig('input_length', {
+ validator: Lang.isNumber,
+ value: null
+ });
+ },
+
+ destroy: function () {
+ var el = this.get('element');
+ Event.purgeElement(el, true);
+ el.parentNode.removeChild(el);
+ },
+
+ _padValue: function(value)
+ {
+ value = value.toString('10');
+ var padding = this.get('input_length') - value.length;
+ if (padding > 0) {
+ return ((new Array(padding+1).join('0')) +
value);
+ }
+ return value;
+ },
+
+ _updateValue: function() {
+ var input = this.get('input');
+ var value;
+
+ if (input.value.length > 0) {
+ value = parseInt(input.value, 10);
+ } else {
+ value = 0;
+ }
+
+ if (isNaN(value)) {
+ value = this.get('min');
+ }
+
+ if (value < this.get('min')) {
+ value = this.get('min');
+ }
+
+ if (value > this.get('max')) {
+ value = this.get('max');
+ }
+
+ this.set('value', value);
+ },
+
+ _fireUpdateEvent: function()
+ {
+ this._updateValue();
+ this.update();
+
+ this.fireEvent('updateEvent');
+ },
+
+ update: function() {
+ if (!this.get('input')) { return; }
+ this.get('input').value =
this._padValue(this.get('value'));
+ },
+
+ render: function (parentEl) {
+ parentEl = Dom.get(parentEl);
+
+ if (!parentEl) {
+ YAHOO.log('Missing mandatory argument in
YAHOO.portico.InputNumberRange.render: parentEl','error','Field');
+ return null;
+ }
+
+ var containerEl = this.get('element');
+ this.addClass(CSS_PREFIX + 'container');
+
+ var inputEl = this.get('inputEl');
+ Dom.addClass(inputEl, CSS_PREFIX + 'input');
+
+ this._renderInputEl(inputEl);
+
+ parentEl.appendChild(containerEl); //Appends to
document to show the component
+ },
+
+ _renderInputEl: function (containerEl) {
+ var input =
containerEl.appendChild(document.createElement('input'));
+
+ if (!this.get('input_length')) {
+ this.set('input_length',
this.get('max').toString().length);
+ }
+
+ var size = this.get('input_length');
+ input.setAttribute('size', size);
+ input.setAttribute('maxlength', size);
+
+ if (YAHOO.env.ua.ie > 6) {
+ YAHOO.util.Dom.setStyle(input, 'width', '2em');
+ }
+
+ input.value = this._padValue(this.get('value'));
+
+ this.set('input', input);
+
+ Event.on(input,'keyup', function (oArgs) {
+ this._updateValue();
+ }, this, true);
+
+ Event.on(input, 'change', function(oArgs) {
+ this._fireUpdateEvent();
+ }, this, true);
+
+ oForm = input.form;
+
+ if (oForm) {
+ Event.on(oForm, "submit", function() {
+ this._fireUpdateEvent();
+ }, null, this);
+ }
+
+ }
+ });
+
+})();
Added: trunk/phpgwapi/js/yahoo/datatable.js
===================================================================
--- trunk/phpgwapi/js/yahoo/datatable.js (rev 0)
+++ trunk/phpgwapi/js/yahoo/datatable.js 2012-06-19 14:06:11 UTC (rev
9631)
@@ -0,0 +1,178 @@
+YAHOO.portico.setupToolbar = function() {
+ YAHOO.portico.renderUiFormItems('toolbar');
+};
+
+YAHOO.portico.setupListActions = function() {
+ YAHOO.portico.renderUiFormItems('list_actions');
+};
+
+YAHOO.portico.renderUiFormItems = function(container) {
+ var items = YAHOO.util.Dom.getElementsBy(function(){return true;},
'input', container);
+ for(var i=0; i < items.length; i++) {
+ var type = items[i].getAttribute('type');
+ if(type == 'link') {
+ new YAHOO.widget.Button(items[i],
+ {type: 'link',
+ href: items[i].getAttribute('href')});
+ }
+ else if(type == 'submit') {
+ new YAHOO.widget.Button(items[i], {type: 'submit'});
+ }
+ }
+};
+
+YAHOO.portico.setupPaginator = function() {
+ var paginatorConfig = {
+ rowsPerPage: 10,
+ alwaysVisible: false,
+ template: "{PreviousPageLink} <strong>{CurrentPageReport}</strong>
{NextPageLink}",
+ pageReportTemplate: "Showing items {startRecord} - {endRecord} of
{totalRecords}",
+ containers: ['paginator']
+ };
+
+ YAHOO.portico.lang('setupPaginator', paginatorConfig);
+ var pag = new YAHOO.widget.Paginator(paginatorConfig);
+ pag.render();
+ return pag;
+};
+
+YAHOO.portico.preSerializeQueryFormListeners = new Array();
+
+ YAHOO.portico.addPreSerializeQueryFormListener = function(func) {
+ YAHOO.portico.preSerializeQueryFormListeners.push(func);
+}
+
+YAHOO.portico.preSerializeQueryForm = function(form) {
+ for (var key in YAHOO.portico.preSerializeQueryFormListeners) {
+ YAHOO.portico.preSerializeQueryFormListeners[key](form);
+ }
+}
+
+YAHOO.portico.initializeDataTable = function()
+{
+ YAHOO.portico.setupToolbar();
+ YAHOO.portico.setupListActions();
+ YAHOO.portico.setupDatasource();
+ var pag = YAHOO.portico.setupPaginator();
+
+ var fields = [];
+ for(var i=0; i < YAHOO.portico.columnDefs.length; i++) {
+ fields.push(YAHOO.portico.columnDefs[i].key);
+ }
+ var baseUrl = YAHOO.portico.dataSourceUrl;
+ if(baseUrl[baseUrl.length - 1] != '&') {
+ baseUrl += '&';
+ }
+
+ if (YAHOO.portico.initialSortedBy) {
+ baseUrl += 'sort=' + YAHOO.portico.initialSortedBy.key + '&dir=' +
YAHOO.portico.initialSortedBy.dir;
+ } else {
+ baseUrl += 'sort=' + fields[0];
+ }
+
+ baseUrl += '&results=' + pag.getRowsPerPage() + '&';
+ var myDataSource = new YAHOO.util.DataSource(baseUrl);
+
+ myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
+ myDataSource.connXhrMode = "queueRequests";
+ myDataSource.responseSchema = {
+ resultsList: "ResultSet.Result",
+ fields: fields,
+ metaFields : {
+ totalResultsAvailable: "ResultSet.totalResultsAvailable",
+ startIndex: 'ResultSet.startIndex',
+ sortKey: 'ResultSet.sortKey',
+ sortDir: 'ResultSet.sortDir'
+ }
+ };
+ var myDataTable = new YAHOO.widget.DataTable("datatable-container",
+ YAHOO.portico.columnDefs, myDataSource, {
+ paginator: pag,
+ dynamicData: true,
+ sortedBy: YAHOO.portico.initialSortedBy || {key: fields[0], dir:
YAHOO.widget.DataTable.CLASS_ASC}
+ });
+ var handleSorting = function (oColumn) {
+ var sDir = this.getColumnSortDir(oColumn);
+ var newState = getState(oColumn.key, sDir);
+ History.navigate("state", newState);
+ };
+ myDataTable.sortColumn = handleSorting;
+
+ var handlePagination = function(state) {
+ var sortedBy = this.get("sortedBy");
+ var newState = getState(sortedBy.key, sortedBy.dir,
state.recordOffset);
+ History.navigate("state", newState);
+ };
+ pag.unsubscribe("changeRequest", myDataTable.onPaginatorChangeRequest);
+ pag.subscribe("changeRequest", handlePagination, myDataTable, true);
+ myDataTable.doBeforeLoadData = function(oRequest, oResponse, oPayload) {
+ oPayload.totalRecords = oResponse.meta.totalResultsAvailable;
+ oPayload.pagination = {
+ rowsPerPage: oResponse.meta.paginationRowsPerPage ||
10,
+ recordOffset: oResponse.meta.startIndex || 0
+ }
+ oPayload.sortedBy = {
+ key: oResponse.meta.sortKey || "id",
+ dir: (oResponse.meta.sortDir) ? "yui-dt-" +
oResponse.meta.sortDir : "yui-dt-asc"
+ };
+ return true;
+ }
+
+ YAHOO.util.Event.on(
+ YAHOO.util.Selector.query('select'), 'change', function (e) {
+ //var val = this.value;
+ var state = getState();
+ YAHOO.util.Dom.setStyle('list_flash', 'display',
'none');
+ History.navigate('state', state);
+ });
+
+ YAHOO.util.Event.addListener('queryForm', "submit", function(e){
+ YAHOO.util.Event.stopEvent(e);
+ var state = getState();
+ YAHOO.util.Dom.setStyle('list_flash', 'display', 'none');
+ History.navigate('state', state);
+ });
+
+ YAHOO.util.Event.addListener('list_actions_form', "submit", function(e){
+ YAHOO.util.Event.stopEvent(e);
+ window.setTimeout(function() {
+ var state = getState();
+ var action = myDataSource.liveData + '&' + state;
+ action = action.replace('&phpgw_return_as=json', '');
+
YAHOO.util.Dom.setAttribute(document.getElementById('list_actions_form'),
'action', action);
+ document.getElementById('list_actions_form').submit();
+ }, 0);
+ });
+
+ var History = YAHOO.util.History;
+ var getState = function(skey, sdir, start) {
+ var state = YAHOO.portico.serializeForm('queryForm');
+ var sortedBy = myDataTable.get("sortedBy");
+ skey = skey ? skey : sortedBy.key;
+ sdir = sdir ? sdir : sortedBy.dir;
+ sdir = sdir == 'yui-dt-asc' ? 'asc' : 'desc';
+ start = start ? start : 0;
+ state += '&sort=' + skey;
+ state += '&dir=' + sdir;
+ state += '&startIndex=' + start;
+ return state;
+ }
+
+ var handleHistoryNavigation = function (state) {
+ var params = YAHOO.portico.parseQS(state);
+ YAHOO.portico.fillForm('queryForm', params);
+ myDataSource.sendRequest(state, {success: function(sRequest,
oResponse, oPayload) {
+ myDataTable.onDataReturnInitializeTable(sRequest,
oResponse, pag);
+ }});
+ };
+
+ var initialRequest = History.getBookmarkedState("state") || getState();
+ History.register("state", initialRequest, handleHistoryNavigation);
+ History.onReady(function() {
+ var state = YAHOO.util.History.getCurrentState('state');
+ handleHistoryNavigation(state);
+ });
+ History.initialize("yui-history-field", "yui-history-iframe");
+};
+
+YAHOO.util.Event.addListener(window, "load",
YAHOO.portico.initializeDataTable);
Added: trunk/phpgwapi/templates/base/datatable_common.xsl
===================================================================
--- trunk/phpgwapi/templates/base/datatable_common.xsl
(rev 0)
+++ trunk/phpgwapi/templates/base/datatable_common.xsl 2012-06-19 14:06:11 UTC
(rev 9631)
@@ -0,0 +1,244 @@
+<func:function name="phpgw:conditional">
+ <xsl:param name="test"/>
+ <xsl:param name="true"/>
+ <xsl:param name="false"/>
+
+ <func:result>
+ <xsl:choose>
+ <xsl:when test="$test">
+ <xsl:value-of select="$true"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$false"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </func:result>
+</func:function>
+
+<xsl:template match="data">
+ <iframe id="yui-history-iframe"
src="phpgwapi/js/yahoo/history/assets/blank.html"
style="position:absolute;top:0; left:0;width:1px;
height:1px;visibility:hidden;"></iframe>
+ <input id="yui-history-field" type="hidden"/>
+ <xsl:call-template name="yui_phpgw_i18n"/>
+ <xsl:apply-templates select="form" />
+ <xsl:apply-templates select="paging"/>
+ <div id="list_flash">
+ <xsl:call-template name="msgbox"/>
+ </div>
+ <xsl:apply-templates select="datatable"/>
+ <xsl:apply-templates select="form/list_actions"/>
+</xsl:template>
+
+<xsl:template match="toolbar">
+ <div id="toolbar">
+ <table class='yui-skin-sam' border="0" cellspacing="0"
cellpadding="0" style="padding:0px; margin:0px;">
+ <tr>
+ <xsl:for-each select="item">
+ <xsl:variable name="filter_key"
select="concat('filter_', name)"/>
+ <xsl:variable name="filter_key_name"
select="concat(concat('filter_', name), '_name')"/>
+ <xsl:variable name="filter_key_id"
select="concat(concat('filter_', name), '_id')"/>
+
+ <xsl:choose>
+ <xsl:when test="type = 'date-picker'">
+ <td valign="top">
+ <div class="date-picker">
+ <input id="filter_{name}" name="filter_{name}"
type="text">
+ <xsl:attribute
name="value"><xsl:value-of select="../../../filters/*[local-name() =
$filter_key]"/></xsl:attribute>
+ </input>
+ </div>
+ </td>
+ </xsl:when>
+ <xsl:when test="type = 'autocomplete'">
+ <td valign="top" width="160px">
+ <div style="width:140px">
+ <input
id="filter_{name}_name" name="filter_{name}_name" type="text">
+ <xsl:attribute
name="value"><xsl:value-of select="../../../filters/*[local-name() =
$filter_key_name]"/></xsl:attribute>
+ </input>
+ <input
id="filter_{name}_id" name="filter_{name}_id" type="hidden">
+ <xsl:attribute
name="value"><xsl:value-of select="../../../filters/*[local-name() =
$filter_key_id]"/></xsl:attribute>
+ </input>
+ <div
id="filter_{name}_container"/>
+ </div>
+ <script type="text/javascript">
+
YAHOO.util.Event.onDOMReady(function() {
+ var app = "<xsl:value-of
select="app"/>";
+ var name = "<xsl:value-of
select="name"/>";
+ var ui = "<xsl:value-of
select="ui"/>";
+
+ var itemSelectCallback
= false;
+ <xsl:if
test="onItemSelect">
+
itemSelectCallback = <xsl:value-of select="onItemSelect"/>;
+ </xsl:if>
+
+ var
onClearSelectionCallback = false;
+ <xsl:if
test="onClearSelection">
+
onClearSelectionCallback = <xsl:value-of select="onClearSelection"/>;
+ </xsl:if>
+
+ var requestGenerator =
false;
+ <xsl:if
test="requestGenerator">
+
requestGenerator = <xsl:value-of select="requestGenerator"/>;
+ </xsl:if>
+
+ <![CDATA[
+ var oArgs =
{menuaction: app + '.ui'+ui+'.index'};
+ var requestUrl =
phpGWLink('index.php', oArgs, true);
+ requestUrl +=
'filter_'+name+'_name', 'filter_'+name+'_id', 'filter_'+name+'_container';
+ alert('FIXME:
autocompleteHelper::requestUrl ' + requestUrl );
+
+ var oAC =
YAHOO.portico.autocompleteHelper(requestUrl);
+
+ if (requestGenerator) {
+
oAC.generateRequest = requestGenerator;
+ }
+
+ if (itemSelectCallback)
{
+
oAC.itemSelectEvent.subscribe(itemSelectCallback);
+ }
+
+
YAHOO.util.Event.addBlurListener('filter_'+name+'_name', function() {
+ if
(YAHOO.util.Dom.get('filter_'+name+'_name').value == "") {
+
YAHOO.util.Dom.get('filter_'+name+'_id').value = "";
+ if
(onClearSelectionCallback) {
+
onClearSelectionCallback();
+ }
+ }
+ });
+
+
YAHOO.portico.addPreSerializeQueryFormListener(function(form) {
+ if
(YAHOO.util.Dom.get('filter_'+name+'_name').value == "") {
+
YAHOO.util.Dom.get('filter_'+name+'_id').value = "";
+ }
+ });
+ ]]>
+ });
+ </script>
+ </td>
+ </xsl:when>
+ <xsl:when test="type = 'filter'">
+ <td valign="top">
+ <xsl:variable name="name"><xsl:value-of
select="name"/></xsl:variable>
+ <select name="{$name}"
onMouseout="window.status='';return true;">
+ <xsl:for-each select="list">
+ <xsl:variable name="id"><xsl:value-of
select="id"/></xsl:variable>
+ <xsl:if test="id = ''">
+ <option value="{$id}"
selected="selected">
+
<xsl:value-of select="name"/>
+ </option>
+ </xsl:if>
+ <xsl:if test="id != ''">
+ <option value="{$id}">
+
<xsl:value-of select="name"/>
+ </option>
+ </xsl:if>
+ </xsl:for-each>
+ </select>
+ </td>
+ </xsl:when>
+ <xsl:otherwise>
+ <td valign="top">
+ <input id="innertoolbar">
+ <xsl:attribute
name="type"><xsl:value-of select="phpgw:conditional(not(type), '',
type)"/></xsl:attribute>
+ <xsl:attribute
name="name"><xsl:value-of select="phpgw:conditional(not(name), '',
name)"/></xsl:attribute>
+ <xsl:attribute
name="onclick"><xsl:value-of select="phpgw:conditional(not(onClick), '',
onClick)"/></xsl:attribute>
+ <xsl:attribute
name="value"><xsl:value-of select="phpgw:conditional(not(value), '',
value)"/></xsl:attribute>
+ <xsl:attribute
name="href"><xsl:value-of select="phpgw:conditional(not(href), '',
href)"/></xsl:attribute>
+ </input>
+ </td>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </tr>
+ <xsl:if test="item/text and normalize-space(item/text)">
+ <thead style="background:none">
+ <tr>
+ <xsl:for-each select="item">
+ <td>
+ <xsl:if
test="name">
+ <label
style='margin:auto 0.25em'>
+
<xsl:attribute name="for"><xsl:value-of select="phpgw:conditional(not(name),
'', name)"/></xsl:attribute>
+
<xsl:value-of select="phpgw:conditional(not(text), '', text)"/>
+ </label>
+ </xsl:if>
+ </td>
+ </xsl:for-each>
+ </tr>
+ </thead>
+ </xsl:if>
+ </table>
+ </div>
+</xsl:template>
+
+<xsl:template match="form/list_actions">
+ <form id="list_actions_form" method="POST">
+ <!-- Form action is set by javascript listener -->
+ <div id="list_actions" class='yui-skin-sam'>
+ <table cellpadding="0" cellspacing="0">
+ <tr>
+ <xsl:for-each select="item">
+ <td valign="top">
+ <input
id="innertoolbar">
+ <xsl:attribute
name="type"><xsl:value-of select="phpgw:conditional(not(type), '',
type)"/></xsl:attribute>
+ <xsl:attribute
name="name"><xsl:value-of select="phpgw:conditional(not(name), '',
name)"/></xsl:attribute>
+ <xsl:attribute
name="onclick"><xsl:value-of select="phpgw:conditional(not(onClick), '',
onClick)"/></xsl:attribute>
+ <xsl:attribute
name="value"><xsl:value-of select="phpgw:conditional(not(value), '',
value)"/></xsl:attribute>
+ <xsl:attribute
name="href"><xsl:value-of select="phpgw:conditional(not(href), '',
href)"/></xsl:attribute>
+ </input>
+ </td>
+ </xsl:for-each>
+ </tr>
+ </table>
+ </div>
+ </form>
+</xsl:template>
+<xsl:template match="form">
+ <form id="queryForm">
+ <xsl:attribute name="method">
+ <xsl:value-of select="phpgw:conditional(not(method),
'GET', method)"/>
+ </xsl:attribute>
+
+ <xsl:attribute name="action">
+ <xsl:value-of select="phpgw:conditional(not(action),
'', action)"/>
+ </xsl:attribute>
+ <xsl:apply-templates select="toolbar"/>
+ </form>
+</xsl:template>
+
+<xsl:template match="datatable">
+ <div id="paginator"/>
+ <div id="datatable-container"/>
+ <xsl:call-template name="datasource-definition" />
+</xsl:template>
+
+<xsl:template name="datasource-definition">
+ <script>
+ YAHOO.portico.setupDatasource = function() {
+ <xsl:if test="source">
+ YAHOO.portico.dataSourceUrl = '<xsl:value-of
select="source"/>';
+ YAHOO.portico.initialSortedBy = false;
+ YAHOO.portico.initialFilters = false;
+ <xsl:if test="sorted_by">
+ YAHOO.portico.initialSortedBy =
{key: '<xsl:value-of select="sorted_by/key"/>', dir: '<xsl:value-of
select="sorted_by/dir"/>'};
+ </xsl:if>
+ </xsl:if>
+
+ YAHOO.portico.columnDefs = [
+ <xsl:for-each select="//datatable/field">
+ {
+ key: "<xsl:value-of
select="key"/>",
+ <xsl:if test="label">
+ label: "<xsl:value-of
select="label"/>",
+ </xsl:if>
+ sortable: <xsl:value-of
select="phpgw:conditional(not(sortable = 0), 'true', 'false')"/>,
+ <xsl:if test="hidden">
+ hidden: true,
+ </xsl:if>
+ <xsl:if test="formatter">
+ formatter: <xsl:value-of
select="formatter"/>,
+ </xsl:if>
+ className: "<xsl:value-of
select="className"/>"
+ }<xsl:value-of
select="phpgw:conditional(not(position() = last()), ',', '')"/>
+ </xsl:for-each>
+ ];
+ }
+ </script>
+</xsl:template>
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Fmsystem-commits] [9631] phpgwapi : uicommon,
Sigurd Nes <=