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>