Enable etemplate to mark rows of a grid / table as part of the header or

footer to repeat them on each printed page.
This commit is contained in:
Ralf Becker 2009-02-23 13:21:28 +00:00
parent 5c948f5d5d
commit bdcb10ea2d
7 changed files with 120 additions and 29 deletions

View File

@ -40,6 +40,11 @@ class editor
'bottom' => 'Bottom',
'baseline' => 'Baseline',
);
var $parts = array(
'' => 'Body',
'header' => 'Header',
'footer' => 'Footer',
);
var $edit_menu = array(
'delete' => 'delete',
'cut' => 'cut',
@ -1239,7 +1244,8 @@ class editor
{
list(,$row,$col) = $matches;
$parent['data'][0]['h'.$row] = $content['grid_row']['height'].
($content['grid_row']['disabled']?','.$content['grid_row']['disabled']:'');
($content['grid_row']['disabled']||$content['grid_row']['part']?','.$content['grid_row']['disabled']:'').
($content['grid_row']['part']?','.$content['grid_row']['part']:'');
$parent['data'][0]['c'.$row] = $content['grid_row']['class'].
($content['grid_row']['valign']?','.$content['grid_row']['valign']:'');
$parent['data'][0][$col] = $content['grid_column']['width'].
@ -1300,12 +1306,17 @@ class editor
list(,$row,$col) = $matches;
$grid_row =& $content['grid_row'];
list($grid_row['height'],$grid_row['disabled']) = explode(',',$parent['data'][0]['h'.$row]);
list($grid_row['height'],$grid_row['disabled'],$grid_row['part']) = explode(',',$parent['data'][0]['h'.$row]);
list($grid_row['class'],$grid_row['valign']) = explode(',',$parent['data'][0]['c'.$row]);
$grid_column =& $content['grid_column'];
list($grid_column['width'],$grid_column['disabled']) = explode(',',$parent['data'][0][$col]);
//echo "<p>grid_row($row)=".print_r($grid_row,true).", grid_column($col)=".print_r($grid_column,true)."</p>\n";
list(,,$previous_part) = explode(',',$parent['data'][0]['h'.($row-1)]);
list(,,$next_part) = explode(',',$parent['data'][0]['h'.($row+1)]);
$allowed_parts = $this->get_allowed_parts($row,$previous_part,$next_part);
//echo "<p>$row: previous=$previous_part, current={$grid_row['part']}, next=$next_part".(!isset($allowed_parts[$grid_row['part']])?': current part is NOT allowed!!!':'')."</p>\n"; _debug_array($allowed_parts);
}
else
{
@ -1352,6 +1363,7 @@ class editor
'type' => array_merge($this->etemplate->types,$this->extensions),
'align' => &$this->aligns,
'valign' => &$this->valigns,
'part' => $allowed_parts,
'edit_menu' => &$this->edit_menu,
'box_menu' => &$this->box_menu,
'row_menu' => &$this->row_menu,
@ -1362,6 +1374,38 @@ class editor
),'',$preserv,2);
}
/**
* Get the allowed tables-part for a table rows based on row-number, previous and next part
*
* @param int $row (1-based!)
* @param string $previous_part ''=body, 'h'=header, 'f'=footer
* @param string $next_part see above
* @return array
*/
private function get_allowed_parts($row,$previous_part,$next_part)
{
$allowed_parts = $this->parts;
switch((string)$previous_part)
{
case 'footer':
unset($allowed_parts['header']);
break;
case '':
if ($row > 1) $allowed_parts = array('' => $allowed_parts['']);
break;
}
switch($next_part)
{
case 'header':
$allowed_parts = array('header' => $allowed_parts['header']);
break;
case 'footer':
unset($allowed_parts['']);
break;
}
return $allowed_parts;
}
/**
* edit dialog for the styles of a templat or app
*

View File

@ -718,13 +718,15 @@ class etemplate extends boetemplate
else
{
$cols = &$data[$r_key];
list($height,$disabled) = explode(',',$opts["h$row"]);
$part = ''; // '' = body-prefix
list($height,$disabled,$part) = explode(',',$opts["h$row"]);
$class = /*TEST-RB$no_table_tr ? $tr_class :*/ $opts["c$row"];
}
if ($disabled != '' && $this->check_disabled($disabled,$content))
{
continue; // row is disabled
}
if ($part) $row = $part[0].$row; // add part prefix
$rows[".$row"] .= html::formatOptions($height,'height');
list($cl) = explode(',',$class);
if ($cl == '@' || $cl && strpos($cl,'$') !== false)

View File

