Author: spadkins Date: Wed Mar 5 06:57:20 2008 New Revision: 10880 Added: p5ee/trunk/App-Widget-ExtJS/ p5ee/trunk/App-Widget-ExtJS/CHANGES p5ee/trunk/App-Widget-ExtJS/MANIFEST p5ee/trunk/App-Widget-ExtJS/MANIFEST.SKIP p5ee/trunk/App-Widget-ExtJS/META.yml p5ee/trunk/App-Widget-ExtJS/Makefile.PL p5ee/trunk/App-Widget-ExtJS/README (contents, props changed) p5ee/trunk/App-Widget-ExtJS/TODO p5ee/trunk/App-Widget-ExtJS/lib/ p5ee/trunk/App-Widget-ExtJS/lib/App/ p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/ p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS.pm p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/DataTable.pm p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/Date.pm p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/DualSelectWidget.pm p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/TabbedAppFrame.pm p5ee/trunk/App-Widget-ExtJS/t/ p5ee/trunk/App-Widget-ExtJS/t/main.t (contents, props changed)
Log: new Added: p5ee/trunk/App-Widget-ExtJS/CHANGES ============================================================================== --- (empty file) +++ p5ee/trunk/App-Widget-ExtJS/CHANGES Wed Mar 5 06:57:20 2008 @@ -0,0 +1,7 @@ +######################################### +# CHANGE LOG +######################################### + +VERSION 0.50 + o initial release + Added: p5ee/trunk/App-Widget-ExtJS/MANIFEST ============================================================================== --- (empty file) +++ p5ee/trunk/App-Widget-ExtJS/MANIFEST Wed Mar 5 06:57:20 2008 @@ -0,0 +1,8 @@ +CHANGES +lib/App/Widget/ExtJS.pm +Makefile.PL +MANIFEST +META.yml Module meta-data (added by MakeMaker) +README +t/main.t +TODO Added: p5ee/trunk/App-Widget-ExtJS/MANIFEST.SKIP ============================================================================== --- (empty file) +++ p5ee/trunk/App-Widget-ExtJS/MANIFEST.SKIP Wed Mar 5 06:57:20 2008 @@ -0,0 +1,12 @@ +~$ +^MANIFEST\. +^Makefile$ +^blib/ +^pm_to_blib$ +\.old$ +\.bak$ +\.cvsignore$ +\.tar\.gz$ +\.svn +htdocs/.exists +CVS/ Added: p5ee/trunk/App-Widget-ExtJS/META.yml ============================================================================== --- (empty file) +++ p5ee/trunk/App-Widget-ExtJS/META.yml Wed Mar 5 06:57:20 2008 @@ -0,0 +1,11 @@ +# http://module-build.sourceforge.net/META-spec.html +#XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# +name: App-Widget-ExtJS +version: 0.50 +version_from: +installdirs: site +requires: + App::Widget: 0 + +distribution_type: module +generated_by: ExtUtils::MakeMaker version 6.17 Added: p5ee/trunk/App-Widget-ExtJS/Makefile.PL ============================================================================== --- (empty file) +++ p5ee/trunk/App-Widget-ExtJS/Makefile.PL Wed Mar 5 06:57:20 2008 @@ -0,0 +1,22 @@ + +###################################################################### +## File: $Id: Makefile.PL 6707 2006-07-25 02:21:19Z spadkins $ +###################################################################### + +use ExtUtils::MakeMaker; +# See lib/ExtUtils/MakeMaker.pm for details of how to influence +# the contents of the Makefile that is written. + +%opts = ( + 'NAME' => 'App-Widget-ExtJS', + 'DISTNAME' => 'App-Widget-ExtJS', + 'VERSION' => '0.50', + 'PREREQ_PM' => { 'Alien::ExtJS' => 0, }, +); + +###################################################################### +# MAKE THE MAKEFILE +###################################################################### + +WriteMakefile(%opts); + Added: p5ee/trunk/App-Widget-ExtJS/README ============================================================================== --- (empty file) +++ p5ee/trunk/App-Widget-ExtJS/README Wed Mar 5 06:57:20 2008 @@ -0,0 +1,23 @@ +###################################################################### +## File: $Id: README 3468 2005-08-09 19:46:51Z spadkins $ +###################################################################### + +WHAT IS THIS? + +This is the App-Widget-ExtJS distribution. +It incorporates the JavaScripted ExtJS widgets + + http://www.extjs.com + +into the App-Widget world of the App-Context framework. + +HOW DO I INSTALL IT? + +To install this module, cd to the directory that contains this README +file and type the following: + + perl Makefile.PL + make + make test + make install + Added: p5ee/trunk/App-Widget-ExtJS/TODO ============================================================================== --- (empty file) +++ p5ee/trunk/App-Widget-ExtJS/TODO Wed Mar 5 06:57:20 2008 @@ -0,0 +1,7 @@ +###################################################################### +## File: $Id: TODO 3468 2005-08-09 19:46:51Z spadkins $ +###################################################################### + +To get to Version 1.0 + o tbd + Added: p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS.pm ============================================================================== --- (empty file) +++ p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS.pm Wed Mar 5 06:57:20 2008 @@ -0,0 +1,398 @@ + +###################################################################### +## $Id: ExtJS.pm 9649 2007-06-13 15:40:18Z spadkins $ +###################################################################### + +package App::Widget::ExtJS; +$VERSION = (q$Revision: 9649 $ =~ /(\d[\d\.]*)/)[0]; # VERSION numbers generated by svn + +use App::Widget; [EMAIL PROTECTED] = ( "App::Widget" ); + +use strict; + +=head1 NAME + +App::Widget::ExtJS - Dynamic, client-side widgets for the App-Context Framework using the ExtJS Javascript distribution + +=head1 SYNOPSIS + + use App::Widget::ExtJS; + + ... + +=cut + +sub _init { + &App::sub_entry if ($App::trace); + my ($self) = @_; + $self->init_js(); + $self->SUPER::_init(); + &App::sub_exit() if ($App::trace); +} + +sub serialize_as_javascript { + &App::sub_entry if ($App::trace); + my ($self, $value) = @_; + my $modified_value; + my ($val, $oneline); + if (ref ($value) eq 'ARRAY') { + $oneline = ($#$value > -1 && ref($value->[0])) ? 0 : 1; + $modified_value .= "["; + $modified_value .= "\n " if (!$oneline); + for (my $i = 0; $i <= $#$value; $i++) { + $val = $value->[$i]; + if (ref($val)) { + $modified_value .= $self->serialize_as_javascript($val); + } + elsif ($val =~ /^(false|true)$/) { + $modified_value .= "$val"; + } + elsif ($val =~ /^-?[0-9]+\.?[0-9]*$/) { + $modified_value .= "$val"; + } + else { + $modified_value .= "'$val'"; + } + $modified_value .= "," if ($i < $#$value); + $modified_value .= "\n" if (!$oneline); + $modified_value .= " " if (!$oneline && $i < $#$value); + } + $modified_value .= "]"; + $modified_value .= "\n " if (!$oneline); + } + elsif (ref($value) eq 'HASH') { + $modified_value .= "{"; + foreach my $key (keys %$value) { + $val = $value->{$key}; + if ($key =~ /^[a-zA-Z_][a-zA-Z0-9_]*$/) { + $modified_value .= "$key : "; + } + else { + $modified_value .= "\"$key\" : "; + } + if(ref($val) eq 'HASH') { + $modified_value .= $self->serialize_as_javascript($val); + } + elsif ($val =~ /^(false|true)$/) { + $modified_value .= $val; + } + elsif ($val =~ /^-?[0-9]+\.?[0-9]*$/) { + $modified_value .= $val; + } + else { + $modified_value .= "'$val'"; + } + $modified_value .= ", "; + } + + $modified_value =~ s/, *$//; + $modified_value .= "}"; + } + + $modified_value =~ s/[,\s\n]*$//s; + &App::sub_exit() if ($App::trace); + return $modified_value; + +} + +sub html { + &App::sub_entry if ($App::trace); + my $self = shift; + my $name = $self->{name}; + my $context = $self->{context}; + + my %js_special = ( attrib => 1, hidden => 1, include_value_domain => 1, value_domain => 1, domain => 1, conf => 1, values_labels => 1 ); + my (@attrib); + foreach my $key (keys %$self) { + if ($key =~ /^js_(.+)/) { + push(@attrib, $1, $self->{$key}) if (!$js_special{$1}); + } + } + if (! defined $self->{js_submittable} || $self->{js_submittable}) { + push(@attrib, "submittable", 1); + } + my $value = $context->so_get($name); + $value = "" if (!defined $value); + $value = join(",",@$value) if (ref($value) eq "ARRAY"); + push(@attrib, "default", $value); + my $js_conf = ""; + my ($var, $val); + if ($#attrib > -1) { + $js_conf .= ", {" if (!$js_conf); + for (my $i = 0; $i < $#attrib; $i += 2) { + $js_conf .= "," if ($i > 0); + $var = $attrib[$i]; + $val = $attrib[$i+1]; + if (ref($val)) { + $js_conf .= " \"$var\" : " . $self->serialize_as_javascript($val); + } + else { + $js_conf .= " \"$var\" : \"" . $self->escape_double_quoted_value($val) . "\""; + } + } + } + if ($self->{js_conf}) { + $js_conf .= ($js_conf) ? ",\n" : ", {\n"; + $js_conf .= $self->{js_conf}; + } + + if (defined $self->{js_attrib}) { + my ($value, $so_name); + my $attribs = $self->{js_attrib}; + foreach my $attrib (sort keys %$attribs) { + $so_name = $attribs->{$attrib}; + $so_name = $attrib if (!$so_name || $so_name eq "1"); + $value = $context->so_get($so_name); + $value = join(",",@$value) if (ref($value) eq "ARRAY"); + $js_conf .= ",\n \"$attrib\" : \"" . $self->escape_double_quoted_value($value) . "\""; + } + } + + if (defined $self->{js_value_domain}) { + my $value_domain_name = $self->{js_value_domain}; + $self->include_value_domain($value_domain_name); + $js_conf .= ",\n \"domain\" : \"$value_domain_name\""; + } + + if (defined $self->{js_include_value_domain}) { + foreach my $value_domain_name (@{$self->{js_include_value_domain}}) { + $self->include_value_domain($value_domain_name); + } + } + + if (defined $self->{js_domain}) { + my ($value_domain, $values, $labels, $domain_alias); + my ($values_text, $labels_text, $i); + foreach my $domain_name (sort keys %{$self->{js_domain}}) { + + $domain_alias = $self->{js_domain}{$domain_name}; + $domain_alias = $domain_name if (!$domain_alias || $domain_alias eq "1"); + + $value_domain = $context->value_domain($domain_name); + ($values, $labels) = $value_domain->values_labels(); + + $values_text = ""; + $labels_text = ""; + + if ($#$values > -1) { + $values_text = ",\n \"${domain_alias}_values\" : ["; + for ($i = 0; $i <= $#$values; $i++) { + $values_text .= "," if ($i > 0); + $values_text .= "\n " if ($i % 10 == 0); + $values_text .= " \"$values->[$i]\""; + } + $values_text .= "\n ]"; + + if ($labels && %$labels) { + $labels_text = ",\n \"${domain_alias}_labels\" : {"; + for ($i = 0; $i <= $#$values; $i++) { + next if (! defined $labels->{$values->[$i]}); + $labels_text .= "," if ($i > 0); + $labels_text .= "\n " if ($i % 10 == 0); + $labels_text .= " \"$values->[$i]\" : \"$labels->{$values->[$i]}\""; + } + $labels_text .= "\n }"; + } + } + else { + $values_text = ",\n \"${domain_alias}_values\" : [ ]"; + $labels_text = ",\n \"${domain_alias}_labels\" : { }"; + } + $js_conf .= $values_text; + $js_conf .= $labels_text; + } + } + + if ($self->{js_values_labels}) { + my ($values, $labels) = $self->values_labels(); + my ($values_text, $i); + my $labels_text = ""; + + if ($#$values > -1) { + $values_text = ",\n \"values\" : ["; + for ($i = 0; $i <= $#$values; $i++) { + $values_text .= "," if ($i > 0); + $values_text .= "\n " if ($i % 10 == 0); + $values_text .= " \"$values->[$i]\""; + } + $values_text .= "\n ]"; + + if ($labels && %$labels) { + $labels_text = ",\n \"labels\" : {"; + for ($i = 0; $i <= $#$values; $i++) { + next if (! defined $labels->{$values->[$i]}); + $labels_text .= "," if ($i > 0); + $labels_text .= "\n " if ($i % 10 == 0); + $labels_text .= " \"$values->[$i]\" : \"$labels->{$values->[$i]}\""; + } + $labels_text .= "\n }"; + } + } + else { + $values_text = ",\n values : [ ]"; + } + $js_conf .= $values_text; + $js_conf .= $labels_text; + } + + if ($js_conf) { + $js_conf .= " }"; + } + + my $html = <<EOF; +<script type="text/javascript"> + document.write("$name"); +</script> +EOF + if ($self->{js_hidden}) { + my ($vars, @vars); + $vars = $self->{js_hidden}; + if (ref($vars) eq "ARRAY") { + @vars = @$vars; + } + elsif ($vars =~ /,/) { + @vars = split(/,/, $vars); + } + else { + @vars = ($vars); + } + foreach my $var (@vars) { + $value = $self->escape_html_attribute_value($context->so_get($var)); + my $hidden_input = "<input type=\"hidden\" name=\"${var}\" value=\"$value\" />\n"; + $html = $hidden_input . $html; + } + } + + &App::sub_exit($html) if ($App::trace); + return($html); +} + +sub escape_double_quoted_value { + my ($self, $value) = @_; + $value =~ s/"/\\"/g; + $value =~ s/\r//msg; + $value =~ s/\n/\\n/msg; + return($value); +} + +sub escape_html_attribute_value { + my ($self, $value) = @_; + if (!defined $value) { + $value = ""; + } + # I'm not exactly sure that this is the right way to escape special characters + # *within* an HTML attribute value. + elsif ($value =~ /[\&<>"]/) { + $value =~ s/\&/\&/g; + $value =~ s/</\</g; + $value =~ s/>/\>/g; + $value =~ s/"/\"/g; + } + return($value); +} + +sub init_js { + &App::sub_entry if ($App::trace); + my ($self) = @_; + my $context = $self->{context}; + my $options = $context->{options}; + + my $html_url_dir = $options->{html_url_dir} || die "The parameter 'html_url_dir' must be set in the option file"; + my $version = $options->{extjs_version} || die "The parameter 'extjs_version' must be set in the option file"; + if ($version !~ /^ext-[0-9.]+$/) { + die "The parameter 'extjs_version' in the option file must be of a form similar to 'ext-2.0.1'"; + } + my $debug = $options->{extjs_debug}; + my $adapter = $options->{extjs_adapter} || "ext"; # ext, jquery, prototype, yui + + my $response = $context->response(); + + my $js = $debug ? "$html_url_dir/$version/ext-all-debug.js" : "$html_url_dir/$version/ext-all.js"; + if (!$response->is_included("javascript", $js)) { + $response->include("css", "$html_url_dir/$version/resources/css/ext-all.css"); + my $js_conf = $self->javascript_conf(); + $response->include("javascript", $js_conf); + my $adapter_js = "$html_url_dir/$version/adapter/ext/ext-base.js"; + if ($adapter ne "ext") { + $adapter_js = "$html_url_dir/$version/adapter/$adapter/ext-${adapter}-adapter.js"; + } + $response->include("javascript", $adapter_js); + $response->include("javascript", $js); + } + + &App::sub_exit() if ($App::trace); +} + +sub include_value_domain { + &App::sub_entry if ($App::trace); + my ($self, $value_domain_name) = @_; + my $context = $self->{context}; + my $response = $context->response(); + my $javascript_key = "ValueDomain($value_domain_name)"; + if (!$response->is_included("javascript", $javascript_key)) { + my $value_domain = $context->value_domain($value_domain_name); + my ($values, $labels) = $value_domain->values_labels(); + my $values_text = ""; + my $labels_text = ""; + my ($i); + if ($#$values > -1) { + $values_text = ",\n \"values\" : ["; + for ($i = 0; $i <= $#$values; $i++) { + $values_text .= "," if ($i > 0); + $values_text .= "\n " if ($i % 10 == 0); + $values_text .= " \"$values->[$i]\""; + } + $values_text .= "\n ]"; + + if ($labels && %$labels) { + $labels_text = ",\n \"labels\" : {"; + for ($i = 0; $i <= $#$values; $i++) { + next if (! defined $labels->{$values->[$i]}); + $labels_text .= "," if ($i > 0); + $labels_text .= "\n " if ($i % 10 == 0); + $labels_text .= " \"$values->[$i]\" : \"$labels->{$values->[$i]}\""; + } + $labels_text .= "\n }"; + } + } + else { + $values_text = ",\n \"values\" : [ ]"; + $labels_text = ",\n \"labels\" : { }"; + } + my $js = <<EOF; +<script type="text/javascript" language="JavaScript"> +context.valueDomain("$value_domain_name", { + serviceClass : "ValueDomain"$values_text$labels_text +}); +</script> +EOF + $response->include("javascript", $js, $javascript_key); + } + &App::sub_exit() if ($App::trace); +} + +sub javascript_conf { + &App::sub_entry if ($App::trace); + my ($self) = @_; + my $context = $self->{context}; + my $options = $context->options(); + my $html_url_dir = $options->{html_url_dir}; + my $script_url_dir = $options->{script_url_dir}; + my $js = $options->{js_init}; + if (!$js) { + $js = <<EOF; +<script type="text/javascript" language="JavaScript"> + var appOptions = { + urlDocRoot : "$html_url_dir", + urlScriptRoot : "$script_url_dir" + }; +</script> +EOF + } + &App::sub_exit($js) if ($App::trace); + return($js); +} + +1; + Added: p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/DataTable.pm ============================================================================== --- (empty file) +++ p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/DataTable.pm Wed Mar 5 06:57:20 2008 @@ -0,0 +1,356 @@ + +###################################################################### +## $Id: DataTable.pm 3681 2006-03-13 19:55:12Z spadkins $ +###################################################################### + +package App::Widget::ExtJS::DataTable; +$VERSION = (q$Revision: 3681 $ =~ /(\d[\d\.]*)/)[0]; # VERSION numbers generated by svn + +use App::Widget::ExtJS; [EMAIL PROTECTED] = ( "App::Widget::ExtJS" ); + +use strict; + +=head1 NAME + +App::Widget::ExtJS::DataTable - A data table widget + +=head1 SYNOPSIS + + use App::Widget::ExtJS::DataTable; + + ... + +=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("DataTable->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("DataTable->get_headings(): column=$column(",$#$columns,") heading=$heading(",$#$headings,")") + if ($App::DEBUG >= 6 && $self->{context}->dbg(6)); + } + } + $self->{context}->dbgprint("DataTable->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) = @_; + $self->{context}->dbgprint("DataTable->get_data()") + if ($App::DEBUG && $self->{context}->dbg(1)); + my ($data); + $data = $self->{data}; + if (!defined $data) { + $self->load(); + $data = $self->{data}; + } + &App::sub_exit($data) if ($App::trace); + return $data; +} + +sub load { + &App::sub_entry if ($App::trace); + my ($self) = @_; + $self->{context}->dbgprint("DataTable->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("DataTable->load(): get_rows($table,c=$columns,p=$params,pv=$paramvalues,oc=$order_by,$startrow,$endrow,$direction);"); + $self->{context}->dbgprint("DataTable->load(): columns=[", join(",", @$columns), "]") if (ref($columns) eq "ARRAY"); + $self->{context}->dbgprint("DataTable->load(): params=[", join(",", @$params), "]") if (ref($params) eq "ARRAY"); + $self->{context}->dbgprint("DataTable->load(): paramvalues=[", join(",", %$paramvalues), "]") if (ref($paramvalues) eq "HASH"); + $self->{context}->dbgprint("DataTable->load(): order_by=[", join(",", @$order_by), "]") if (ref($order_by) eq "ARRAY"); + $self->{context}->dbgprint("DataTable->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 $rep = $self->repository(); + my $tabledef = $rep->get_table_def($table); + + my $data = $self->get_data(); + my $js_data = $self->serialize_as_javascript($data); + + 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 }; + push(@$column_data_defs, $column_data_def); + $label = $tabledef->{column}{$column}{label} || $column; + $label =~ s/<br>//g; + $column_display_def = { header => $label, sortable => "true", width => 100, dataIndex => $column }; + push(@$column_display_defs, $column_display_def); + } + 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 $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 $html = <<EOF; +<script type="text/javascript"> +Ext.onReady(function(){ + + // Ext.state.Manager.setProvider(new Ext.state.CookieProvider()); + + var data = $js_data; + + // create the data store + var dataStore = new Ext.data.SimpleStore({ + fields: $js_column_data_defs + }); + dataStore.loadData(data); + + // create the Grid + var grid = new Ext.grid.GridPanel({ + store: dataStore, + columns: $js_column_display_defs, + stripeRows: true, + frame: true, + // stateful: true, + height: $height, + width: $width, + title: '$table_label' + }); + + grid.render('$name'); + + grid.getSelectionModel().selectFirstRow(); +}); +</script> +<div id="$name"></div> +EOF + + &App::sub_exit("<html...>") if ($App::trace); + return($html); +} + +1; + Added: p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/Date.pm ============================================================================== --- (empty file) +++ p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/Date.pm Wed Mar 5 06:57:20 2008 @@ -0,0 +1,50 @@ + +###################################################################### +## $Id: Date.pm 3681 2006-03-13 19:55:12Z spadkins $ +###################################################################### + +package App::Widget::ExtJS::Date; +$VERSION = (q$Revision: 3681 $ =~ /(\d[\d\.]*)/)[0]; # VERSION numbers generated by svn + +use App::Widget::ExtJS; [EMAIL PROTECTED] = ( "App::Widget::ExtJS" ); + +use strict; + +=head1 NAME + +App::Widget::ExtJS::Date - A date widget + +=head1 SYNOPSIS + + use App::Widget::ExtJS::Date; + + ... + +=cut + +sub html { + my $self = shift; + my $name = $self->{name}; + + $self->init_js(); + + my $context = $self->{context}; + my $value = $context->so_get($name); + $value = "" if (!defined $value); + + my $html = <<EOF; +<script type="text/javascript"> + context.widget("$name", { + "serviceClass" : "DateWidget", + "submittable" : 1, + "default" : "$value" + }).write(); +</script> +EOF + + return($html); +} + +1; + Added: p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/DualSelectWidget.pm ============================================================================== --- (empty file) +++ p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/DualSelectWidget.pm Wed Mar 5 06:57:20 2008 @@ -0,0 +1,98 @@ + +###################################################################### +## $Id: DualSelectWidget.pm 8534 2007-01-10 00:14:39Z spadkins $ +###################################################################### + +package App::Widget::ExtJS::DualSelectWidget; +$VERSION = (q$Revision: 8534 $ =~ /(\d[\d\.]*)/)[0]; # VERSION numbers generated by svn + +use App::Widget::ExtJS; [EMAIL PROTECTED] = ( "App::Widget::ExtJS" ); + +use strict; + +=head1 NAME + +App::Widget::ExtJS::DualSelectWidget - An ordered multi-select widget made up of two HTML <select> tags and four buttons, +enhanced by JavaScript + +=head1 SYNOPSIS + + use App::Widget::ExtJS::DualSelectWidget; + + ... + +=cut + +sub html { + my $self = shift; + my $name = $self->{name}; + + $self->init_js(); + + my $extra_attribs = ""; + $extra_attribs .= ",\n \"size\" : $self->{size}" if ($self->{size}); + $extra_attribs .= ",\n \"maxselected\" : $self->{maxselected}" if ($self->{maxselected}); + + if (defined $self->{js_include_value_domain}) { + foreach my $value_domain_name (@{$self->{js_include_value_domain}}) { + $self->include_value_domain($value_domain_name); + } + } + + my $values_text = ""; + my $labels_text = ""; + + if ($self->{domain}) { + $self->include_value_domain($self->{domain}); + $extra_attribs .= ",\n \"domain\" : \"$self->{domain}\""; + } + else { + my ($values, $labels) = $self->values_labels(); + my ($i); + + if ($#$values > -1) { + $values_text = ",\n \"values\" : ["; + for ($i = 0; $i <= $#$values; $i++) { + $values_text .= "," if ($i > 0); + $values_text .= "\n " if ($i % 10 == 0); + $values_text .= " \"$values->[$i]\""; + } + $values_text .= "\n ]"; + + if ($labels && %$labels) { + $labels_text = ",\n \"labels\" : {"; + for ($i = 0; $i <= $#$values; $i++) { + next if (! defined $labels->{$values->[$i]}); + $labels_text .= "," if ($i > 0); + $labels_text .= "\n " if ($i % 10 == 0); + $labels_text .= " \"$values->[$i]\" : \"$labels->{$values->[$i]}\""; + } + $labels_text .= "\n }"; + } + } + else { + $values_text = ",\n values : [ ]"; + } + } + my $context = $self->{context}; + my $value = $context->so_get($name); + $value = "" if (!defined $value); + + my $class = $self->{js_serviceClass} || 'DualSelectWidget'; + + my $html = <<EOF; +<script type="text/javascript"> + context.widget("$name", { + "serviceClass" : "$class", + "submittable" : 1, + "default" : "$value"$extra_attribs$values_text$labels_text + }).write(); +</script> +EOF + + return($html); +} + +1; + Added: p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/TabbedAppFrame.pm ============================================================================== --- (empty file) +++ p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/TabbedAppFrame.pm Wed Mar 5 06:57:20 2008 @@ -0,0 +1,72 @@ + +###################################################################### +## $Id: TabbedAppFrame.pm 5896 2006-04-11 17:47:00Z spadkins $ +###################################################################### + +package App::Widget::ExtJS::TabbedAppFrame; +$VERSION = (q$Revision: 5896 $ =~ /(\d[\d\.]*)/)[0]; # VERSION numbers generated by svn + +use App; +use App::Widget::TabbedAppFrame; +use App::Widget::ExtJS; [EMAIL PROTECTED] = ( "App::Widget::TabbedAppFrame", "App::Widget::ExtJS" ); + +use strict; + +=head1 NAME + +App::Widget::ExtJS::TabbedAppFrame - An application frame. + +=head1 SYNOPSIS + + $name = "office"; + + # official way + use Widget; + $context = App->context(); + $w = $context->widget($name); + + # internal way + use App::Widget::ExtJS::TabbedAppFrame; + $w = App::Widget::ExtJS::TabbedAppFrame->new($name); + +=cut + +###################################################################### +# CONSTANTS +###################################################################### + +###################################################################### +# ATTRIBUTES +###################################################################### + +# INPUTS FROM THE ENVIRONMENT + +=head1 DESCRIPTION + +This class implements an application frame. +This includes a menu, an application toolbar, a screen selector, +a screen title, a screen toolbar, and +a screen frame. The application is actually implemented by the set +of screens that the application frame is configured to allow navigation +to. + +The application frame can implement itself in frames if it is +configured to do so. Otherwise, it implements itself as a table. + +=cut + +###################################################################### +# OUTPUT METHODS +###################################################################### + +sub _init { + &App::sub_entry if ($App::trace); + my $self = shift; + $self->SUPER::_init(@_); + $self->init_js(); + &App::sub_exit() if ($App::trace); +} + +1; + Added: p5ee/trunk/App-Widget-ExtJS/t/main.t ============================================================================== --- (empty file) +++ p5ee/trunk/App-Widget-ExtJS/t/main.t Wed Mar 5 06:57:20 2008 @@ -0,0 +1,11 @@ +#!/usr/local/bin/perl -w + +use Test::More qw(no_plan); +use lib "lib"; +use lib "../lib"; + +use strict; + +ok(1, "no tests"); +exit(0); +
