cvsuser 05/10/20 13:29:50
Added: App-Widget/lib/App/Widget DataTable2.pm
Log:
new
Revision Changes Path
1.1 p5ee/App-Widget/lib/App/Widget/DataTable2.pm
Index: DataTable2.pm
===================================================================
######################################################################
## $Id: DataTable2.pm,v 1.1 2005/10/20 20:29:50 spadkins Exp $
######################################################################
package App::Widget::DataTable2;
$VERSION = do { my @r=(q$Revision: 1.1 $=~/\d+/g); sprintf
"%d."."%02d"x$#r,@r};
use App;
use App::Widget;
@ISA = ( "App::Widget" );
use strict;
=head1 NAME
App::Widget::DataTable2 - An HTML table which serves as a repository table
viewer/editor
=head1 SYNOPSIS
use App::Widget::DataTable2;
$name = "get_data";
$w = App::Widget::DataTable2->new($name);
print $w->html();
=cut
######################################################################
# CONSTANTS
######################################################################
######################################################################
# ATTRIBUTES
######################################################################
# {border} = 0;
# {cellspacing} = 2;
# {cellpadding} = 0;
# {width} = "";
# {bgcolor} = "";
# {nowrap} = "1";
# {font_face} = "verdana,geneva,arial,sans-serif";
# {font_size} = "-2";
# {font_color} = "";
# {heading_bgcolor} = "#cccccc";
# {heading_nowrap} = 0;
# {heading_align} = 0;
# {heading_valign} = 0;
# {column_selectable} = 1;
# {row_selectable} = 0;
# {row_single_selectable} = 0;
# {columns} = [ "Name", "Address", "City", "State", "Country",
"Home Phone" ];
# {headings} = [ "Name", "Address", "City", "State", "Country",
"Home Phone" ];
# {data} = [ [ "Smith, Harold", "1215 Interloke Pass",
"Jonesboro", "GA", "US", "770-603-1810" ],
# [ "Smith, Mike", "1215 Interloke Pass",
"Jonesboro", "GA", "US", "770-603-1811" ],
# [ "Smith, Sarah", "1215 Interloke Pass",
"Jonesboro", "GA", "US", "770-603-1812" ],
# [ "Smith, Ken", "1215 Interloke Pass",
"Jonesboro", "GA", "US", "770-603-1813" ],
# [ "Smith, Mary", "1215 Interloke Pass",
"Jonesboro", "GA", "US", "770-603-1814" ], ];
# {startrow} = 1
# {maxrows} = 20
# {scrollable} = 0;
# {sortable} = 0;
# {filterable} = 0;
# {editable} = 0;
# INPUTS FROM THE ENVIRONMENT
=head1 DESCRIPTION
This class is a <input type=submit> HTML element.
In the advanced configurations, it is rendered as an image button.
=cut
######################################################################
# INITIALIZATION
######################################################################
sub _init {
&App::sub_entry if ($App::trace);
my $self = shift;
$self->SUPER::_init(@_);
$self->{table} = $self->{name} if (!$self->{table});
$self->{context}->dbgprint("DataTable2->init()")
if ($App::DEBUG && $self->{context}->dbg(1));
}
######################################################################
# EVENTS
######################################################################
# Usage: $widget->handle_event($event, @args);
sub handle_event {
&App::sub_entry if ($App::trace);
my ($self, $wname, $event, @args) = @_;
my ($name, $context, $colnum, $x, $y, $startrow, $maxrows, $width,
$direction);
#$self->clear_messages();
$name = $self->{name};
$self->{context}->dbgprint("DataTable2($name)->handle_event($wname,$event,@args)")
if ($App::DEBUG && $self->{context}->dbg(1));
my $handled = 0;
if ($wname eq "$name-view") {
$self->set("mode","view");
$self->delete("editdata");
$handled = 1;
}
elsif ($wname eq "$name-edit") {
$self->set("mode","edit");
$handled = 1;
}
elsif ($wname eq "$name-next") {
$startrow = $self->get("startrow",1,1);
$maxrows = $self->get("maxrows",20,1);
$startrow += $maxrows;
$self->set("startrow",$startrow);
$handled = 1;
}
elsif ($wname eq "$name-prev") {
$startrow = $self->get("startrow",1,1);
$maxrows = $self->get("maxrows",20,1);
$startrow -= $maxrows;
$startrow = 1 if ($startrow < 1);
$self->set("startrow",$startrow);
$handled = 1;
}
elsif ($wname eq "$name-save") {
$self->save();
$self->delete("editdata");
$handled = 1;
}
elsif ($wname eq "$name-add") {
$self->{context}->add_message("Add Rows: not yet implemented");
$handled = 1;
}
elsif ($wname eq "$name-delete") {
$self->{context}->add_message("Delete Rows: not yet implemented");
$handled = 1;
}
elsif ($event eq "sort") {
($colnum, $direction) = @args;
my ($columns, $directions, $order_by, $column, $i);
$columns = $self->get_columns();
$column = $columns->[$colnum];
$order_by = $self->get("order_by") || $self->get("ordercols"); #
ordercols is deprecated in favor of order_by
if (defined $order_by) {
$directions = $self->get("directions");
$directions = [] if (!defined $directions);
for ($i = 0; $i <= $#$order_by; $i++) {
if ($order_by->[$i] eq $column) {
splice(@$order_by, $i, 1); # delete the use of $column
splice(@$directions, $i, 1); # delete the sort
direction
last;
}
}
unshift(@$order_by, $column); # put it at the beginning
unshift(@$directions, $direction);
}
else {
$order_by = [ $column ];
$directions = [ $direction ];
}
$self->set("order_by",$order_by);
$self->set("directions",$directions);
$handled = 1;
}
elsif ($wname =~ /-sort[0-9]*$/) {
($colnum, $x, $y) = @args;
$context = $self->{context};
$width = $context->widget($wname)->get("width");
if ($x <= $width/2) {
$handled = $self->handle_event($wname, "sort", $colnum, "UP");
}
else {
$handled = $self->handle_event($wname, "sort", $colnum, "DOWN");
}
}
else {
$handled = $self->SUPER::handle_event(@_);
}
&App::sub_exit($handled) if ($App::trace);
return($handled);
}
######################################################################
# METHODS
######################################################################
sub get_columns {
&App::sub_entry if ($App::trace);
my $self = shift;
my ($columns);
$columns = $self->{columns};
if (defined $columns && ref($columns) eq "") {
$columns = [ $columns ];
$self->set("columns", $columns);
}
if (!defined $columns) {
my ($repository, $rep, $table);
$repository = $self->{repository};
$table = $self->{table};
$rep = $self->{context}->repository($repository);
if ($rep && $table) {
$columns = $rep->get_column_names($table);
}
}
$columns = [] if (!defined $columns || ref($columns) eq "");
&App::sub_exit($columns) if ($App::trace);
$columns;
}
sub get_headings {
&App::sub_entry if ($App::trace);
my $self = shift;
$self->{context}->dbgprint("DataTable2->get_headings()")
if ($App::DEBUG && $self->{context}->dbg(1));
my ($table, $headings, $heading, $columns, $column, $lang);
$table = $self->get("table");
$columns = $self->get_columns();
$headings = $self->get("headings");
$lang = $self->{lang};
my $column_attribs = $self->{column} || {};
if (!defined $headings) {
$headings = [];
my ($repname, $context, $rep, $columnlabels);
$repname = $self->get("repository");
$context = $self->{context};
$rep = $context->repository($repname);
$columnlabels = $rep->get_column_labels($table);
foreach $column (@$columns) {
$heading = $column_attribs->{$column}{label} ||
$columnlabels->{$column} || $column;
$heading = $self->translate($heading, $lang) if (defined $lang);
push(@$headings, $heading);
$self->{context}->dbgprint("DataTable2->get_headings():
column=$column(",$#$columns,") heading=$heading(",$#$headings,")")
if ($App::DEBUG >= 6 && $self->{context}->dbg(6));
}
}
$self->{context}->dbgprint("DataTable2->get_headings(): columns=[",
join(",", @{$self->get("columns",[])}), "]")
if ($App::DEBUG && $self->{context}->dbg(1));
&App::sub_exit($headings) if ($App::trace);
$headings;
}
sub get_data {
&App::sub_entry if ($App::trace);
my $self = shift;
$self->{context}->dbgprint("DataTable2->get_data()")
if ($App::DEBUG && $self->{context}->dbg(1));
my ($data);
$data = $self->{data};
$data = $self->get("data") if (! defined $data);
if (!defined $data) {
$self->load();
$data = $self->{data};
}
&App::sub_exit($data) if ($App::trace);
return $data;
}
sub load {
&App::sub_entry if ($App::trace);
my $self = shift;
$self->{context}->dbgprint("DataTable2->load()")
if ($App::DEBUG && $self->{context}->dbg(1));
my ($context, $repname, $rep, $rows, $table, $columns, $sql, $error,
$data);
my ($params, $paramvalues, $param, $paramvalue, @paramvalues);
my ($startrow, $maxrows, $endrow, $keycolidx);
my (%paramvalues, $filter, $column);
$repname = $self->get("repository");
$context = $self->{context};
$rep = $context->repository($repname);
return if (! defined $rep);
$sql = $self->get("sql");
$data = $self->get("data");
if ($sql) {
$paramvalues = $self->substitute($self->get("paramvalues"));
$sql = $self->substitute($sql, $paramvalues);
$startrow = $self->get("startrow", 1, 1);
$maxrows = $self->get("maxrows", 20, 1);
$endrow = ($maxrows != 0) ? ($startrow + $maxrows - 1) : 0;
$rows = [ $rep->exec_select($sql, $startrow, $endrow) ];
$error = $rep->error();
if ($#$rows == -1 && $error) {
$context->add_message("SQL error: $error<br>$sql");
}
}
elsif ($data) {
$rows = $data;
}
else {
$table = $self->get("table");
$columns = $self->get_columns();
if (! defined $columns || $#$columns == -1) {
$columns = $rep->get_column_names($table);
if (!defined $columns || $#$columns == -1) {
$context->add_message("No columns specified");
return;
}
}
else {
$columns = [ @$columns ];
}
$params = $self->get("params");
$paramvalues = $self->substitute($self->get("paramvalues",{}));
%paramvalues = %$paramvalues;
$filter = $self->get("filter",{});
foreach $column (%$filter) {
$param = $column;
$paramvalue = $filter->{$column};
if (defined $paramvalue && $paramvalue ne "") {
if ($param =~ /\./) {
if (!defined $paramvalues{$param} && defined $params) {
push(@$params,$param);
}
$paramvalues{$param} = $paramvalue;
}
elsif ($paramvalue =~ /^ *[=~!<>\/]/) {
@paramvalues = split(/ *([=~!<>\/]+) */,$paramvalue);
my ($i, $op);
for ($i = 1; $i < $#paramvalues; $i += 2) {
$op = "";
if ($paramvalues[$i] eq "=") { $op = "eq"; }
elsif ($paramvalues[$i] eq "==") { $op = "eq"; }
elsif ($paramvalues[$i] eq "!=") { $op = "ne"; }
elsif ($paramvalues[$i] eq "<>") { $op = "ne"; }
elsif ($paramvalues[$i] eq "<") { $op = "lt"; }
elsif ($paramvalues[$i] eq "<=") { $op = "le"; }
elsif ($paramvalues[$i] eq ">") { $op = "gt"; }
elsif ($paramvalues[$i] eq ">=") { $op = "ge"; }
elsif ($paramvalues[$i] eq "~") { $op = "contains"; }
elsif ($paramvalues[$i] eq "~=") { $op = "contains"; }
elsif ($paramvalues[$i] eq "=~") { $op = "contains"; }
elsif ($paramvalues[$i] eq "/") { $op = "matches"; }
$paramvalue = $paramvalues[$i+1];
if ($op) {
$param = "$column.$op";
if (!defined $paramvalues{$param}) {
push(@$params,$param) if (defined $params);
$paramvalues{$param} = $paramvalue;
}
}
}
}
elsif ($paramvalue =~ /,/) {
$param = "$column.in";
if (!defined $paramvalues{$param}) {
push(@$params,$param) if (defined $params);
$paramvalues{$param} = $paramvalue;
}
}
else {
$param = "$column.contains";
if (!defined $paramvalues{$param} && defined $params) {
push(@$params,$param);
}
$paramvalues{$param} = $paramvalue;
}
}
}
my $order_by = $self->get("order_by") || $self->get("ordercols");
# ordercols is deprecated in favor of order_by
my $group_by = $self->get("group_by");
my $directions = $self->get("directions");
$startrow = $self->get("startrow", 1, 1);
$maxrows = $self->get("maxrows", 20, 1);
$endrow = ($maxrows != 0) ? ($startrow + $maxrows - 1) : 0;
if ($App::DEBUG && $self->{context}->dbg(1)) {
$self->{context}->dbgprint("DataTable2->load():
get_rows($table,c=$columns,p=$params,pv=$paramvalues,oc=$order_by,$startrow,$endrow,$directions);");
$self->{context}->dbgprint("DataTable2->load(): columns=[",
join(",", @$columns), "]") if (ref($columns) eq "ARRAY");
$self->{context}->dbgprint("DataTable2->load(): params=[",
join(",", @$params), "]") if (ref($params) eq "ARRAY");
$self->{context}->dbgprint("DataTable2->load(): paramvalues=[",
join(",", %$paramvalues), "]") if (ref($paramvalues) eq "HASH");
$self->{context}->dbgprint("DataTable2->load(): order_by=[",
join(",", @$order_by), "]") if (ref($order_by) eq "ARRAY");
$self->{context}->dbgprint("DataTable2->load(): directions=[",
join(",", @$directions), "]") if (ref($directions) eq "ARRAY");
}
#$rows = $rep->select_rows($table, $columns, $params, \%paramvalues,
$order_by, $startrow, $endrow, $directions);
#$rows = $rep->select_rows($table, $columns, undef, \%paramvalues,
$order_by, $startrow, $endrow, $directions);
$rows = $rep->get_rows($table, \%paramvalues, $columns,
{order_by => $order_by, startrow => $startrow, endrow => $endrow,
directions => $directions, group_by => $group_by});
$error = $rep->error();
if ($#$rows == -1 && $error) {
$sql = $rep->{sql};
$context->add_message("SQL error: $error<br>$sql");
}
}
my ($keys, $row);
$self->{data} = $rows;
$keycolidx = $self->get("keycolidx");
if (defined $keycolidx && ref($keycolidx) eq "ARRAY") {
$keys = [];
foreach $row (@$rows) {
push(@$keys, [ @[EMAIL PROTECTED] ]);
}
$self->set("keys", $keys);
}
&App::sub_exit() if ($App::trace);
}
sub save {
&App::sub_entry if ($App::trace);
my $self = shift;
my ($repname, $context, $rep, $table);
my ($editdata, $key, $column, @columns, @values);
$repname = $self->get("repository");
$context = $self->{context};
$rep = $context->repository($repname);
if (! $rep) {
$context->add_message("No repository specified");
return;
}
$table = $self->get("table");
if (! $table) {
$context->add_message("No table specified");
return;
}
$editdata = $self->get("editdata");
if ($editdata) {
foreach $key (keys %$editdata) {
@columns = ();
@values = ();
foreach $column (keys %{$editdata->{$key}}) {
push(@columns, $column);
push(@values, $editdata->{$key}{$column});
}
$rep->set($table, $key, [EMAIL PROTECTED], [EMAIL PROTECTED]);
}
}
$rep->commit();
&App::sub_exit() if ($App::trace);
}
sub substitute {
&App::sub_entry if ($App::trace);
my ($self, $text, $values) = @_;
my ($phrase, $var, $value, $context);
$context = $self->{context};
$values = {} if (! defined $values);
if (ref($text) eq "HASH") {
my ($hash, $newhash);
$hash = $text; # oops, not text, but a hash of text values
$newhash = {}; # prepare a new hash for the substituted values
foreach $var (keys %$hash) {
$newhash->{$var} = $self->substitute($hash->{$var}, $values);
}
&App::sub_exit($newhash) if ($App::trace);
return($newhash); # short-circuit this whole process
}
while ( $text =~ /^\[([^\[\]]+)\]$/ ) {
$phrase = $1;
while ( $phrase =~ /\{([^\{\}]+)\}/ ) {
$var = $1;
if (defined $values->{$var}) {
$value = $values->{$var};
$value = join(",", @$value) if (ref($value) eq "ARRAY");
$phrase =~ s/\{$var\}/$value/g;
}
else {
$value = $context->so_get($var);
$value = join(",", @$value) if (ref($value) eq "ARRAY");
if (defined $value) {
$phrase =~ s/\{$var\}/$value/g;
}
else {
$phrase = "";
}
}
}
if ($phrase eq "") {
$text =~ s/^\[[^\[\]]+\]\n?$//; # zap it including (optional)
ending newline
}
else {
$text =~ s/^\[[^\[\]]+\]$/$phrase/;
}
}
while ( $text =~ /\{([^\{\}]+)\}/ ) { # vars of the form {var}
$var = $1;
if (defined $values->{$var}) {
$value = $values->{$var};
$value = join(",", @$value) if (ref($value) eq "ARRAY");
$text =~ s/\{$var\}/$value/g;
}
else {
$value = $context->so_get($var);
$value = join(",", @$value) if (ref($value) eq "ARRAY");
}
$value = "" if (!defined $value);
$text =~ s/\{$var\}/$value/g;
}
&App::sub_exit($text) if ($App::trace);
$text;
}
######################################################################
# OUTPUT METHODS
######################################################################
sub table_html {
&App::Widget::DataTable2::html(@_);
}
sub html {
&App::sub_entry if ($App::trace);
my $self = shift;
$self->{context}->dbgprint("DataTable2->html()")
if ($App::DEBUG && $self->{context}->dbg(1));
my ($context, $name, $data);
$context = $self->{context};
$name = $self->{name};
my ($key, $column);
my ($numcols, $table, $title);
my ($width, $border, $cellspacing, $cellpadding);
my ($bgcolor, $align, $valign, $nowrap);
my ($font_face, $font_size, $font_color);
my ($heading_bgcolor, $heading_align, $heading_valign, $heading_nowrap);
my ($columns, $headings, $scrollable, $sortable, $filterable, $editable);
my ($startrow, $numrow, $numbered);
my ($keys, $mode, $sql);
my ($column_selectable, $row_selectable, $row_single_selectable,
$elem_selected, $single_row_select);
my (@edit_style, @column_length);
my ($rowactions, $rowactiondefs, $rowaction, $rowactiondef);
my (@select_actions, @single_select_actions, @row_actions);
$table = $self->get("table");
return "No table defined." if (!$table);
$columns = $self->get_columns();
return "No columns defined for table [$table]. (maybe it doesn't exist)"
if (!$columns || $#$columns == -1);
$headings = $self->get_headings();
$data = $self->get_data();
$startrow = $self->get("startrow", 1);
$title = $self->get("title");
$width = $self->get("width");
$bgcolor = $self->get("bgcolor");
$font_color = $self->get("font_color");
$border = $self->get("border", 0);
$cellspacing = $self->get("cellspacing", 2);
$cellpadding = $self->get("cellpadding", 2);
$align = $self->get("align", "");
$valign = $self->get("valign", "top");
$nowrap = $self->get("nowrap", 1);
$font_face = $self->get("font_face",
"verdana,geneva,arial,sans-serif");
$font_size = $self->get("font_size", -2);
$heading_bgcolor = $self->get("heading_bgcolor", "#cccccc");
$heading_align = $self->get("heading_align", $align);
$heading_valign = $self->get("heading_valign", "bottom");
$heading_nowrap = $self->get("heading_nowrap", $nowrap);
$mode = $self->get("mode", "view");
$scrollable = $self->get("scrollable", 0);
$sortable = $self->get("sortable", 0);
$filterable = $self->get("filterable", 0);
$editable = $self->get("editable", 0);
$numbered = $self->get("numbered", 1);
$column_selectable = $self->get("column_selectable", 1);
$row_selectable = $self->get("row_selectable", (($mode eq "edit") ?
1 : 0));
$row_single_selectable = $self->get("row_single_selectable", 0);
$keys = $self->get("keys");
$sql = $self->get("sql");
$rowactions = $self->get("rowactions");
$rowactiondefs = $self->get("rowaction");
my $repname = $self->get("repository");
my $rep = $context->repository($repname);
my $table_def = $rep->{table}{$table};
my $table_column_defs = $table_def->{column};
my $view_column_defs = $self->{column} || {};
if (! $self->{keycolidx}) {
$rowactions = undef;
$row_selectable = 0; # can't select row(s) if no primary key
$row_single_selectable = 0; # can't select row if no primary key
}
elsif ($rowactions && $rowactiondefs) {
foreach $rowaction (@$rowactions) {
if ($rowactiondefs->{$rowaction}{select} eq "single") {
push(@single_select_actions, $rowaction);
$row_single_selectable = 1;
}
elsif ($rowactiondefs->{$rowaction}{select} eq "multi") {
push(@select_actions, $rowaction);
$row_selectable = 1;
}
else {
push(@row_actions, $rowaction);
}
}
}
# only needed for subtotals
#my ($subtotal, $subtotal_keys, $order_by);
#$subtotal_keys = $self->get("subtotal_keys");
#$subtotal = (defined $subtotal_keys && ref($subtotal_keys) eq "ARRAY" &&
$#$subtotal_keys > -1);
#if ($subtotal) {
# $order_by = $self->get("order_by") || $self->get("ordercols"); #
ordercols is deprecated in favor of order_by
#}
my ($html, $row, $col, $elem);
my ($td_row_attrib, $td_col_attrib, $elem_begin, $elem_end, $table_begin);
$table_begin = "<table";
$table_begin .= " width=\"$width\"" if (defined $width && $width ne "");
$table_begin .= " border=\"$border\"" if (defined $border && $border ne
"");
$table_begin .= " cellspacing=\"$cellspacing\"" if (defined $cellspacing
&& $cellspacing ne "");
$table_begin .= " cellpadding=\"$cellpadding\"" if (defined $cellpadding
&& $cellpadding ne "");
$table_begin .= ">\n";
$html = "<!-- -->";
if (defined $title) {
$title = $context->substitute($title);
$html .= $title;
}
$numcols = $self->{numcols} || $#$headings + 1;
if ($scrollable || $sortable || $filterable || $mode eq "edit") {
$elem_begin = "";
$elem_end = "";
if ($font_face || $font_size || $font_color) {
$elem_begin = "<font";
$elem_begin .= " face=\"$font_face\"" if ($font_face);
$elem_begin .= " size=\"" . ($font_size+1) . "\"" if
($font_size);
$elem_begin .= " color=\"$font_color\"" if ($font_color);
$elem_begin .= ">";
$elem_end = "</font>";
}
if ($scrollable) {
$html .= "<table border=\"0\" cellspacing=\"0\"
cellpadding=\"5\"><tr><td>\n";
$html .= "<table border=\"0\" cellspacing=\"0\"
cellpadding=\"3\"><tr><td valign=\"middle\" nowrap> \n";
$html .= $context->widget("$name-view",
class => "App::Widget::ImageButton",
image_script => 'app-button',
#volatile => 1,
label => 'View',
height => 17,
width => 50,
bevel => 2,
)->html();
$html .= " ";
if ($editable) {
$html .= $context->widget("$name-edit",
class => "App::Widget::ImageButton",
image_script => 'app-button',
#volatile => 1,
label => 'Edit',
height => 17,
width => 50,
bevel => 2,
)->html();
$html .= " ";
}
$html .= " </td><td nowrap";
$html .= " bgcolor=\"$heading_bgcolor\"" if ($heading_bgcolor);
$html .= ">$elem_begin \n";
$html .= $context->widget("$name-prev",
class => "App::Widget::ImageButton",
image_script => 'app-button',
#volatile => 1,
label => '<< Prev',
height => 17,
width => 70,
bevel => 2,
)->html();
$html .= "\n Start Row:";
$html .= $context->widget("$name-startrow",
class => "App::Widget::TextField",
size => 4,
maxlength => 12,
)->html();
$html .= " Num Rows:";
$html .= $context->widget("$name-maxrows",
class => "App::Widget::TextField",
size => 4,
maxlength => 12,
)->html();
$html .= "\n";
$html .= $context->widget("$name-next",
class => "App::Widget::ImageButton",
image_script => 'app-button',
#volatile => 1,
label => 'Next >>',
height => 17,
width => 70,
bevel => 2,
)->html();
$html .= " $elem_end</td></tr></table>\n";
$html .= "</td></tr></table>\n";
}
if ($mode eq "edit") {
$html .= "<table border=\"0\" cellspacing=\"0\"
cellpadding=\"3\"><tr>\n";
$html .= "<td>\n";
$html .= $context->widget("$name-save",
class => "App::Widget::ImageButton",
image_script => 'app-button',
#volatile => 1,
label => 'Save',
height => 17,
width => 50,
bevel => 2,
)->html();
$html .= "</td>\n";
$html .= "<td>\n";
$html .= $context->widget("$name.add",
class => "App::Widget::ImageButton",
image_script => 'app-button',
#volatile => 1,
label => 'Add Rows',
height => 17,
width => 85,
bevel => 2,
)->html();
$html .= "</td>\n";
$html .= "<td>\n";
$html .= $context->widget("$name-delete",
class => "App::Widget::ImageButton",
image_script => 'app-button',
#volatile => 1,
label => 'Delete Rows',
height => 17,
width => 85,
bevel => 2,
)->html();
$html .= "</td>\n";
#$html .= "<td>\n";
#$html .= $context->widget("$name-confirm",
# class => "App::Widget::RadioButtonSet",
# #volatile => 1,
# values => [ "no_confirm", "confirm", "auto_confirm"
],
# labels => {
# "no_confirm" => "Changes Not Confirmed",
# "confirm" => "Confirm Changes",
# "auto_confirm" => "Auto-Confirm",
# },
# )->html();
#$html .= "</td>\n";
$html .= "</tr></table>\n";
}
$html .= $table_begin;
if (!$sql) {
if ($sortable) {
$html .= "<tr>\n";
$html .= " <td> </td>\n" if ($numbered);
$html .= " <td> </td>\n" if ($row_selectable);
$html .= " <td> </td>\n" if ($row_single_selectable);
$html .= " <td> </td>\n" if ($#row_actions > -1);
for ($col = 0; $col < $numcols; $col++) {
$elem = $context->widget("$name-sort$col",
class => "App::Widget::ImageButton",
image_script => 'app-button',
#volatile => 1,
label => 'Up|Dn',
height => 17,
width => 50,
bevel => 2,
args => $col,
)->html();
$html .= " <td>$elem</td>\n";
}
$html .= "</tr>\n";
}
if ($filterable) {
my ($w);
$html .= "<tr>\n";
$html .= " <td> </td>\n" if ($numbered);
$html .= " <td> </td>\n" if ($row_selectable);
$html .= " <td> </td>\n" if ($row_single_selectable);
$html .= " <td> </td>\n" if ($#row_actions > -1);
for ($col = 0; $col < $numcols; $col++) {
$column = $columns->[$col];
#$elem = $context->widget("$name\{filter}{$column}",
# class => "App::Widget::TextField",
# size => 5,
# maxwidth => 99,
# )->html();
$w = $context->widget("$name\{filter}{$column}",
class => "App::Widget::TextField",
size => 5,
maxwidth => 99,
);
$elem = $w->html();
$html .= " <td>$elem_begin$elem$elem_end</td>\n";
}
$html .= "</tr>\n";
}
}
if ($mode eq "edit" && $column_selectable) {
$html .= "<tr>\n";
$html .= " <td bgcolor=\"#ffaaaa\"> </td>\n" if ($numbered);
$html .= " <td bgcolor=\"#ffaaaa\"> </td>\n" if
($row_selectable);
$html .= " <td bgcolor=\"#ffaaaa\"> </td>\n" if
($row_single_selectable);
$html .= " <td bgcolor=\"#ffaaaa\"> </td>\n" if
($#row_actions > -1);
for ($col = 0; $col < $numcols; $col++) {
$column = $columns->[$col];
$elem = $context->widget("$name\{column_selected}{$column}",
class => "App::Widget::Checkbox",
)->html();
$html .= " <td bgcolor=\"#ffaaaa\" valign=\"bottom\"
align=\"center\">$elem</td>\n";
}
$html .= "</tr>\n";
}
}
else {
$html .= $table_begin;
}
$elem_begin = "";
$elem_end = "";
if ($font_face || $font_size || $font_color) {
$elem_begin = "<font";
$elem_begin .= " face=\"$font_face\"" if ($font_face);
$elem_begin .= " size=\"$font_size\"" if ($font_size);
$elem_begin .= " color=\"$font_color\"" if ($font_color);
$elem_begin .= ">";
$elem_end = "</font>";
}
$td_row_attrib = "";
$td_row_attrib .= " bgcolor=\"$heading_bgcolor\"" if ($heading_bgcolor);
$td_row_attrib .= " align=\"$heading_align\"" if ($heading_align);
$td_row_attrib .= " valign=\"$heading_valign\"" if ($heading_valign);
$td_row_attrib .= " nowrap" if ($heading_nowrap);
$html .= "<tr>\n";
$html .= " <td bgcolor=\"$heading_bgcolor\"> </td>\n" if
($numbered);
if ($row_selectable) {
if ($#select_actions > -1) {
my (%args);
$html .= " <td bgcolor=\"$heading_bgcolor\" valign=\"bottom\">";
foreach $rowaction (@select_actions) {
%args = (
override => 1,
class => "App::Widget::ImageButton",
image_script => 'app-button',
volatile => 1,
height => 17,
width => 50,
bevel => 2,
);
$rowactiondef = $rowactiondefs->{$rowaction};
if ($rowactiondef) {
foreach (keys %$rowactiondef) {
$args{$_} = $rowactiondef->{$_};
}
}
$html .= $context->widget("$name-${rowaction}", %args,
args => "{${name}" . "{row_selected}}"
)->html();
$html .= "<br>\n" if ($rowaction ne
$select_actions[$#select_actions]);
}
$html .= "</td>\n";
}
else {
$html .= " <td bgcolor=\"#ffaaaa\"> </td>\n";
}
}
if ($row_single_selectable) {
if ($#single_select_actions > -1) {
my (%args);
$html .= " <td bgcolor=\"$heading_bgcolor\" valign=\"bottom\">";
foreach $rowaction (@single_select_actions) {
%args = (
override => 1,
class => "App::Widget::ImageButton",
image_script => 'app-button',
volatile => 1,
height => 17,
width => 50,
bevel => 2,
);
$rowactiondef = $rowactiondefs->{$rowaction};
if ($rowactiondef) {
foreach (keys %$rowactiondef) {
$args{$_} = $rowactiondef->{$_};
}
}
$html .= $context->widget("$name-${rowaction}", %args,
args => "{${name}" . "{row_single_selected}}"
)->html();
$html .= "<br>\n" if ($rowaction ne
$single_select_actions[$#select_actions]);
}
$html .= "</td>\n";
}
else {
$html .= " <td bgcolor=\"#ffaaaa\"> </td>\n";
}
}
$html .= " <td bgcolor=\"$heading_bgcolor\"> </td>\n" if
($#row_actions > -1);
for ($col = 0; $col < $numcols; $col++) {
$td_col_attrib = "";
$elem = $headings->[$col];
$elem = " " if (!defined $elem || $elem eq "");
$html .= "
<td$td_row_attrib$td_col_attrib>$elem_begin$elem$elem_end</td>\n";
}
$html .= "</tr>\n";
$td_row_attrib = "";
$td_row_attrib .= " bgcolor=\"$bgcolor\"" if ($bgcolor);
#$td_row_attrib .= " align=\"$align\"" if ($align);
$td_row_attrib .= " valign=\"$valign\"" if ($valign);
$td_row_attrib .= " nowrap" if ($nowrap);
# since we are editing, we need to prepare these two arrays...
@edit_style = ();
@column_length = ();
if ($mode eq "edit") {
# prepare the style attribute arrays
push(@edit_style, "font_family", $font_face) if ($font_face);
push(@edit_style, "color", $font_color) if ($font_color);
# This seems to cause <input> elements to take on the font size
# currently active for text that surrounds them
# i.e. <font size="-2"><input type="text" style="font-size:
100%;"></font>
push(@edit_style, "font_size", "100%") if ($font_size);
# border_style",
# border_width",
# border_color",
# padding",
# background_color",
# any columns we are editing, we need to compute max width (size) for
textfield
for ($col = 0; $col < $numcols; $col++) {
$column_length[$col] = 5; # minimum length
$column = "";
if (defined $columns && defined $columns->[$col]) {
$column = $columns->[$col];
}
if (($column ne "" && $self->{column_selected}{$column}) ||
($self->{row_selected} && %{$self->{row_selected}})) {
for ($row = 0; $row <= $#$data; $row++) {
$elem = $data->[$row][$col];
if (defined $elem && length($elem) >
$column_length[$col]) {
$column_length[$col] = length($elem);
}
}
}
}
}
my ($format, $scale_factor);
for ($row = 0; $row <= $#$data; $row++) {
$numrow = $startrow + $row;
$html .= "<tr>\n";
$key = "";
if (defined $keys && defined $keys->[$row]) {
$key = join(",", @{$keys->[$row]}); # need to HTML-escape these!
}
$html .= " <td bgcolor=\"$heading_bgcolor\"
align=\"right\">$elem_begin$numrow$elem_end</td>\n" if ($numbered);
if ($row_selectable) {
$html .= " <td bgcolor=\"#ffaaaa\" valign=\"middle\"
align=\"center\">\n";
$html .= $context->widget("$name\{row_selected}{$key}",
class => "App::Widget::Checkbox",
)->html();
$html .= " </td>\n";
}
if ($row_single_selectable) {
$html .= " <td bgcolor=\"#ffaaaa\" valign=\"middle\"
align=\"center\">\n";
$html .= $context->widget("$name\{row_single_selected}",
class => "App::Widget::RadioButton",
override => 1,
value => $key,
)->html();
$html .= " </td>\n";
}
if ($#row_actions > -1) {
my (%args);
$html .= " <td bgcolor=\"$heading_bgcolor\">";
foreach $rowaction (@row_actions) {
%args = (
override => 1,
class => "App::Widget::ImageButton",
image_script => 'app-button',
volatile => 1,
height => 17,
width => 50,
bevel => 2,
);
$rowactiondef = $rowactiondefs->{$rowaction};
if ($rowactiondef) {
foreach (keys %$rowactiondef) {
$args{$_} = $rowactiondef->{$_};
}
}
$html .= $context->widget("$name.${rowaction}", %args, args
=> $key)->html();
}
$html .= "</td>\n";
}
for ($col = 0; $col < $numcols; $col++) {
$elem = $data->[$row][$col];
$column = "";
$format = "";
$scale_factor = "";
$align = "";
if (defined $columns && defined $columns->[$col]) {
$column = $columns->[$col];
$format = $view_column_defs->{$column}{format} ||
$table_column_defs->{$column}{format};
$scale_factor = $view_column_defs->{$column}{scale_factor} ||
$table_column_defs->{$column}{scale_factor};
$align = $view_column_defs->{$column}{align} ||
$table_column_defs->{$column}{align};
}
$elem_selected = 0;
if ($mode eq "edit") {
if (($self->{column_selected}{$column} &&
$self->{row_selected}{$key}) ||
($self->{column_selected}{$column} && (!defined
$self->{row_selected} || !%{$self->{row_selected}})) ||
((!defined $self->{column_selected} ||
!%{$self->{column_selected}}) && $self->{row_selected}{$key})) {
$elem_selected = 1;
}
}
if ($elem_selected) {
if (!defined $elem || $elem eq "") {
$elem = "";
$td_col_attrib = " align=\"left\"";
}
else {
$elem = $elem * $scale_factor if ($scale_factor);
if ($align) {
$td_col_attrib = " align=\"$align\"";
}
elsif ($elem =~ /^[-0-9.,%]+$/) {
$td_col_attrib = " align=\"right\"";
}
else {
$td_col_attrib = " align=\"left\"";
}
$elem = sprintf($format, $elem) if ($format);
}
if (! defined $self->{editdata}{$key}{$column}) {
$self->{editdata}{$key}{$column} = $elem
}
$html .= " <td $td_row_attrib$td_col_attrib>${elem_begin}";
$html .= $context->widget("$name\{editdata}{$key}{$column}",
class => "App::Widget::TextField",
size => $column_length[$col]+2, # add 2 just
to give some visual space
maxlength => 99,
background_color => "#ffaaaa",
border_style => "solid",
border_width => "1px",
padding => 0,
@edit_style,
)->html();
$html .= "$elem_end</td>\n";
}
else {
$elem = $self->html_escape($elem);
if (!defined $elem || $elem eq "") {
$elem = " ";
}
else {
$elem = $elem * $scale_factor if ($scale_factor);
$elem = sprintf($format, $elem) if ($format);
if ($align) {
$td_col_attrib = " align=\"$align\"";
}
elsif ($elem =~ /^[-0-9.,%]+$/) {
$td_col_attrib = " align=\"right\"";
}
else {
$td_col_attrib = " align=\"left\"";
}
}
$html .= "
<td$td_row_attrib$td_col_attrib>$elem_begin$elem$elem_end</td>\n";
}
}
$html .= "</tr>\n";
}
$html .= "</table>\n";
if (1) {
$html .= "<!-- SQL used in table query\n";
$html .= $rep->{sql};
$html .= "-->\n";
}
&App::sub_exit("<html ...>") if ($App::trace);
$html;
}
1;