Author: spadkins
Date: Wed Apr 16 07:22:31 2008
New Revision: 11091
Added:
p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/SummaryDataTable.pm
(contents, props changed)
Log:
A data table capable of grouping and summarizing data.
Added: p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/SummaryDataTable.pm
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/SummaryDataTable.pm
Wed Apr 16 07:22:31 2008
@@ -0,0 +1,450 @@
+
+######################################################################
+## $Id: SummaryDataTable.pm 3681 2006-03-13 19:55:12Z spadkins $
+######################################################################
+
+package App::Widget::ExtJS::SummaryDataTable;
+$VERSION = (q$Revision: 3681 $ =~ /(\d[\d\.]*)/)[0]; # VERSION numbers
generated by svn
+
+use App::Widget::ExtJS;
[EMAIL PROTECTED] = ( "App::Widget::ExtJS" );
+
+use strict;
+use Data::Dumper;
+
+=head1 NAME
+
+App::Widget::ExtJS::SummaryDataTable - A data table widget
+
+=head1 SYNOPSIS
+
+ use App::Widget::ExtJS::SummaryDataTable;
+
+ ...
+
+=cut
+
+sub _init {
+ &App::sub_entry if ($App::trace);
+ my ($self) = @_;
+ $self->SUPER::_init(@_);
+ $self->{table} = $self->{name} if (!$self->{table});
+
+ if (!$self->{keycolidx}) {
+ my $context = $self->{context};
+ my $table = $self->{table};
+ my $rep = $self->{repository};
+ my $r = $context->repository($rep);
+ $r->_load_table_metadata($table);
+ my $primary_key = $r->{table}{$table}{primary_key};
+ if ($primary_key && ref($primary_key) eq "ARRAY" && $#$primary_key >
-1) {
+ my (@keycolidx, %colidx);
+ my $columns = $self->get_columns();
+ for (my $col = 0; $col <= $#$columns; $col++) {
+ $colidx{$columns->[$col]} = $col;
+ }
+ for (my $col = 0; $col <= $#$primary_key; $col++) {
+ if (defined $colidx{$primary_key->[$col]}) {
+ push(@keycolidx, $colidx{$primary_key->[$col]});
+ }
+ }
+ $self->{keycolidx} = [EMAIL PROTECTED] if ($#keycolidx ==
$#$primary_key);
+ }
+ }
+}
+
+sub repository {
+ &App::sub_entry if ($App::trace);
+ my ($self) = @_;
+ my $repname = $self->{repository};
+ my $context = $self->{context};
+ my $rep = $context->repository($repname);
+ &App::sub_exit($rep) if ($App::trace);
+ return($rep);
+}
+
+sub get_columns {
+ &App::sub_entry if ($App::trace);
+ my ($self) = @_;
+ my ($columns);
+ $columns = $self->{columns};
+ if (defined $columns && ref($columns) eq "") {
+ $columns = [ $columns ];
+ $self->set("columns", $columns);
+ }
+ if (!defined $columns) {
+ my $rep = $self->repository();
+ my $table = $self->{table};
+ 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) = @_;
+ $self->{context}->dbgprint("SummaryDataTable->get_headings()")
+ if ($App::DEBUG && $self->{context}->dbg(1));
+ my ($table, $headings, $heading, $columns, $column, $lang);
+ $table = $self->{table};
+ $columns = $self->get_columns();
+ $headings = $self->{headings};
+ $lang = $self->{lang};
+ my $column_attribs = $self->{column} || {};
+ if (!defined $headings) {
+ $headings = [];
+ my ($rep, $columnlabels);
+ $rep = $self->repository();
+ $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("SummaryDataTable->get_headings():
column=$column(",$#$columns,") heading=$heading(",$#$headings,")")
+ if ($App::DEBUG >= 6 && $self->{context}->dbg(6));
+ }
+ }
+ $self->{context}->dbgprint("SummaryDataTable->get_headings(): columns=[",
join(",", @{$self->get("columns",[])}), "]")
+ if ($App::DEBUG && $self->{context}->dbg(1));
+ &App::sub_exit($headings) if ($App::trace);
+ return($headings);
+}
+
+sub get_data {
+ &App::sub_entry if ($App::trace);
+ my ($self, $columns) = @_;
+ $self->{context}->dbgprint("SummaryDataTable->get_data()")
+ if ($App::DEBUG && $self->{context}->dbg(1));
+ my ($data);
+
+ $data = $self->{data};
+ if (!defined $data) {
+ $self->load();
+ $data = $self->{data};
+ }
+
+ my $csize = @$columns;
+
+ if (defined $data) {
+ my @tmp;
+
+ for my $row (@$data) {
+ my $data_def;
+
+ for (my $i=0; $i < $csize; $i++) {
+ $data_def->[EMAIL PROTECTED] = @$row[$i];
+ }
+ push(@tmp, $data_def);
+ }
+
+ $data = [EMAIL PROTECTED];
+ }
+
+ &App::sub_exit($data) if ($App::trace);
+ return $data;
+}
+
+sub get_functions {
+ &App::sub_entry if ($App::trace);
+ my ($self) = @_;
+ my ($functions);
+ $functions = $self->{functions};
+ if (defined $functions && ref($functions) eq "") {
+ $functions = [ $functions ];
+ $self->set("functions", $functions);
+ }
+
+ $functions = [] if (!defined $functions || ref($functions) eq "");
+ &App::sub_exit($functions) if ($App::trace);
+ $functions;
+}
+
+sub load {
+ &App::sub_entry if ($App::trace);
+ my ($self) = @_;
+ $self->{context}->dbgprint("SummaryDataTable->load()")
+ if ($App::DEBUG && $self->{context}->dbg(1));
+ my ($context, $rep, $rows, $table, $columns, $sql, $error, $data);
+ my ($params, $paramvalues, $param, $paramvalue, @paramvalues);
+ my ($startrow, $maxrows, $endrow, $keycolidx);
+ my (%paramvalues, $filter, $column);
+
+ $rep = $self->repository();
+ return if (! defined $rep);
+
+ $sql = $self->{sql};
+ $data = $self->{data};
+
+ if ($sql) {
+ $paramvalues = $self->substitute($self->{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->{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->{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->{order_by} || $self->{ordercols}; #
ordercols is deprecated in favor of order_by
+ my $group_by = $self->{group_by};
+ my $direction = $self->{direction} || $self->{directions} || {}; #
directions is deprecated in favor of direction
+ $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("SummaryDataTable->load():
get_rows($table,c=$columns,p=$params,pv=$paramvalues,oc=$order_by,$startrow,$endrow,$direction);");
+ $self->{context}->dbgprint("SummaryDataTable->load(): columns=[",
join(",", @$columns), "]") if (ref($columns) eq "ARRAY");
+ $self->{context}->dbgprint("SummaryDataTable->load(): params=[",
join(",", @$params), "]") if (ref($params) eq "ARRAY");
+ $self->{context}->dbgprint("SummaryDataTable->load():
paramvalues=[", join(",", %$paramvalues), "]") if (ref($paramvalues) eq "HASH");
+ $self->{context}->dbgprint("SummaryDataTable->load(): order_by=[",
join(",", @$order_by), "]") if (ref($order_by) eq "ARRAY");
+ $self->{context}->dbgprint("SummaryDataTable->load():
directions={", join(",", %$direction), "}") if (ref($direction) eq "HASH");
+ }
+
+ $rows = $rep->get_rows($table, \%paramvalues, $columns,
+ {order_by => $order_by, startrow => $startrow, endrow => $endrow,
direction => $direction, 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 html {
+ &App::sub_entry if ($App::trace);
+ my ($self) = @_;
+ my $name = $self->{name};
+
+ my $context = $self->{context};
+ my $value = $context->so_get($name);
+ $value = "" if (!defined $value);
+ my $table = $self->{table} || "unknown";
+
+ my $ext_columns = $self->{ext_columns};
+ my $ext_data = $self->{ext_data};
+
+ my $serialized_columns = $self->serialize_as_javascript($ext_columns);
+ my $serialized_data = $self->serialize_as_javascript($ext_data);
+
+ my $rep = $self->repository();
+ my $tabledef = $rep->get_table_def($table);
+
+
+ my $columns = $self->get_columns();
+ my $column_data_defs = [];
+ my $column_display_defs = [];
+ my ($column_data_def, $column_display_def, $label);
+
+ foreach my $column (@$columns) {
+ $column_data_def = { name => $column };
+ $label = $self->{column}{$column}{label} || $column;
+ $label =~ s/<br>//g;
+
+ my $display_defs = $self->{column}{$column};
+
+ $column_display_def = { header => $label, dataIndex => $column };
+
+ my $n = 0;
+
+ while ( my ($name, $value) = each(%$display_defs) ) {
+ $column_display_def->{$name} = $value if ($name ne 'label' &&
$name ne 'dataIndex' && $name ne 'type');
+ $column_data_def->{$name} = $value if ($name eq 'type');
+ }
+
+ push(@$column_data_defs, $column_data_def);
+ push(@$column_display_defs, $column_display_def);
+ }
+
+ my $data = $self->get_data($columns);
+
+ my $js_data = $self->serialize_as_javascript($data);
+ my $js_column_data_defs =
$self->serialize_as_javascript($column_data_defs);
+ my $js_column_display_defs =
$self->serialize_as_javascript($column_display_defs);
+
+ my $group_field = $self->{group_field};
+ my $sort_field = $self->{sort_field};
+ my $sort_dir = $self->{sort_dir};
+ my $height = $self->{height} || 500;
+ my $width = $self->{width} || 800;
+ my $table_label = $self->{label} || $tabledef->{label};
+ if (!$table_label) {
+ $table_label = lc($table);
+ $table_label =~ s/_/ /g;
+ $table_label = ucfirst($table_label);
+ }
+
+ my $functions = $self->get_functions();
+
+ my $function_html = '';
+
+ while ( my ($fname, $fvalue) = each(%$functions) ) {
+ $function_html .= "var $fname = $fvalue\n";
+ }
+
+ my $html = <<EOF;
+<script type="text/javascript">
+Ext.onReady(function(){
+
+ Ext.QuickTips.init();
+
+ var xg = Ext.grid;
+
+
+ var reader = new Ext.data.JsonReader({
+ fields: $js_column_data_defs
+ });
+
+ $function_html
+
+ var summary = new Ext.grid.GroupSummary();
+
+ // summary.Calculations['test'] = function(v, record, field, data) {
return v; };
+ Ext.grid.GroupSummary.Calculations ['test'] = function(v, record, field,
data) { return v; };
+
+ var data = $js_data;
+
+ var dataStore = new Ext.data.GroupingStore({
+ reader: reader,
+ sortInfo:{field: '$sort_field', direction: '$sort_dir'},
+ groupField:'$group_field'
+ });
+ dataStore.loadData(data);
+
+ var grid = new xg.GridPanel({
+ ds: dataStore,
+ columns: $js_column_display_defs,
+
+ view: new Ext.grid.GroupingView({
+ forceFit:true,
+ showGroupName: false,
+ enableNoGroups:false,
+ hideGroupedColumn: true
+ }),
+
+ plugins: summary,
+
+ frame:true,
+ width: $width,
+ height: $height,
+ clicksToEdit: 1,
+ collapsible: true,
+ animCollapse: false,
+ trackMouseOver: true,
+ enableColumnMove: true,
+ title: '$table_label',
+ iconCls: 'icon-grid',
+ autoScroll: true,
+ autoHeight: true,
+ autoWidth: false,
+ });
+
+ grid.render('$name');
+ grid.getSelectionModel().selectFirstRow();
+});
+</script>
+<div id="$name"></div>
+EOF
+
+ &App::sub_exit("<html...>") if ($App::trace);
+ return($html);
+}
+1;
\ No newline at end of file