App-Widget
view release on metacpan or search on metacpan
lib/App/Widget/DataTable.pm view on Meta::CPAN
######################################################################
## $Id: DataTable.pm 12437 2009-01-14 14:26:36Z spadkins $
######################################################################
package App::Widget::DataTable;
$VERSION = (q$Revision: 12437 $ =~ /(\d[\d\.]*)/)[0]; # VERSION numbers generated by svn
use App;
use App::Widget;
@ISA = ( "App::Widget" );
use strict;
=head1 NAME
App::Widget::DataTable - An HTML table which serves as a repository table viewer/editor
=head1 SYNOPSIS
use App::Widget::DataTable;
$name = "get_data";
$w = App::Widget::DataTable->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("DataTable->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("DataTable($name)->handle_event($wname,$event,@args)")
if ($App::DEBUG && $self->{context}->dbg(1));
lib/App/Widget/DataTable.pm view on Meta::CPAN
}
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::DataTable::html(@_);
}
sub html {
&App::sub_entry if ($App::trace);
my $self = shift;
$self->{context}->dbgprint("DataTable->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,
lib/App/Widget/DataTable.pm view on Meta::CPAN
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);
( run in 0.561 second using v1.01-cache-2.11-cpan-5735350b133 )