Author: spadkins
Date: Thu Oct 22 10:18:36 2009
New Revision: 13418

Modified:
   p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/DataTable.pm

Log:
new logic for sizeable, filter, edit

Modified: p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/DataTable.pm
==============================================================================
--- p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/DataTable.pm       
(original)
+++ p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/DataTable.pm       Thu Oct 
22 10:18:36 2009
@@ -57,19 +57,34 @@
     my $options           = $context->{options};
     my $html_url_dir      = $options->{html_url_dir} || "";
     my $ext_extension_dir = $options->{ext_extension_dir} || "/App";
+    my $ext_resources_dir = $options->{ext_resources_dir} || "";
 
     my ($response, $js, $css);
-    if ($lock_columns || $filterable) {
+    if ($filterable) {
+
         $response = $context->response() if (!$response);
-        $css = "${html_url_dir}${ext_extension_dir}/Ext.ux.ColumnLock.css";
-        $js  = "${html_url_dir}${ext_extension_dir}/Ext.ux.ColumnLock.js";
-        if (!$response->is_included("javascript", $js)) {
-            $response->include("css",        $css);
-            $response->include("javascript", $js);
-        }
-        $js = 
"${html_url_dir}${ext_extension_dir}/Ext.ux.grid.LockingGridHeaderFilters.js";
-        if (!$response->is_included("javascript", $js)) {
-            $response->include("javascript", $js);
+
+        $css = 
"${html_url_dir}${ext_resources_dir}/GridFilters/GridFilters.css";
+
+        if (!$response->is_included("css", $css)) {
+            $response->include("css", $css);
+        }
+
+        my @js = ( "${html_url_dir}${ext_extension_dir}/menu/EditableItem.js",
+                   "${html_url_dir}${ext_extension_dir}/menu/RangeMenu.js",
+                   "${html_url_dir}${ext_extension_dir}/grid/GridFilters.js",
+                   "${html_url_dir}${ext_extension_dir}/grid/filter/Filter.js",
+                   
"${html_url_dir}${ext_extension_dir}/grid/filter/StringFilter.js",
+                   
"${html_url_dir}${ext_extension_dir}/grid/filter/DateFilter.js",
+                   
"${html_url_dir}${ext_extension_dir}/grid/filter/ListFilter.js",
+                   
"${html_url_dir}${ext_extension_dir}/grid/filter/NumericFilter.js",
+                   
"${html_url_dir}${ext_extension_dir}/grid/filter/BooleanFilter.js"
+                 );
+
+        foreach my $java_script (@js) {
+            if (!$response->is_included("javascript", $java_script)) {
+                $response->include("javascript", $java_script);
+            }
         }
     }
 }
@@ -296,6 +311,129 @@
     &App::sub_exit() if ($App::trace);
 }
 
