From ef3e6bc4f4726e96890755f94076cbafcde8565f Mon Sep 17 00:00:00 2001
From: Ralf Becker
Date: Thu, 2 Jun 2005 22:43:44 +0000
Subject: [PATCH] New widget for durations: floating point input with an
optional selectbox to specify a unit (hours or days). The storage format is
configurabe and can be either minutes (integer) or hours or days as float
---
etemplate/doc/reference.html | 19 +++-
etemplate/inc/class.date_widget.inc.php | 138 +++++++++++++++++++++++-
etemplate/setup/phpgw_de.lang | 3 +
etemplate/setup/phpgw_en.lang | 3 +
4 files changed, 155 insertions(+), 8 deletions(-)
diff --git a/etemplate/doc/reference.html b/etemplate/doc/reference.html
index ac07a85bd7..93a77a2617 100644
--- a/etemplate/doc/reference.html
+++ b/etemplate/doc/reference.html
@@ -204,7 +204,7 @@ implement only a subset of XUL. Here are the main differences:
(or as tooltip for buttons or general in gtk).
If the user has JavaScript switched off, the help-texts get NOT submitted, as this is detected.
If the helptext starts with a '@' it is replaced by the value of the content-array at this
- index (with the '@'-removed).
+ index (with the '@'-removed and after expanding the variables).
@@ -216,7 +216,7 @@ implement only a subset of XUL. Here are the main differences:
This attribute controls certain aspects of the different widgets. It's meaning and xml / xul-values
are document with the widgets.
If the options-string starts with a '@' it is replaced by the value of the content-array at this
- index (with the '@'-removed).
+ index (with the '@'-removed and after expanding the variables).
@@ -288,6 +288,8 @@ implement only a subset of XUL. Here are the main differences:
of 'all' can be used to indicate it should span all remaining cells of a row.
This is not supported by xul-grid's at the moment, but is planned to be.
class: the CSS class for the widget.
+ If the class-string starts with a '@' it is replaced by the value of the content-array at this
+ index (with the '@'-removed and after expanding the variables).
@@ -615,8 +617,9 @@ implement only a subset of XUL. Here are the main differences:
<date options="Y-m-d,1"/>
<date type="date-time"/>
- <date type="date-timeonly" options="H:i"/>
- <date type="date-houronly"/>
+ <date type="date-timeonly" options="H:i"/>
+ <date type="date-houronly"/>
+ <date type="date-duration"/>
|
no |
date |
@@ -639,7 +642,13 @@ implement only a subset of XUL. Here are the main differences:
Sub-widgets: date-time: a date and a time and date-timeonly or date-houronly: only a time / hour
These widgets allow the input of times too or only, they use 12h am/pm or 24h format as
specified in the user prefs.
- If readonly is set, this widget can be used to display a date, without the need to convert it.
+ If readonly is set, this widget can be used to display a date, without the need to convert it.
+ Duration a floating point input with an optional selectbox for the unit (hours or days)
+ Options: [duration-storage-format] [,[duration-display][,hours_per_day]]
+ duration-storage-format: 'h' = hours (float), 'd' = days (float), default minutes (integer)
+ duration-display: 'd' = days, 'h' = hours, 'dh' = days or hours with selectbox, optional '%' allows to enter a percentage
+ hours_per_day: conversation between hours and (working) day, default 8
+ hours_per_day: conversation between hours and (working) day, default 8
diff --git a/etemplate/inc/class.date_widget.inc.php b/etemplate/inc/class.date_widget.inc.php
index 5232cb2129..3d1886fae8 100644
--- a/etemplate/inc/class.date_widget.inc.php
+++ b/etemplate/inc/class.date_widget.inc.php
@@ -51,6 +51,7 @@
'date-time' => 'Date+Time', // date + time
'date-timeonly' => 'Time', // time
'date-houronly' => 'Hour', // hour
+ 'date-duration' => 'Duration', // duration
);
var $dateformat; // eg. Y-m-d, d-M-Y
var $timeformat; // 12 or 24
@@ -90,13 +91,16 @@
function pre_process($name,&$value,&$cell,&$readonlys,&$extension_data,&$tmpl)
{
$type = $cell['type'];
- list($data_format,$options) = explode(',',$cell['size']);
+ if ($type == 'date-duration')
+ {
+ return $this->pre_process_duration($name,$value,$cell,$readonlys,$extension_data,$tmpl);
+ }
+ list($data_format,$options,$options2) = explode(',',$cell['size']);
if ($type == 'date-houronly' && empty($data_format)) $data_format = 'H';
$extension_data = array(
- 'data_format' => $data_format,
'type' => $type,
+ 'data_format' => $data_format,
);
-
if (!$value)
{
$value = array(
@@ -304,6 +308,100 @@
return True; // extra Label is ok
}
+ /**
+ * pre-processing of the duration extension
+ *
+ * Options contain $data_format,$input_format,$hours_per_day
+ * - data_format: d = days, h = hours, default minutes
+ * - input_format: d = days, h = hours, default hours+days (selectbox), optional % = allow to enter a percent value (no conversation)
+ * - hours_per_day: default 8 (workday)
+ *
+ * @param string $name form-name of the control
+ * @param mixed &$value value / existing content, can be modified
+ * @param array &$cell array with the widget, can be modified for ui-independent widgets
+ * @param array &$readonlys names of widgets as key, to be made readonly
+ * @param mixed &$extension_data data the extension can store persisten between pre- and post-process
+ * @param object &$tmpl reference to the template we belong too
+ * @return boolean true if extra label is allowed, false otherwise
+ */
+ function pre_process_duration($name,&$value,&$cell,&$readonlys,&$extension_data,&$tmpl)
+ {
+ $readonly = $readonlys || $cell['readonly'];
+ list($data_format,$input_format,$hours_per_day) = explode(',',$cell['size']);
+ if (!$hours_per_day) $hours_per_day = 8; // workday is 8 hours
+ if (($percent_allowed = strstr($input_format,'%') !== false))
+ {
+ $input_format = str_replace('%','',$input_format);
+ }
+ if ($input_format != 'h' && $input_format != 'd') $input_format = 'dh'; // hours + days
+
+ $extension_data = array(
+ 'type' => $cell['type'],
+ 'data_format' => $data_format,
+ 'unit' => ($unit = $input_format == 'd' ? 'd' : 'h'),
+ 'input_format' => $input_format,
+ 'hours_per_day' => $hours_per_day,
+ 'percent_allowed'=> $percent_allowed,
+ );
+ switch($data_format)
+ {
+ case 'd':
+ $value *= $hours_per_day;
+ // fall-through
+ case 'h': case 'H':
+ $value *= 60;
+ break;
+ }
+ $cell['type'] = 'text';
+ $cell['size'] = '4,,/^-?[0-9]*[,.]?[0-9]*'.($percent_allowed ? '%?' : '').'$/';
+ $cell_name = $cell['name'];
+ $cell['name'] .= '[value]';
+
+ if ($input_format == 'dh' && $value >= 60*$hours_per_day)
+ {
+ $unit = 'd';
+ }
+ $value = !$value ? '' : round($value / 60 / ($unit == 'd' ? $hours_per_day : 1),3);
+
+ if (!$readonly && $input_format == 'dh') // selectbox to switch between hours and days
+ {
+ $value = array(
+ 'value' => $value,
+ 'unit' => $unit,
+ );
+ $tpl =& new etemplate;
+ $tpl->init('*** generated fields for duration','','',0,'',0,0); // make an empty template
+ // keep the editor away from the generated tmpls
+ $tpl->no_onclick = true;
+
+ $selbox =& $tpl->empty_cell('select',$cell_name.'[unit]');
+ $selbox['sel_options'] = array(
+ 'h' => 'hours',
+ 'd' => 'days',
+ );
+
+ $tpl->data[0] = array();
+ $tpl->data[1] =array(
+ 'A' => $cell,
+ 'B' => $selbox,
+ );
+ $tpl->set_rows_cols();
+ $tpl->size = ',,,,0';
+
+ unset($cell['size']);
+ $cell['type'] = 'template';
+ $cell['name'] = $tpl->name;
+ unset($cell['label']);
+ $cell['obj'] = &$tpl;
+ }
+ elseif (!$readonly || $value)
+ {
+ $cell['no_lang'] = 2;
+ $cell['label'] .= ($cell['label'] ? ' ' : '') . '%s '.($input_format == 'h' ? lang('hours') : lang('days'));
+ }
+ return True; // extra Label is ok
+ }
+
/**
* postprocessing method, called after the submission of the form
*
@@ -328,6 +426,40 @@
{
return False;
}
+ if ($extension_data['type'] == 'date-duration')
+ {
+ if (is_array($value)) // template with selectbox
+ {
+ $unit = $value['unit'];
+ $value = $value['value'];
+ }
+ elseif (!preg_match('/^-?[0-9]*[,.]?[0-9]*'.($extension_data['percent_allowed'] ? '%?' : '').'$/',$value_in))
+ {
+ $GLOBALS['phpgw_info']['etemplate']['validation_errors'][$name] = lang("'%1' is not a valid floatingpoint number !!!",$value_in);
+ return false;
+ }
+ else
+ {
+ $value = $value_in;
+ $unit = $extension_data['unit'];
+ }
+ if ($extension_data['percent_allowed'] && substr($value,-1) == '%')
+ {
+ return $value;
+ }
+ $value = (int) round(str_replace(',','.',$value) * 60 * ($unit == 'd' ? $extension_data['hours_per_day'] : 1));
+
+ switch($extension_data['data_format'])
+ {
+ case 'd':
+ $value /= (float) $extension_data['hours_per_day'];
+ // fall-through
+ case 'h': case 'H':
+ $value /= 60.0;
+ break;
+ }
+ return true;
+ }
$no_date = substr($extension_data['type'],-4) == 'only';
if ($value['today'])
diff --git a/etemplate/setup/phpgw_de.lang b/etemplate/setup/phpgw_de.lang
index cd8e13ec77..29e94a4990 100644
--- a/etemplate/setup/phpgw_de.lang
+++ b/etemplate/setup/phpgw_de.lang
@@ -79,6 +79,7 @@ cut etemplate de Ausschneiden
date+time etemplate de Datum+Uhrzeit
datum etemplate de Datum
day etemplate de Tag
+days etemplate de Tage
db ensures that every row has a unique value in that column etemplate de die Datenbank stelt sicher das alle Zeilen einen einmaligen Wert in dieser Spalte haben
db-specific index options (comma-sep.), eg. mysql(fulltext) or mysql(100) for the indexed length of a col etemplate de DB-spezifische Index-Optionen (Komma-getrennt), zB. mysql(FULLTEXT) oder mysql(100) für die indizierte Länge der Spalte
db-tools etemplate de DB-Tools
@@ -107,6 +108,7 @@ documentation etemplate de Dokumentation
drop a table - this can not be undone etemplate de Tabelle löschen (drop) - NICHT rückgänig zu machen
drop table etemplate de Tabelle löschen
dump4setup etemplate de Dump4Setup
+duration etemplate de Dauer
edit etemplate de Bearbeiten
edit embeded css styles or of the applications app.css file etemplate de bearbeitet die eingebetteten CSS Stile oder die app.css Datei der Anwendung
edit the etemplate spez. above etemplate de das oben spezifizierte eTemplate bearbeiten
@@ -165,6 +167,7 @@ height, disabled etemplate de H
help etemplate de Hilfe
horizontal rule etemplate de Waagrechte Linie
hour etemplate de Stunde
+hours etemplate de Stunden
html etemplate de HTML
if field is disabled an empty table-cell is displayed, for (temporal) removement of a field/cell etemplate de wenn das Feld deaktiviert ist, wird eine leere Tabellenzelle angezeigt, zum (zeitweisen) Entfernen eines Feldes
image etemplate de Grafik
diff --git a/etemplate/setup/phpgw_en.lang b/etemplate/setup/phpgw_en.lang
index aa2a3867bf..c36cbcac23 100644
--- a/etemplate/setup/phpgw_en.lang
+++ b/etemplate/setup/phpgw_en.lang
@@ -79,6 +79,7 @@ cut etemplate en Cut
date+time etemplate en Date+Time
datum etemplate en Datum
day etemplate en Day
+days etemplate en days
db ensures that every row has a unique value in that column etemplate en DB ensures that every row has a unique value in that column
db-specific index options (comma-sep.), eg. mysql(fulltext) or mysql(100) for the indexed length of a col etemplate en db-specific index options (comma-sep.), eg. mysql(FULLTEXT) or mysql(100) for the indexed length of a col
db-tools etemplate en DB-Tools
@@ -107,6 +108,7 @@ documentation etemplate en Documentation
drop a table - this can not be undone etemplate en Drop a table - this can NOT be undone
drop table etemplate en Drop Table
dump4setup etemplate en Dump4Setup
+duration etemplate en Duration
edit etemplate en Edit
edit embeded css styles or of the applications app.css file etemplate en edit embeded CSS styles or of the applications app.css file
edit the etemplate spez. above etemplate en edit the eTemplate spez. above
@@ -165,6 +167,7 @@ height, disabled etemplate en Height, Disabled
help etemplate en Help
horizontal rule etemplate en Horizontal Rule
hour etemplate en Hour
+hours etemplate en hours
html etemplate en Html
if field is disabled an empty table-cell is displayed, for (temporal) removement of a field/cell etemplate en if field is disabled an empty table-cell is displayed, for (temporal) removement of a field/cell
image etemplate en Image