@ -35,7 +35,7 @@
{
/**
* translate attr, common to all widgets
*
*
* @var array
*/
var $attr2xul = array(
@ -49,7 +49,7 @@
);
/**
* translate widget-names and widget-spec. attr., not set ones are identical
*
*
* @var array
*/
var $widget2xul = array(
@ -104,7 +104,7 @@
);
/**
* translate xul-widget names to our internal ones, not set ones are identical
*
*
* @var array
*/
var $xul2widget = array(
@ -236,7 +236,7 @@
{
$attr_widget->set_attribute('type',$cell['type']);
}
break;
break;
case 'groupbox':
if ($cell['label'])
{
@ -328,7 +328,7 @@
{
$xul_row =& new xmlnode('row');
$this->set_attributes($xul_row,'class,valign',$opts["c$r"]);
$this->set_attributes($xul_row,'height,disabled',$opts["h$r"]);
$this->set_attributes($xul_row,'height,disabled,part',$opts["h$r"]);
$spanned = 0;
foreach($row as $c => $cell)
@ -344,7 +344,7 @@
continue; // spanned cells are not written
}
$this->add_widget($xul_row,$cell,$embeded_too);
$spanned = $cell['span'] == 'all' ? 999 : $cell['span'];
}
$xul_rows->add_node($xul_row);
@ -367,7 +367,7 @@
{
if (isset($embeded_too[$etempl->name]))
{
return; // allready embeded
return; // allready embeded
}
}
else
@ -375,14 +375,14 @@
$embeded_too = array();
}
$embeded_too[$etempl->name] = True;
$template =& new xmlnode('template');
$template->set_attribute('id',$etempl->name);
$template->set_attribute('template',$etempl->template);
$template->set_attribute('lang',$etempl->lang);
$template->set_attribute('group',$etempl->group);
$template->set_attribute('version',$etempl->version);
foreach($etempl->children as $child)
{
$this->add_widget($template,$child,$embeded_too);
@ -400,7 +400,7 @@
* create an XML representation of an eTemplate
*
* @param object $etempl eTemplate object to export
* @return string the XML
* @return string the XML
*/
function export($etempl)
{
@ -431,7 +431,7 @@
* create an eTemplate from it's XML representation
*
* @param object &$etempl eTemplate object to set
* @param string $data the XML
* @param string $data the XML
* @return array/string array with names of imported templates or error-message
*/
function import(&$etempl,$data)
@ -576,7 +576,8 @@
$nul = null; soetemplate::add_child($parent,$nul); // null =& new row
$parent['data'][0]['c'.$parent['rows']] = $attr['class'] . ($attr['valign'] ? ','.$attr['valign'] : '');
$parent['data'][0]['h'.$parent['rows']] = $attr['height'] .
($attr['disabled'] ? ','.$attr['disabled'] : '');
($attr['disabled']||$attr['part'] ? ','.$attr['disabled'] : '').
($attr['part'] ? ','.$attr['part'] : '');
break;
case 'styles':
$etempl->style = trim($node['value']);
@ -595,7 +596,7 @@
$tab_attr['help'] = implode('|',$tab_helps);
$tab_attr['span'] .= $tab_attr['class'] ? ','.$tab_attr['class'] : '';
unset($tab_attr['class']);
soetemplate::add_child($parent,$tab_attr);
unset($tab_attr);
}
@ -628,7 +629,7 @@
soetemplate::add_child($parent,$menulist_attr);
unset($menulist_attr);
}
break;
break;
case 'vbox':
case 'hbox':
case 'deck':

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<!-- $Id$ -->
<overlay>
<template id="etemplate.editor.widget.generic" template="" lang="" group="0" version="1.0.1.002">
<template id="etemplate.editor.widget.generic" template="" lang="" group="0" version="1.3.001">
<grid>
<columns>
<column/>
@ -38,7 +38,6 @@
<checkbox label="%s needed" align="center" id="needed" statustext="check if field has to be filled by user"/>
<checkbox label="%s readonly" align="center" id="readonly" statustext="check if content should only be displayed but not altered (the content is not send back then!)"/>
<checkbox label="%s disabled" align="center" id="disabled" statustext="if field is disabled an empty table-cell is displayed, for (temporal) removement of a field/cell"/>
<checkbox label="%s onChange" align="center" id="onchange" statustext="enable JavaScript onChange submit"/>
</hbox>
</row>
<row class="row" disabled="@type=label">
@ -51,21 +50,30 @@
</row>
<row class="row">
<description options=",,,help" value="Help"/>
<textbox size="73" span="all" id="help" statustext="displayed in statusline of browser if input-field gets focus"/>
<textbox size="71" span="all" id="help" statustext="displayed in statusline of browser if input-field gets focus"/>
</row>
<row class="row" disabled="!@type=button">
<row class="row" disabled="@type=label">
<description value="onChange"/>
<hbox span="all">
<menulist>
<menupopup id="onchange_type" statustext="Should the form be submitted or any custom javascript be executed"/>
</menulist>
<textbox size="50" span="all" id="onchange" statustext="custom javascript for onChange"/>
</hbox>
</row>
<row class="row">
<description options="onclick" value="onClick"/>
<hbox span="all">
<menulist>
<menupopup id="onclick_type" statustext="confirmation necesary or custom java-script"/>
</menulist>
<textbox size="58" span="all" id="onclick" statustext="confirmation message or custom javascript (returning true or false)"/>
<textbox size="53" span="all" id="onclick" statustext="confirmation message or custom javascript (returning true or false)"/>
</hbox>
</row>
</rows>
</grid>
</template>
<template id="etemplate.editor.widget" template="" lang="" group="0" version="1.0.1.006">
<template id="etemplate.editor.widget" template="" lang="" group="0" version="1.7.001">
<grid>
<columns>
<column/>
@ -114,12 +122,15 @@
<row disabled="!@grid_row">
<groupbox span="all" orient="horizontal">
<caption label="Grid row attributes"/>
<textbox size="5" label="Height" id="grid_row[height]" statustext="height of row (in % or pixel)"/>
<textbox size="10" label="Disabled" id="grid_row[disabled]" statustext="to disable: [! = not]&lt;value&gt;[=&lt;check&gt;] eg: '!@data' disables if content of data is empty"/>
<textbox size="10" label="Class" id="grid_row[class]" statustext="CSS-class name for this row, preset: 'th' = header, 'row' = alternating row, 'row_off'+'row_on' rows"/>
<textbox size="3" label="Height" id="grid_row[height]" statustext="height of row (in % or pixel)"/>
<textbox size="8" label="Disabled" id="grid_row[disabled]" statustext="to disable: [! = not]&lt;value&gt;[=&lt;check&gt;] eg: '!@data' disables if content of data is empty"/>
<textbox size="8" label="Class" id="grid_row[class]" statustext="CSS-class name for this row, preset: 'th' = header, 'row' = alternating row, 'row_off'+'row_on' rows"/>
<menulist>
<menupopup label="Valign" id="grid_row[valign]" statustext="vertical alignment of row"/>
</menulist>
<menulist>
<menupopup label="Part" id="grid_row[part]" statustext="part of the table (header and footer have to be before body!)"/>
</menulist>
</groupbox>
</row>
<row disabled="!@grid_column">

View File

@ -733,11 +733,24 @@ class html
return self::form(self::submit_button($name,$label),$hidden_vars,$url,$url_vars,$form_name,'',$method);
}
const THEAD = 1;
const TFOOT = 2;
const TBODY = 3;
static $part2tag = array(
self::THEAD => 'thead',
self::TFOOT => 'tfoot',
self::TBODY => 'tbody',
);
/**
* creates table from array of rows
*
* abstracts the html stuff for the table creation
* Example: $rows = array (
* 'h1' => array( // optional header row(s)
* ),
* 'f1' => array( // optional footer row(s)
* ),
* '1' => array(
* 1 => 'cell1', '.1' => 'colspan=3',
* 2 => 'cell2',
@ -754,12 +767,20 @@ class html
{
$html = $no_table_tr ? '' : "<table $options>\n";
$part = 0;
foreach($rows as $key => $row)
{
if (!is_array($row))
{
continue; // parameter
}
// get the current part from the optional 'h' or 'f' prefix of the key
$p = $key[0] == 'h' ? html::THEAD : ($key[0] == 'f' ? html::TFOOT : html::TBODY);
if ($part < $p && ($part || $p < self::TBODY)) // add only allowed and neccessary transitions
{
if ($part) $html .= '</'.self::$part2tag[$part].">\n";
$html .= '<'.self::$part2tag[$part=$p].">\n";
}
$html .= $no_table_tr && $key == 1 ? '' : "\t<tr ".$rows['.'.$key].">\n";
foreach($row as $key => $cell)
@ -785,6 +806,10 @@ class html
{
echo "<p>".function_backtrace()."</p>\n";
}
if ($part) // close current part
{
$html .= "</".self::$part2tag[$part].">\n";
}
$html .= "</table>\n";
if ($no_table_tr)

View File

@ -1,6 +1,6 @@
/*
The styles in this file are used for printing only!
Additional UI Elements can be disabled for printing by adding their Id here or adding the noPrint class to them.
*/
/* $Id$ */
@ -66,4 +66,8 @@ a,a:link,a:visited,a:hover {
/* hide background-image to save print costs and spool time */
body {
background-image: none;
}
}
/* MSIE needs these styles to repeat table header and footer part on each page */
thead { display: table-header-group; }
tfoot { display: table-footer-group; }