+sub create_filter_js {
+    &App::sub_entry if ($App::trace);
+    my ($self, $col_types) = @_;
+
+    my $js;
+    my %types = ( integer => 'numeric', datetime => 'string', text => 
'string', string => 'string', float => 'numeric' );
+
+    foreach my $col_type (@$col_types) {
+        my $type      = $types{$col_type->{type}} || 'string';
+        my $dataIndex = $col_type->{dataIndex};
+        $js .= "{type: '$type',  dataIndex: '$dataIndex'},\n";
+    }
+
+    $js =~ s/(.*?),\n$/$1/sg;
+
+    my $filter_js = <<EOF;
+        var filters = new Ext.ux.grid.GridFilters(
+            {
+                //local:true, // tell the filter plugin to use local data.
+                filters:[
+                    $js
+                ]
+            }
+        );
+EOF
+
+    &App::sub_exit($filter_js) if ($App::trace);
+    return $filter_js;
+}
+
+sub create_sizable_js {
+    &App::sub_entry if ($App::trace);
+    my ($self, $height, $width, $name) = @_;
+
+    my $sizable_js = <<EOF;
+        var win = new Ext.Window(
+            {
+                height: $height,
+                width: $width,
+                layout: 'fit',
+                closable:false,
+                items: grid
+            }
+        );
+        
+        win.show();
+        var myDiv = Ext.get('$name');
+        win.alignTo(myDiv); 
+EOF
+
+    &App::sub_exit($sizable_js) if ($App::trace);
+    return $sizable_js;
+}
+
+sub create_edit_js {
+    &App::sub_entry if ($App::trace);
+    my ($self) = @_;
+
+    my $edit_js = <<EOF;
+        sm: new Ext.grid.RowSelectionModel({
+            singleSelect: true
+        }),
+        listeners: {
+            afteredit: function() {
+               grid.stopEditing();
+               var changes = new Array();
+               var dirty = dataStore.getModifiedRecords();
+               var value; var col;
+               for ( var i = 0; i < dirty.length; i++ ) {
+                   var fields = dirty[i].getChanges();
+                   for(var n in fields){
+                       value = fields[n];
+                       col   = n;
+                   }
+                   changes.push(fields);
+               }
+               submitChanges(changes, col, value);
+               dataStore.commitChanges();
+            }
+        },
+EOF
+
+    &App::sub_exit($edit_js) if ($App::trace);
+    return $edit_js;
+}
+
+sub create_edit_submit_changes_js {
+    &App::sub_entry if ($App::trace);
+    my ($self, $table, $repository, $primary_key) = @_;
+
+    my $context        = $self->{context};
+    my $options        = $context->{options};
+    my $script_url_dir = $options->{script_url_dir}  || die "The parameter 
'script_url_dir' must be set in the option file";
+    my $script_url     = "$script_url_dir/App/app-ext-repository";
+
+    my $edit_submit_changes_js = <<EOF;
+    function submitChanges(data, col, value) {
+        var sm      = grid.getSelectionModel();
+        var records = sm.getSelections();
+        var r       = records[0];
+        var fields  = r.fields.keys;
+        var h = {};
+        for (var i = 0; i < fields.length; i++) {
+            if (fields[i] != col) {
+                h[fields[i]] = r.json[i];
+            }
+        }
+        //console.log(Ext.util.JSON.encode(data));
+        //console.log(Ext.util.JSON.encode(h));
+        Ext.Ajax.request({
+            url:        "$script_url",
+            success:    function() { dataStore.reload() },
+            params:     { modifiedRecord: Ext.util.JSON.encode(data), record: 
Ext.util.JSON.encode(h), table: '$table',
+                          repository: '$repository', primary_key: 
'$primary_key' }
+        });
+    }
+EOF
+
+    &App::sub_exit($edit_submit_changes_js) if ($App::trace);
+    return $edit_submit_changes_js;
+}
+
+
 sub html {
     &App::sub_entry if ($App::trace);
     my ($self) = @_;
@@ -310,40 +448,88 @@
     my $sortable   = $self->{sortable};
     my $filterable = $self->{filterable};
     my $editable   = $self->{editable};
+    my $sizable    = $self->{sizable};
 
     my $lock_columns = $self->{lock_columns};
 
     my $rep = $self->repository();
+    my $repository = $self->{repository} || 'default';
     my $tabledef = $rep->get_table_def($table);
+    my $primary_key = $tabledef->{primary_key};
+
+    if (ref $primary_key eq "ARRAY") {
+        $primary_key = $primary_key->[0];
+    }
 
     my $columns = $self->get_columns();
     my $columns_list = join(",", @$columns);
     my $column_data_defs = [];
     my $column_display_defs = [];
-    my ($column_data_def, $column_display_def, $label, $column);
+    my ($column_data_def, $column_display_def, $label, $column, $type, 
@col_types, $filter_js);
+    my ($col_width, $sizable_js, $edit_js, $edit_submit_changes_js);
+    my %edit_type = ( string => 'TextField', text => 'TextField', datetime => 
'TextField', integer => 'NumberField', float => 'NumberField' );
+
     for (my $i = 0; $i <= $#$columns; $i++) {
         $column = $columns->[$i];
-        $column_data_def = { name => $column, mapping => $i };
-        push(@$column_data_defs, $column_data_def);
+
+        $type  = $tabledef->{column}{$column}{type};
         $label = $tabledef->{column}{$column}{label} || $column;
         $label =~ s/<br>//g;
-        $column_display_def = { header => $label, width => 100, dataIndex => 
$column };
+
+        my $editor = $edit_type{$type} || 'TextField';
+
+        my $col_length = length($label);
+        if ($col_length >= 14) {
+            $col_width  = $col_length + 130;
+        }
+        else {
+            $col_width  = $col_length + 90;
+        }
+
+        if ($type eq "datetime") {
+            #$column_display_def = { header => $label, width => 100, dataIndex 
=> $column, renderer => "Ext.util.Format.dateRenderer('Y-m-d H:i:s')" };
+            #$column_data_def = { name => $column, mapping => $i, dateFormat 
=> 'Y-m-d H:i:s' };
+            $column_display_def = { header => $label, width => $col_width, 
dataIndex => $column };
+            $column_data_def = { name => $column, mapping => $i };
+        }
+        else {
+            $column_display_def = { header => $label, width => $col_width, 
dataIndex => $column };
+            $column_data_def = { name => $column, mapping => $i };
+        }
         $column_display_def->{sortable} = "true" if ($sortable);
