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

Reply via email to