-        $column_display_def->{filter} = {xtype => "textfield"} if 
($filterable);
+        $column_display_def->{editor}   = "new Ext.form.${editor}()" if 
($editable);
+        #$column_display_def->{filter} = {xtype => "textfield"} if 
($filterable);
+
         push(@$column_display_defs, $column_display_def);
+        push(@$column_data_defs,    $column_data_def);
+        push(@col_types,            {dataIndex => $column, type => $type});
     }
+
     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 $height      = $self->{height} || 500;
+    my $height      = $self->{height} || 490;
     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 $grid_panel_type = "Ext.grid.GridPanel";
+
+    if ($filterable) {
+        $filter_js = $self->create_filter_js(\...@col_types);
+    }
+
+    if ($editable) {
+        $grid_panel_type = "Ext.grid.EditorGridPanel";
+        $edit_js = $self->create_edit_js();
+        $edit_submit_changes_js = $self->create_edit_submit_changes_js($table, 
$repository, $primary_key);
+    }
+
     my ($html);
 
     if ($scrollable) {
@@ -358,12 +544,26 @@
         my $script_url     = "$script_url_dir/App/app-ext-repository";
         my $pagesize       = 100;
 
-        my (@plugins);
-        my $plugins_js = "";
-        if ($filterable || $lock_columns) {
-            push(@plugins, "Ext.ux.grid.LockingGridHeaderFilters");
+        my (@plugins, $plugins_js);
+        if ($filterable) {
+            push(@plugins, "filters");
+            $plugins_js .= "\n        plugins: " . join(",", @plugins). ",";
+        }
+
+        my $render_grid_js;
+        if ($sizable) {
+            $sizable_js = $self->create_sizable_js($height, $width, $name);
+            $render_grid_js = <<EOF;
+    dataStore.load({params: {start: 0, limit: $pagesize}});
+EOF
+        }
+        else {
+            $render_grid_js = <<EOF;
+    grid.render('$name');
+    dataStore.load({params: {start: 0, limit: $pagesize}});
+    grid.getSelectionModel().selectFirstRow();
+EOF
         }
-        $plugins_js .= "\n        plugins: [new " . join("(), new ", @plugins) 
. "()],";
 
         $html = <<EOF;
 <script type="text/javascript">
@@ -377,7 +577,7 @@
         totalProperty: 'totalCount',
         remoteSort: true,
         proxy: new Ext.data.HttpProxy({ url: '$script_url', method: 'POST' }),
-        baseParams: {table: '$table', columns: '$columns_list'$order_by_js}
+        baseParams: {table: '$table', repository: '$repository', columns: 
'$columns_list'$order_by_js}
     });
 
     var pagingBar = new Ext.PagingToolbar({
@@ -388,24 +588,25 @@
         emptyMsg: 'No data to display'
     });
 
+    $filter_js
+
     // create the Grid
-    var grid = new Ext.grid.GridPanel({
+    var grid = new $grid_panel_type ({
         id: '$name-grid',
         store: dataStore,$plugins_js
         columns: $js_column_display_defs,
         stripeRows: true,
         frame:  true,
-        // stateful: true,
         height: $height,
         width:  $width,
         title: '$table_label',
+        $edit_js
         bbar: pagingBar
     });
 
-    grid.render('$name');
-    dataStore.load({params: {start: 0, limit: $pagesize}});
-
-    grid.getSelectionModel().selectFirstRow();
+    $render_grid_js
+    $edit_submit_changes_js
+    $sizable_js
 });
 </script>
 <div id="$name"></div>

Reply via email to