added: DataTable asset
This commit is contained in:
parent
828930d193
commit
3e1f66a0e7
9 changed files with 1638 additions and 0 deletions
BIN
docs/upgrades/packages-7.6.2/datatable.wgpkg
Normal file
BIN
docs/upgrades/packages-7.6.2/datatable.wgpkg
Normal file
Binary file not shown.
|
|
@ -37,8 +37,54 @@ upgradeToYui26($session);
|
|||
addUsersOnlineMacro($session);
|
||||
addProfileExtrasField($session);
|
||||
addWorkflowToDataform( $session );
|
||||
installDataTableAsset( $session );
|
||||
installAjaxI18N( $session );
|
||||
finish($session); # this line required
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# installDataTableAsset
|
||||
# Install the asset by creating the DB table and adding it to the config file
|
||||
sub installDataTableAsset {
|
||||
my $session = shift;
|
||||
print "\tInstalling the DataTable asset... " unless $quiet;
|
||||
|
||||
$session->db->write( <<'ENDSQL' );
|
||||
CREATE TABLE DataTable (
|
||||
assetId VARCHAR(22) BINARY NOT NULL,
|
||||
revisionDate BIGINT NOT NULL,
|
||||
data LONGTEXT,
|
||||
templateId VARCHAR(22) BINARY,
|
||||
PRIMARY KEY ( assetId, revisionDate )
|
||||
)
|
||||
ENDSQL
|
||||
|
||||
my $assets = $session->config->get( "assets" );
|
||||
$assets->{ "WebGUI::Asset::Wobject::DataTable" } = { category => "basic" };
|
||||
$session->config->set( "assets", $assets );
|
||||
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# installDataTableAsset
|
||||
# Install the content handler by adding it to the config file
|
||||
sub installAjaxI18N {
|
||||
my $session = shift;
|
||||
print "\tInstalling the AjaxI18N content handler... " unless $quiet;
|
||||
|
||||
my $oldHandlers = $session->config->get( "contentHandlers" );
|
||||
my @newHandlers;
|
||||
for my $handler ( @{ $oldHandlers } ) {
|
||||
if ( $handler eq "WebGUI::Content::Operation" ) {
|
||||
push @newHandlers, "WebGUI::Content::AjaxI18N";
|
||||
}
|
||||
push @newHandlers, $handler;
|
||||
}
|
||||
$session->config->set( "contentHandlers", \@newHandlers );
|
||||
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
sub upgradeToYui26 {
|
||||
my $session = shift;
|
||||
|
|
@ -195,6 +241,7 @@ sub updateTemplates {
|
|||
my @files = readdir(DIR);
|
||||
closedir(DIR);
|
||||
my $newFolder = undef;
|
||||
$session->db->write( "UPDATE asset SET parentId='infinityandbeyond' WHERE assetId='pbversion0000000000001'" );
|
||||
foreach my $file (@files) {
|
||||
next unless ($file =~ /\.wgpkg$/);
|
||||
# Fix the filename to include a path
|
||||
|
|
|
|||
296
lib/WebGUI/Asset/Wobject/DataTable.pm
Normal file
296
lib/WebGUI/Asset/Wobject/DataTable.pm
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
package WebGUI::Asset::Wobject::DataTable;
|
||||
|
||||
$VERSION = "1.0.0";
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2008 Plain Black Corporation.
|
||||
#-------------------------------------------------------------------
|
||||
# Please read the legal notices (docs/legal.txt) and the license
|
||||
# (docs/license.txt) that came with this distribution before using
|
||||
# this software.
|
||||
#-------------------------------------------------------------------
|
||||
# http://www.plainblack.com info@plainblack.com
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
use strict;
|
||||
use Tie::IxHash;
|
||||
use WebGUI::International;
|
||||
use WebGUI::Utility;
|
||||
use base 'WebGUI::Asset::Wobject';
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 definition ( session, definition )
|
||||
|
||||
=cut
|
||||
|
||||
sub definition {
|
||||
my $class = shift;
|
||||
my $session = shift;
|
||||
my $definition = shift;
|
||||
my $i18n = WebGUI::International->new($session, 'Asset_DataTable');
|
||||
|
||||
tie my %properties, 'Tie::IxHash', (
|
||||
data => {
|
||||
fieldType => 'DataTable',
|
||||
defaultValue => undef,
|
||||
autoGenerate => 0,
|
||||
},
|
||||
templateId => {
|
||||
tab => "display",
|
||||
fieldType => "template",
|
||||
namespace => "DataTable",
|
||||
defaultValue => "3rjnBVJRO6ZSkxlFkYh_ug",
|
||||
label => $i18n->get( "editForm templateId label" ),
|
||||
hoverHelp => $i18n->get( "editForm templateId description" ),
|
||||
},
|
||||
);
|
||||
|
||||
push @{$definition}, {
|
||||
assetName => $i18n->get('assetName'),
|
||||
icon => 'Asset.gif',
|
||||
autoGenerateForms => 1,
|
||||
tableName => 'DataTable',
|
||||
className => 'WebGUI::Asset::Wobject::DataTable',
|
||||
properties => \%properties,
|
||||
};
|
||||
|
||||
return $class->SUPER::definition($session, $definition);
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getDataJson ( )
|
||||
|
||||
Get the data as a JSON object with the following structure:
|
||||
|
||||
{
|
||||
columns => [
|
||||
{
|
||||
key => "Column Key",
|
||||
formatter => "Column Format",
|
||||
},
|
||||
...
|
||||
],
|
||||
rows => [
|
||||
{
|
||||
"Column Key" => "Column Value",
|
||||
...
|
||||
},
|
||||
...
|
||||
],
|
||||
}
|
||||
|
||||
=cut
|
||||
|
||||
sub getDataJson {
|
||||
my $self = shift;
|
||||
|
||||
return $self->get( "data" );
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getDataTable ( )
|
||||
|
||||
Get the YUI DataTable markup and script for this DataTable.
|
||||
|
||||
=cut
|
||||
|
||||
# TODO Have this method get from a WebGUI::DataSource object
|
||||
|
||||
sub getDataTable {
|
||||
my $self = shift;
|
||||
|
||||
# This method assumes the form control has been prepared
|
||||
return $self->{ _datatable }->getValueAsHtml;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getDataTemplateVars ( )
|
||||
|
||||
Get the template variables for the raw data. Returns a hash reference with
|
||||
"rows" and "columns" keys.
|
||||
|
||||
=cut
|
||||
|
||||
# TODO Have this method get from a WebGUI::DataSource object
|
||||
|
||||
sub getDataTemplateVars {
|
||||
my $self = shift;
|
||||
|
||||
# This method assumes the form control has been prepared
|
||||
my $json = $self->{ _datatable }->getValue;
|
||||
my $dt = JSON->new->decode( $json );
|
||||
|
||||
# Make row data more friendly to templates
|
||||
my %cols = map { $_->{ key } => $_ } @{ $dt->{ columns } };
|
||||
for my $row ( @{ $dt->{ rows } } ) {
|
||||
# Create the column loop for the row
|
||||
for my $col ( @{ $dt->{ columns } } ) {
|
||||
push @{ $row->{ row_columns } }, {
|
||||
%{ $col },
|
||||
value => $row->{ $col->{ key } },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return $dt;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getEditForm ( )
|
||||
|
||||
Add the data table to the edit form.
|
||||
|
||||
=cut
|
||||
|
||||
# TODO Get the DataSource's edit form
|
||||
sub getEditForm {
|
||||
my $self = shift;
|
||||
my $tabform = $self->SUPER::getEditForm( @_ );
|
||||
|
||||
$tabform->getTab( "data" )->raw(
|
||||
WebGUI::Form::DataTable->new( $self->session, {
|
||||
name => "data",
|
||||
value => $self->get( "data" ),
|
||||
defaultValue => undef,
|
||||
showEdit => 1,
|
||||
} )->toHtml
|
||||
);
|
||||
|
||||
return $tabform;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getEditTabs ( )
|
||||
|
||||
Add a tab for the data table.
|
||||
|
||||
=cut
|
||||
|
||||
sub getEditTabs {
|
||||
my $self = shift;
|
||||
my $i18n = WebGUI::International->new( $self->session, "Asset_DataTable" );
|
||||
|
||||
return (
|
||||
$self->SUPER::getEditTabs,
|
||||
[ "data" => $i18n->get( "tab label data" ) ],
|
||||
);
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getTemplateVars ( )
|
||||
|
||||
Get the template vars for this asset.
|
||||
|
||||
=cut
|
||||
|
||||
sub getTemplateVars {
|
||||
my $self = shift;
|
||||
my $var = $self->get;
|
||||
|
||||
$var->{ url } = $self->getUrl;
|
||||
$var->{ dataTable } = $self->getDataTable;
|
||||
$var->{ dataJson } = $self->getDataJson;
|
||||
|
||||
%{ $var } = (
|
||||
%{ $var },
|
||||
%{ $self->getDataTemplateVars },
|
||||
);
|
||||
|
||||
return $var;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 prepareView ( )
|
||||
|
||||
Prepare the view. Add stuff to HEAD.
|
||||
|
||||
=cut
|
||||
|
||||
sub prepareView {
|
||||
my $self = shift;
|
||||
$self->SUPER::prepareView( @_ );
|
||||
my $session = $self->session;
|
||||
|
||||
# For now, prepare the form control.
|
||||
# TODO Use a WebGUI::DataSource
|
||||
my $dt = WebGUI::Form::DataTable->new( $session, {
|
||||
name => "data",
|
||||
value => $self->get( 'data' ),
|
||||
defaultValue => undef,
|
||||
} );
|
||||
$dt->prepare;
|
||||
$self->{ _datatable } = $dt;
|
||||
|
||||
# Prepare the template
|
||||
my $template = WebGUI::Asset::Template->new( $session, $self->get( "templateId" ) );
|
||||
$template->prepare;
|
||||
$self->{ _template } = $template;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 view ( )
|
||||
|
||||
method called by the www_view method. Returns a processed template
|
||||
to be displayed within the page style.
|
||||
|
||||
=cut
|
||||
|
||||
sub view {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $var = $self->getTemplateVars;
|
||||
my $dt = $self->{ _datatable };
|
||||
my $template = $self->{ _template };
|
||||
|
||||
return $self->processTemplate( $var, undef, $template );
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 www_ajaxGetData ( )
|
||||
|
||||
Get the data asynchronously.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_ajaxGetData {
|
||||
my $self = shift;
|
||||
|
||||
$self->session->http->setMimeType( "application/json" );
|
||||
return $self->getDataJson;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 www_ajaxUpdateData ( )
|
||||
|
||||
Update the data table asynchronously.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_ajaxUpdateData {
|
||||
my $self = shift;
|
||||
my $data = $self->session->form->get( "data" );
|
||||
|
||||
if ( $data && $self->canEdit ) {
|
||||
$self->update( { data => $data } );
|
||||
}
|
||||
|
||||
$data ||= $self->get( "data" );
|
||||
|
||||
$self->session->http->setMimeType( "application/json" );
|
||||
return $data;
|
||||
}
|
||||
|
||||
1;
|
||||
68
lib/WebGUI/Content/AjaxI18N.pm
Normal file
68
lib/WebGUI/Content/AjaxI18N.pm
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
package WebGUI::Content::AjaxI18N;
|
||||
|
||||
=head1 LEGAL
|
||||
|
||||
-------------------------------------------------------------------
|
||||
WebGUI is Copyright 2001-2008 Plain Black Corporation.
|
||||
-------------------------------------------------------------------
|
||||
Please read the legal notices (docs/legal.txt) and the license
|
||||
(docs/license.txt) that came with this distribution before using
|
||||
this software.
|
||||
-------------------------------------------------------------------
|
||||
http://www.plainblack.com info@plainblack.com
|
||||
-------------------------------------------------------------------
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use JSON;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Package WebGUI::Content::AjaxI18N
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
A content handler to get i18n data using the WebGUI.i18n JavaScript object.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use WebGUI::Content::AjaxI18N
|
||||
my $output = WebGUI::Content::AjaxI18N::handler($session);
|
||||
|
||||
=head1 SUBROUTINES
|
||||
|
||||
These subroutines are available from this package:
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 handler ( session )
|
||||
|
||||
The content handler for this package.
|
||||
|
||||
=cut
|
||||
|
||||
sub handler {
|
||||
my ( $session ) = @_;
|
||||
# Only handle op=ajaxGetI18N
|
||||
return undef unless ( $session->form->get( "op" ) eq "ajaxGetI18N" );
|
||||
|
||||
my $json = $session->form->get( "request" );
|
||||
my $namespaces = JSON->new->decode( $json );
|
||||
my $i18n = WebGUI::International->new( $session );
|
||||
my $response = {};
|
||||
|
||||
for my $ns ( keys %{ $namespaces } ) {
|
||||
for my $key ( @{ $namespaces->{ $ns } } ) {
|
||||
$response->{ $ns }->{ $key } = $i18n->get( $key, $ns );
|
||||
}
|
||||
}
|
||||
|
||||
$session->http->setMimeType( "application/json" );
|
||||
return JSON->new->encode( $response );
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
407
lib/WebGUI/Form/DataTable.pm
Normal file
407
lib/WebGUI/Form/DataTable.pm
Normal file
|
|
@ -0,0 +1,407 @@
|
|||
package WebGUI::Form::DataTable;
|
||||
|
||||
=head1 LEGAL
|
||||
|
||||
-------------------------------------------------------------------
|
||||
WebGUI is Copyright 2001-2008 Plain Black Corporation.
|
||||
-------------------------------------------------------------------
|
||||
Please read the legal notices (docs/legal.txt) and the license
|
||||
(docs/license.txt) that came with this distribution before using
|
||||
this software.
|
||||
-------------------------------------------------------------------
|
||||
http://www.plainblack.com info@plainblack.com
|
||||
-------------------------------------------------------------------
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use base 'WebGUI::Form::Control';
|
||||
use WebGUI::International;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Package WebGUI::Form::DataTable
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Create an editable table. Users can add columns and rows to the table.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
This is a subclass of WebGUI::Form::Control.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
The following methods are specifically available from this class. Check the superclass for additional methods.
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 definition ( [ additionalTerms ] )
|
||||
|
||||
See the super class for additional details.
|
||||
|
||||
=head3 additionalTerms
|
||||
|
||||
The following additional parameters have been added via this sub class.
|
||||
|
||||
=head4 ajaxDataUrl
|
||||
|
||||
This is the URL to get the data from, AJAX-style.
|
||||
|
||||
=head4 ajaxDataFunc
|
||||
|
||||
This is the ?func= to get the data from.
|
||||
|
||||
=head4 ajaxSaveUrl
|
||||
|
||||
This is the URL to send AJAX requests to. If this exists, will send
|
||||
updates to the table asyncronously.
|
||||
|
||||
=head4 ajaxSaveFunc
|
||||
|
||||
This is the ?func= to send AJAX requests to.
|
||||
|
||||
=head4 showEdit
|
||||
|
||||
If true, will enable the table for editing. This is only necessary when
|
||||
displaying the table with getValueAsHtml().
|
||||
|
||||
=cut
|
||||
|
||||
sub definition {
|
||||
my $class = shift;
|
||||
my $session = shift;
|
||||
my $definition = shift || [];
|
||||
|
||||
push @{$definition}, {
|
||||
showEdit => {
|
||||
defaultValue => 0,
|
||||
},
|
||||
ajaxDataUrl => {
|
||||
defaultValue => undef,
|
||||
},
|
||||
ajaxDataFunc => {
|
||||
defaultValue => "view",
|
||||
},
|
||||
ajaxSaveUrl => {
|
||||
defaultValue => undef,
|
||||
},
|
||||
ajaxSaveFunc => {
|
||||
defaultValue => "view",
|
||||
},
|
||||
};
|
||||
|
||||
return $class->SUPER::definition($session, $definition);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getDataTableHtml ( )
|
||||
|
||||
Render the DataTable
|
||||
|
||||
=cut
|
||||
|
||||
sub getDataTableHtml {
|
||||
my $self = shift;
|
||||
|
||||
$self->prepare unless $self->{_prepared};
|
||||
|
||||
my $data = JSON->new->decode( $self->getOriginalValue );
|
||||
my $id = $self->get( 'id' );
|
||||
|
||||
# Get the HTML for the table
|
||||
my $html = $self->getTableHtml( $data );
|
||||
|
||||
### Prepare the columns data
|
||||
my %parsers = (
|
||||
date => "YAHOO.util.DataSource.parseDate",
|
||||
number => "YAHOO.util.DataSource.parseNumber",
|
||||
);
|
||||
|
||||
my %editors = (
|
||||
date => "date",
|
||||
textbox => "textbox",
|
||||
);
|
||||
|
||||
my @columnsJson = ();
|
||||
for my $column ( @{ $data->{ columns } } ) {
|
||||
# Not using a datastructure and JSON.pm because of function references for "parser"
|
||||
my $columnDef = '{'
|
||||
. qq{"key" : "$column->{ key }", }
|
||||
. qq{"abbr" : "$column->{ key }", }
|
||||
. qq{"formatter" : "$column->{ formatter }", }
|
||||
. qq{"resizable" : 1, }
|
||||
. qq{"sortable" : 1}
|
||||
;
|
||||
|
||||
# Automatically determine the parser to use
|
||||
if ( $parsers{ $column->{ formatter } } ) {
|
||||
$columnDef .= qq{, "parser" : $parsers{ $column->{ formatter } }};
|
||||
};
|
||||
|
||||
# If we can edit
|
||||
if ( $self->get( 'showEdit' ) ) {
|
||||
# Set the editor
|
||||
my $editor = $editors{ $column->{ formatter } }
|
||||
|| $editors{ "textbox" }
|
||||
;
|
||||
$columnDef .= qq{, "editor" : "$editor"};
|
||||
}
|
||||
$columnDef .= '}';
|
||||
|
||||
push @columnsJson, $columnDef;
|
||||
}
|
||||
my $columnsJson = "[" . join( ",", @columnsJson ) . "]";
|
||||
|
||||
### Prepare any options
|
||||
my $options = {
|
||||
"showEdit" => $self->get( 'showEdit' ),
|
||||
"inputName" => $self->get( 'name' ),
|
||||
"ajaxDataUrl" => $self->get( 'ajaxDataUrl' ),
|
||||
"ajaxDataFunc" => $self->get( 'ajaxDataFunc' ),
|
||||
"ajaxSaveUrl" => $self->get( 'ajaxSaveUrl' ),
|
||||
"ajaxSaveFunc" => $self->get( 'ajaxSaveFunc' ),
|
||||
};
|
||||
my $optionsJson = JSON->new->encode( $options );
|
||||
|
||||
# Progressively enhance the bejesus out of it
|
||||
$html .= <<"ENDJS";
|
||||
<script type="text/javascript">
|
||||
var myDataTable = WebGUI.Form.DataTable( "$id-container", $columnsJson, $optionsJson );
|
||||
</script>
|
||||
ENDJS
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getDefaultValue ( )
|
||||
|
||||
Get the default value. If none exists, return at least an appropriate
|
||||
data structure.
|
||||
|
||||
=cut
|
||||
|
||||
sub getDefaultValue {
|
||||
my $self = shift;
|
||||
my $value = $self->SUPER::getDefaultValue( @_ );
|
||||
|
||||
if ( !$value ) {
|
||||
$value = JSON->new->encode(
|
||||
{
|
||||
columns => [
|
||||
{
|
||||
key => "New Column",
|
||||
formatter => "text",
|
||||
},
|
||||
],
|
||||
rows => [
|
||||
{
|
||||
"New Column" => "Value",
|
||||
},
|
||||
],
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getName ( session )
|
||||
|
||||
Returns the name of the form control.
|
||||
|
||||
=cut
|
||||
|
||||
sub getName {
|
||||
my ($class, $session) = @_;
|
||||
return WebGUI::International->new($session, "Form_DataTable")->get("topicName");
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getOriginalValue ( )
|
||||
|
||||
Get the original value, or the default value.
|
||||
|
||||
=cut
|
||||
|
||||
sub getOriginalValue {
|
||||
my $self = shift;
|
||||
my $value = $self->SUPER::getOriginalValue( @_ );
|
||||
|
||||
if ( !$value ) {
|
||||
$value = $self->getDefaultValue;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getValue ( [ value ] )
|
||||
|
||||
Return the data for the table in a serialized JSON object with the following
|
||||
structure.
|
||||
|
||||
$VAR1 = {
|
||||
columns => [
|
||||
{
|
||||
key => column name,
|
||||
formatter => "", one of "button", "checkbox", "currency", "date", "dropdown",
|
||||
"email", "link", "number", "radio", "text", "textarea", "textbox"
|
||||
// FUTURE ENHANCEMENTS
|
||||
editor => "", one of "text", "date", "dropdown", "radio", "check"
|
||||
editorOptions => [ ... ], needed for "dropdown", "radio", "check"
|
||||
resizable => 1,
|
||||
sortable => 1,
|
||||
},
|
||||
],
|
||||
rows => [
|
||||
{
|
||||
column name => value,
|
||||
column name => value,
|
||||
...
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
=cut
|
||||
|
||||
sub getValue {
|
||||
my $self = shift;
|
||||
my $value = $self->SUPER::getValue(@_);
|
||||
|
||||
# If passing in a data structure, encode to JSON
|
||||
if ( ref $value eq "HASH" ) {
|
||||
$value = JSON->new->encode( $value );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getValueAsHtml ( )
|
||||
|
||||
Get the value as HTML. Render the datatable in a non-editable form.
|
||||
|
||||
=cut
|
||||
|
||||
sub getValueAsHtml {
|
||||
my $self = shift;
|
||||
return $self->getDataTableHtml;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getTableHtml ( [data] )
|
||||
|
||||
Get the HTML to render the table. C<data> is the data structure with
|
||||
columns and rows to render. Defaults to C<getValue>.
|
||||
|
||||
=cut
|
||||
|
||||
sub getTableHtml {
|
||||
my $self = shift;
|
||||
my $data = shift;
|
||||
|
||||
my $html = '<div id="' . $self->get('id') . '-container" class="yui-skin-sam">';
|
||||
|
||||
# Only insert the table if we're not getting AJAX Data
|
||||
if ( !$self->get( "ajaxDataUrl" ) ) {
|
||||
$html .= '<table id="' . $self->get('id') . '-container-table"><thead><tr>';
|
||||
|
||||
for my $column ( @{ $data->{ columns } } ) {
|
||||
$html .= '<th>' . $column->{ key } . '</th>';
|
||||
}
|
||||
|
||||
# TODO: Add table footer
|
||||
$html .= '</tr></thead><tbody>';
|
||||
|
||||
for my $row ( @{ $data->{ rows } } ) {
|
||||
$html .= '<tr>';
|
||||
|
||||
for my $column ( @{ $data->{ columns } } ) {
|
||||
$html .= '<td>' . $row->{ $column->{ key } } . '</td>';
|
||||
}
|
||||
|
||||
$html .= '</tr>';
|
||||
}
|
||||
|
||||
$html .= '</tbody></table>';
|
||||
}
|
||||
|
||||
$html .= '</div>';
|
||||
|
||||
# Add hidden form element to hold JSON
|
||||
if ( $self->get( 'showEdit' ) ) {
|
||||
$html .= '<input type="hidden" name="' . $self->get( 'name' ) . '" />';
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 prepare ( )
|
||||
|
||||
Load all the script and css files we need. Call this in prepareView() if needed.
|
||||
Otherwise, is called automatically.
|
||||
|
||||
=cut
|
||||
|
||||
sub prepare {
|
||||
my $self = shift;
|
||||
|
||||
# Source in the scripts
|
||||
my $style = $self->session->style;
|
||||
my $url = $self->session->url;
|
||||
$style->setLink( $url->extras( 'yui/build/datatable/assets/skins/sam/datatable.css' ), { rel => "stylesheet", type => "text/css" } );
|
||||
$style->setScript( $url->extras( 'yui/build/yahoo-dom-event/yahoo-dom-event.js' ) );
|
||||
$style->setScript( $url->extras( 'yui/build/element/element-beta.js' ) );
|
||||
$style->setScript( $url->extras( 'yui/build/dragdrop/dragdrop-min.js' ) );
|
||||
$style->setScript( $url->extras( 'yui/build/connection/connection-min.js' ) );
|
||||
$style->setScript( $url->extras( 'yui/build/json/json-min.js' ) );
|
||||
|
||||
# Prepare the editors
|
||||
if ( $self->get( 'showEdit' ) ) {
|
||||
$style->setLink( $url->extras( 'yui/build/button/assets/skins/sam/button.css', { rel => "stylesheet", type => "text/css" } ) );
|
||||
$style->setLink( $url->extras( 'yui/build/calendar/assets/skins/sam/calendar.css', { rel => "stylesheet", type => "text/css" } ) );
|
||||
$style->setLink( $url->extras( 'yui/build/container/assets/skins/sam/container.css' ), { rel => "stylesheet", type => "text/css" } );
|
||||
$style->setScript( $url->extras( 'yui/build/container/container-min.js' ) );
|
||||
$style->setScript( $url->extras( 'yui/build/button/button-min.js' ) );
|
||||
$style->setScript( $url->extras( 'yui/build/calendar/calendar-min.js' ) );
|
||||
}
|
||||
|
||||
$style->setScript( $url->extras( 'yui-webgui/build/i18n/i18n.js' ) );
|
||||
$style->setScript( $url->extras( 'yui/build/datasource/datasource.js' ) );
|
||||
$style->setScript( $url->extras( 'yui/build/datatable/datatable.js' ) );
|
||||
$style->setScript( $url->extras( 'yui-webgui/build/form/datatable.js' ) );
|
||||
|
||||
$self->{_prepared} = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 toHtml ( )
|
||||
|
||||
Render the DataTable in an editable format.
|
||||
|
||||
=cut
|
||||
|
||||
sub toHtml {
|
||||
my $self = shift;
|
||||
$self->set( 'showEdit', 1 );
|
||||
return $self->getDataTableHtml;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
19
lib/WebGUI/i18n/English/Asset_DataTable.pm
Normal file
19
lib/WebGUI/i18n/English/Asset_DataTable.pm
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
package WebGUI::i18n::English::Asset_DataTable;
|
||||
|
||||
use strict;
|
||||
|
||||
our $I18N = {
|
||||
'assetName' => {
|
||||
message => q{DataTable},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'tab label data' => {
|
||||
message => q{Data Table},
|
||||
lastUpdated => 0,
|
||||
context => q{Label for the tab with the editable data table},
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
132
lib/WebGUI/i18n/English/Form_DataTable.pm
Normal file
132
lib/WebGUI/i18n/English/Form_DataTable.pm
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
package WebGUI::i18n::English::Form_DataTable;
|
||||
|
||||
use strict;
|
||||
|
||||
our $I18N = {
|
||||
'topicName' => {
|
||||
message => q{DataTable},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'delete rows' => {
|
||||
message => q{Delete Selected Rows},
|
||||
lastUpdated => 0,
|
||||
context => q{Label for button to delete the selected rows},
|
||||
},
|
||||
|
||||
'save' => {
|
||||
message => q{Save},
|
||||
lastUpdated => 0,
|
||||
context => q{Label for button to Save changes},
|
||||
},
|
||||
|
||||
"add row" => {
|
||||
message => q{Add Row},
|
||||
lastUpdated => 0,
|
||||
context => q{Label for button to Add Row to the table},
|
||||
},
|
||||
|
||||
"help" => {
|
||||
message => q{Help},
|
||||
lastUpdated => 0,
|
||||
context => q{Label for button to open the help dialog},
|
||||
},
|
||||
|
||||
"edit schema" => {
|
||||
message => q{Edit Schema},
|
||||
lastUpdated => 0,
|
||||
context => q{Label for button to edit the table column configuration},
|
||||
},
|
||||
|
||||
"delete confirm" => {
|
||||
message => q{Are you sure you want to delete these rows?},
|
||||
lastUpdated => 0,
|
||||
context => q{Message for pop-up to confirm deleting rows from the table},
|
||||
},
|
||||
|
||||
"format text" => {
|
||||
message => q{Text},
|
||||
lastUpdated => 0,
|
||||
context => q{Format for a plain text column},
|
||||
},
|
||||
|
||||
"format email" => {
|
||||
message => q{E-mail},
|
||||
lastUpdated => 0,
|
||||
context => q{Format for a column for an e-mail address},
|
||||
},
|
||||
|
||||
"format link" => {
|
||||
message => q{URL},
|
||||
lastUpdated => 0,
|
||||
context => q{Format for a column for URLs},
|
||||
},
|
||||
|
||||
"format number" => {
|
||||
message => q{Number},
|
||||
lastUpdated => 0,
|
||||
context => q{Format for a column with numbers},
|
||||
},
|
||||
|
||||
"add column" => {
|
||||
message => q{Add Column},
|
||||
lastUpdated => 0,
|
||||
context => q{Label for button to add a column},
|
||||
},
|
||||
|
||||
"cancel" => {
|
||||
message => q{Cancel},
|
||||
lastUpdated => 0,
|
||||
context => q{Label for button to cancel},
|
||||
},
|
||||
|
||||
"ok" => {
|
||||
message => q{Ok},
|
||||
lastUpdated => 0,
|
||||
context => q{Label for button to close an information dialog},
|
||||
},
|
||||
|
||||
"save success" => {
|
||||
message => q{Table saved successfully!},
|
||||
lastUpdated => 0,
|
||||
context => q{Message shown when the table save succeeds},
|
||||
},
|
||||
|
||||
"save failure" => {
|
||||
message => q{Save failed! Please try again.},
|
||||
lastUpdated => 0,
|
||||
context => q{Message shown when the table save fails},
|
||||
},
|
||||
|
||||
"help edit cell" => {
|
||||
message => q{Double-click a cell to edit the cell. Hitting tab will save the current cell and open the next.},
|
||||
lastUpdated => 0,
|
||||
context => q{How to edit a cell. Shown in the help pop-up},
|
||||
},
|
||||
|
||||
"help select row" => {
|
||||
message => q{Click on a row to select it. Hold shift or ctrl to select multiple rows.},
|
||||
lastUpdated => 0,
|
||||
context => q{How to select a row. Shown in the help pop-up},
|
||||
},
|
||||
|
||||
"help add row" => {
|
||||
message => q{Clicking Add Row will add a row to the bottom of the table.},
|
||||
lastUpdated => 0,
|
||||
context => q{How to add a row. Shown in the help pop-up},
|
||||
},
|
||||
|
||||
"help default sort" => {
|
||||
message => q{By default, the table will be sorted exactly as it is when it is saved.},
|
||||
lastUpdated => 0,
|
||||
context => q{How to set the default sort. Shown in the help pop-up},
|
||||
},
|
||||
|
||||
"help reorder column" => {
|
||||
message => q{Drag and drop columns to reorder them.},
|
||||
lastUpdated => 0,
|
||||
context => q{How to reorder columns. Shown in the help pop-up},
|
||||
},
|
||||
};
|
||||
|
||||
1;
|
||||
583
www/extras/yui-webgui/build/form/datatable.js
vendored
Normal file
583
www/extras/yui-webgui/build/form/datatable.js
vendored
Normal file
|
|
@ -0,0 +1,583 @@
|
|||
|
||||
// Initialize namespace
|
||||
if (typeof WebGUI == "undefined") {
|
||||
var WebGUI = {};
|
||||
}
|
||||
if (typeof WebGUI.Form == "undefined") {
|
||||
WebGUI.Form = {};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This object contains scripts for the DataTable form control
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* DataTable ( containerId, columns, options )
|
||||
* Initialize a WebGUI.Form.DataTable.
|
||||
* containerId is the ID of the container for the table. It is assumed the data
|
||||
* is already in a table inside of the container (progressive enhancement).
|
||||
* columns is an array of definitions for YAHOO.widget.Column objects
|
||||
* rows is an array of key/value pairs
|
||||
* options is an object literal of options with the following keys
|
||||
* ajaxDataUrl : The URL to get data from
|
||||
* ajaxSaveUrl : The URL to save data to
|
||||
* ajaxSaveFunc : The ?func= to save data to
|
||||
* ajaxSaveExtras : Any extra name=value pairs necessary to save the data
|
||||
* inputName : The name of the DataTable when editing the data
|
||||
* showEdit : Show the edit controls and allow inline editing of values
|
||||
*
|
||||
*/
|
||||
WebGUI.Form.DataTable
|
||||
= function ( containerId, columns, options ) {
|
||||
this.containerId = containerId;
|
||||
this.columns = columns;
|
||||
this.dataSource = undefined;
|
||||
this.dataTable = undefined;
|
||||
this.form = undefined;
|
||||
this.options = options;
|
||||
this.schemaDialog = undefined;
|
||||
|
||||
/************************************************************************
|
||||
* addRow ( event, data )
|
||||
* Add a row to the bottom of the table
|
||||
*/
|
||||
this.addRow
|
||||
= function ( event, data ) {
|
||||
if ( !data ) {
|
||||
// Make a blank row
|
||||
data = {};
|
||||
var columns = this.dataTable.getColumnSet().getDefinitions();
|
||||
for ( var i = 0; i < columns.length; i++ ) {
|
||||
data[ columns[ i ].key ] = "";
|
||||
}
|
||||
}
|
||||
this.dataTable.addRow( data );
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* deleteSelectedRows ( )
|
||||
* Delete the selected rows after confirming
|
||||
*/
|
||||
this.deleteSelectedRows
|
||||
= function ( ) {
|
||||
if ( confirm( this.i18n.get( "Form_DataTable", "delete confirm" ) ) ) {
|
||||
var rows = this.dataTable.getSelectedRows();
|
||||
for ( var i = 0; i < rows.length; i++ ) {
|
||||
this.dataTable.deleteRow( this.dataTable.getRecord( rows[i] ) );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* getJson ( )
|
||||
* Get the JSON data structure for the current state of the datatable
|
||||
*/
|
||||
this.getJson
|
||||
= function () {
|
||||
var data = { rows : [], columns : [] };
|
||||
|
||||
// Get the rows
|
||||
var rows = this.dataTable.getRecordSet().getRecords();
|
||||
for ( var i = 0; i < rows.length; i++ ) {
|
||||
data.rows[ i ] = rows[i].getData();
|
||||
}
|
||||
|
||||
// Get the columns
|
||||
var cols = this.dataTable.getColumnSet().getDefinitions();
|
||||
for ( var i = 0; i < cols.length; i++ ) {
|
||||
data.columns[ i ] = cols[i];
|
||||
delete data.columns[ i ].editor;
|
||||
delete data.columns[ i ].editorOptions;
|
||||
}
|
||||
|
||||
return YAHOO.lang.JSON.stringify( data );
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* handleEditorKeyEvent ( obj )
|
||||
* Handle a keypress when the Cell Editor is open
|
||||
* Enter will close the editor and move down
|
||||
* Tab will close the editor and move right.
|
||||
* Use the handleTableKeyEvent() to handle the moving
|
||||
* Open a new cell editor on the newly focused cell
|
||||
*/
|
||||
this.handleEditorKeyEvent
|
||||
= function ( obj ) {
|
||||
// 9 = tab, 13 = enter
|
||||
var e = obj.event;
|
||||
if ( e.keyCode == 9 || e.keyCode == 13 ) {
|
||||
var cell = this.dataTable.getCellEditor().getTdEl();
|
||||
var nextCell = this.dataTable.getNextTdEl( cell );
|
||||
this.dataTable.saveCellEditor();
|
||||
if ( nextCell ) {
|
||||
this.dataTable.showCellEditor( nextCell );
|
||||
e.returnValue = false;
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
// No next cell, make a new row and open the editor for that one
|
||||
this.dataTable.addRow( {} );
|
||||
}
|
||||
// BUG: If pressing Enter, editor gets hidden right away due to YUI default event
|
||||
// putting e.preventDefault() and return false here makes no difference
|
||||
}
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* handleEditorShowEvent ( editor )
|
||||
* Give the focus to the editor
|
||||
*/
|
||||
this.handleEditorShowEvent
|
||||
= function ( obj ) {
|
||||
obj.editor.focus();
|
||||
setTimeout( obj.editor.focus, 500 );
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* handleRowAdd ( )
|
||||
* Open the cell editor for the newly-added row
|
||||
*/
|
||||
this.handleRowAdd
|
||||
= function () {
|
||||
var row = this.dataTable.getLastTrEl();
|
||||
this.dataTable.showCellEditor( row.firstChild );
|
||||
this.dataTable.getCellEditor().focus();
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* handleTableKeyEvent ( obj )
|
||||
* Handle a keypress inside the DataTable
|
||||
* Space will open the cell editor
|
||||
*/
|
||||
this.handleTableKeyEvent
|
||||
= function ( obj ) {
|
||||
// 9 = tab, 13 = enter, 32 = space
|
||||
var e = obj.event;
|
||||
if ( e.keyCode == 32 ) {
|
||||
var cell = this.dataTable.getSelectedTdEls()[0];
|
||||
if ( cell ) {
|
||||
this.dataTable.showCellEditor(cell);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* hideSchemaDialog ( )
|
||||
* Hide the schema dialog without saving changed
|
||||
*/
|
||||
this.hideSchemaDialog
|
||||
= function () {
|
||||
this.schemaDialog.cancel();
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* initDataTable
|
||||
* Initialize the data table. Called automatically when the DOM is ready
|
||||
*/
|
||||
this.initDataTable
|
||||
= function () {
|
||||
var container = document.getElementById( this.containerId );
|
||||
|
||||
// If we have an ajax datasource
|
||||
if ( this.options.ajaxDataUrl ) {
|
||||
this.dataSource
|
||||
= new YAHOO.util.DataSource( this.options.ajaxDataUrl );
|
||||
this.dataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
|
||||
this.dataSource.responseSchema = {
|
||||
resultsList : "rows",
|
||||
fields : this.columns
|
||||
};
|
||||
}
|
||||
else {
|
||||
// Initialize a datasource with the table
|
||||
this.dataSource
|
||||
= new YAHOO.util.DataSource( YAHOO.util.Dom.get( this.containerId + "-table" ) );
|
||||
this.dataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
|
||||
this.dataSource.responseSchema = {
|
||||
fields : this.columns
|
||||
};
|
||||
YAHOO.util.Dom.get( this.containerId + "-table" ).style.display = "none";
|
||||
}
|
||||
|
||||
var dataTableOptions = { };
|
||||
if ( this.options.showEdit ) {
|
||||
dataTableOptions.draggableColumns = true;
|
||||
}
|
||||
if ( this.options.ajaxDataUrl ) {
|
||||
dataTableOptions.initialLoad = true;
|
||||
dataTableOptions.initialRequest = "";
|
||||
}
|
||||
|
||||
this.dataTable = new YAHOO.widget.DataTable(
|
||||
this.containerId,
|
||||
this.columns,
|
||||
this.dataSource,
|
||||
dataTableOptions
|
||||
);
|
||||
|
||||
if ( this.options.showEdit ) {
|
||||
// Add the class so our editors get the right skin
|
||||
YAHOO.util.Dom.addClass( document.body, "yui-skin-sam" );
|
||||
|
||||
this.dataTable.subscribe( "cellDblclickEvent", this.dataTable.onEventShowCellEditor );
|
||||
this.dataTable.subscribe( "rowClickEvent", this.dataTable.onEventSelectRow );
|
||||
this.dataTable.subscribe( "tableKeyEvent", this.handleTableKeyEvent, this, true );
|
||||
this.dataTable.subscribe( "editorKeydownEvent", this.handleEditorKeyEvent, this, true );
|
||||
this.dataTable.subscribe( "editorShowEvent", this.handleEditorShowEvent, this, true );
|
||||
this.dataTable.subscribe( "rowAddEvent", this.handleRowAdd, this, true );
|
||||
|
||||
// Add the Help button
|
||||
var help = new YAHOO.widget.Button( {
|
||||
id : "help",
|
||||
type : "push",
|
||||
label : this.i18n.get( "Form_DataTable", "help" ),
|
||||
container : this.containerId,
|
||||
onclick : {
|
||||
fn : this.showHelp,
|
||||
scope : this
|
||||
}
|
||||
});
|
||||
help.setStyle( "float", "left" );
|
||||
|
||||
// Add the Edit Schema button
|
||||
var editSchema = new YAHOO.widget.Button( {
|
||||
id : "editSchema",
|
||||
type : "push",
|
||||
label : this.i18n.get( "Form_DataTable", "edit schema" ),
|
||||
container : this.containerId,
|
||||
onclick : {
|
||||
fn : this.showSchemaDialog,
|
||||
scope : this
|
||||
}
|
||||
} );
|
||||
editSchema.setStyle( "float", "right" );
|
||||
|
||||
// Add the Add Row and Delete Row buttons
|
||||
var addRow = new YAHOO.widget.Button( {
|
||||
id : "addRow",
|
||||
type : "push",
|
||||
label : this.i18n.get( "Form_DataTable", "add row" ),
|
||||
container : this.containerId,
|
||||
onclick : {
|
||||
fn : this.addRow,
|
||||
scope : this
|
||||
}
|
||||
} );
|
||||
|
||||
var deleteRow = new YAHOO.widget.Button( {
|
||||
id : "deleteRow",
|
||||
type : "push",
|
||||
label : this.i18n.get( "Form_DataTable", "delete rows" ),
|
||||
container : this.containerId,
|
||||
onclick : {
|
||||
fn : this.deleteSelectedRows,
|
||||
scope : this
|
||||
}
|
||||
} );
|
||||
|
||||
// This data table will be submitted async
|
||||
if ( this.options.ajaxSaveUrl ) {
|
||||
var save = new YAHOO.widget.Button( {
|
||||
id : "saveTable",
|
||||
type : "push",
|
||||
label : this.i18n.get( "Form_DataTable", "save" ),
|
||||
container : this.containerId,
|
||||
onclick : {
|
||||
fn : this.submitToAjax,
|
||||
scope : this
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
// This data table will be submitted with a form
|
||||
if ( this.options.inputName && !this.options.ajaxSaveUrl ) {
|
||||
// Find our form
|
||||
var form = document.getElementById( this.containerId );
|
||||
while ( form.nodeName != "FORM" ) {
|
||||
form = form.parentNode;
|
||||
}
|
||||
this.form = form;
|
||||
|
||||
// When form is submitted, compile the JSON
|
||||
YAHOO.util.Event.addListener( form, "submit", this.submitToForm, this, true );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* initI18N ( )
|
||||
* Initialize the I18N that we need. Then initialize the datatable.
|
||||
*/
|
||||
this.initI18N
|
||||
= function ( ) {
|
||||
this.i18n = new WebGUI.i18n( {
|
||||
namespaces : {
|
||||
'Form_DataTable' : [
|
||||
"topicName",
|
||||
"save",
|
||||
"delete rows",
|
||||
"add row",
|
||||
"help",
|
||||
"edit schema",
|
||||
"delete confirm",
|
||||
"format text",
|
||||
"format email",
|
||||
"format link",
|
||||
"format number",
|
||||
"add column",
|
||||
"cancel",
|
||||
"ok",
|
||||
"save success",
|
||||
"save failure",
|
||||
"help edit cell",
|
||||
"help select row",
|
||||
"help add row",
|
||||
"help default sort",
|
||||
"help reorder column"
|
||||
]
|
||||
},
|
||||
onpreload : {
|
||||
fn : this.initDataTable,
|
||||
obj : this,
|
||||
override : true
|
||||
}
|
||||
} );
|
||||
};
|
||||
// Run this automatically
|
||||
YAHOO.util.Event.onDOMReady( this.initI18N, undefined, this );
|
||||
|
||||
/************************************************************************
|
||||
* showHelp ( event )
|
||||
* Show the help dialog, creating it if necessary
|
||||
*/
|
||||
this.showHelp
|
||||
= function ( e ) {
|
||||
if ( !this.helpDialog ) {
|
||||
var helpDialog = new YAHOO.widget.Panel( "helpWindow", {
|
||||
modal : false,
|
||||
draggable : true,
|
||||
zIndex : 1000
|
||||
} );
|
||||
helpDialog.setHeader( "DataTable Help" );
|
||||
helpDialog.setBody(
|
||||
"<ul>"
|
||||
+ "<li>" + this.i18n.get( "Form_DataTable", "help edit cell" ) + "</li>"
|
||||
+ "<li>" + this.i18n.get( "Form_DataTable", "help select row" ) + "</li>"
|
||||
+ "<li>" + this.i18n.get( "Form_DataTable", "help add row" ) + "</li>"
|
||||
+ "<li>" + this.i18n.get( "Form_DataTable", "help default sort" ) + "</li>"
|
||||
+ "<li>" + this.i18n.get( "Form_DataTable", "help reorder column" ) + "</li>"
|
||||
+ "</ul>"
|
||||
);
|
||||
helpDialog.render( document.body );
|
||||
this.helpDialog = helpDialog;
|
||||
}
|
||||
this.helpDialog.show();
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* showSchemaDialog ( event )
|
||||
* Show the Edit Schema YUI Dialog. Markup is in WebGUI::Form::DataTable
|
||||
*/
|
||||
this.showSchemaDialog
|
||||
= function ( e ) {
|
||||
var dg = new YAHOO.widget.Dialog( "editSchemaDialog", {
|
||||
modal : true,
|
||||
fixedcenter : true
|
||||
});
|
||||
dg.setHeader( this.i18n.get( "Form_DataTable", "edit schema" ) );
|
||||
|
||||
var body = '<form>';
|
||||
var cols = this.dataTable.getColumnSet().keys;
|
||||
for ( var i = 0; i < cols.length; i++ ) {
|
||||
body = body
|
||||
+ '<input name="oldKey_' + i + '" type="hidden" value="' + cols[ i ].key + '" />'
|
||||
+ '<input name="newKey_' + i + '" value="' + cols[ i ].key + '"/>'
|
||||
+ '<select name="format_' + i + '">'
|
||||
+ '<option value="text"' + ( cols[ i ].formatter == "text" ? ' selected="selected"' : '' ) + '>'
|
||||
+ this.i18n.get( "Form_DataTable", "format text" ) + '</option>'
|
||||
+ '<option value="number"' + ( cols[ i ].formatter == "number" ? ' selected="selected"' : '' ) + '>'
|
||||
+ this.i18n.get( "Form_DataTable", "format number" ) + '</option>'
|
||||
+ '<option value="link"' + ( cols[ i ].formatter == "link" ? ' selected="selected"' : '' ) + '>'
|
||||
+ this.i18n.get( "Form_DataTable", "format link" ) + '</option>'
|
||||
+ '<option value="email"' + ( cols[ i ].formatter == "email" ? ' selected="selected"' : '' ) + '>'
|
||||
+ this.i18n.get( "Form_DataTable", "format email" ) + '</option>'
|
||||
+ '</select><br/>'
|
||||
}
|
||||
body += '</form>';
|
||||
dg.setBody( body );
|
||||
|
||||
// Function to add a column
|
||||
var addColumn = function ( e ) {
|
||||
// this is the dialog
|
||||
var form = this.element.getElementsByTagName( "form" )[0];
|
||||
|
||||
var newIdx = 0;
|
||||
while ( form.elements[ "oldKey_" + newIdx ] ) { newIdx++; }
|
||||
|
||||
var oldKey = form.elements[ "oldKey_" + (newIdx - 1) ].cloneNode(true);
|
||||
oldKey.name = "oldKey_" + newIdx;
|
||||
oldKey.value = "";
|
||||
form.appendChild( oldKey );
|
||||
|
||||
var newKey = form.elements[ "newKey_" + (newIdx - 1) ].cloneNode(true);
|
||||
newKey.name = "newKey_" + newIdx;
|
||||
newKey.value = "New Column " + newIdx;
|
||||
form.appendChild( newKey );
|
||||
|
||||
var format = form.elements[ "format_" + (newIdx - 1) ].cloneNode(true);
|
||||
format.name = "format_" + newIdx;
|
||||
format.selectedIndex = 0;
|
||||
form.appendChild( format );
|
||||
|
||||
form.appendChild( document.createElement( "br" ) );
|
||||
};
|
||||
|
||||
dg.cfg.queueProperty( "buttons", [
|
||||
{ text: this.i18n.get( "Form_DataTable", "add column" ), handler: addColumn },
|
||||
{ text: this.i18n.get( "Form_DataTable", "cancel" ), handler: { fn: this.hideSchemaDialog, scope: this } },
|
||||
{ text: this.i18n.get( "Form_DataTable", "save" ), handler: { fn: this.updateSchema, scope: this }, isDefault: true }
|
||||
] );
|
||||
dg.render( document.body );
|
||||
this.schemaDialog = dg;
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* submitToAjax ( event )
|
||||
* Save the data table to the AJAX URL
|
||||
*/
|
||||
this.submitToAjax
|
||||
= function ( e ) {
|
||||
if ( this.options.ajaxSaveUrl ) {
|
||||
var callback = {
|
||||
success : function ( o ) {
|
||||
var dialog = new YAHOO.widget.Panel( "savedMessage", {
|
||||
modal : true,
|
||||
fixedcenter : true
|
||||
} );
|
||||
dialog.setBody( this.i18n.get( "Form_DataTable", "save success" ) + "<br/>" );
|
||||
new YAHOO.widget.Button( {
|
||||
id : "ok",
|
||||
type : "push",
|
||||
label : this.i18n.get( "Form_DataTable", "ok" ),
|
||||
container : dialog.body,
|
||||
onclick : {
|
||||
fn : function () { this.destroy() },
|
||||
scope : dialog
|
||||
}
|
||||
} );
|
||||
dialog.render( document.body );
|
||||
},
|
||||
failure : function ( o ) {
|
||||
var dialog = new YAHOO.widget.Panel( el, {
|
||||
modal : true,
|
||||
fixedcenter : true
|
||||
} );
|
||||
dialog.setBody( this.i18n.get( "Form_DataTable", "save failure" ) + "<br/>" );
|
||||
new YAHOO.widget.Button( {
|
||||
id : "ok",
|
||||
type : "push",
|
||||
label : this.i18n.get( "Form_DataTable", "ok" ),
|
||||
container : dialog.body,
|
||||
onclick : {
|
||||
fn : function () { this.destroy() },
|
||||
scope : dialog
|
||||
}
|
||||
} );
|
||||
dialog.render( document.body );
|
||||
},
|
||||
scope : this
|
||||
};
|
||||
|
||||
var data = this.getJson();
|
||||
var postdata = "func=" + this.options.ajaxSaveFunc + ";"
|
||||
+ this.options.ajaxSaveExtras + ";"
|
||||
+ this.options.inputName + "=" + escape( data )
|
||||
;
|
||||
|
||||
YAHOO.util.Connect.asyncRequest(
|
||||
"POST",
|
||||
this.options.ajaxSaveUrl,
|
||||
callback,
|
||||
postdata
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* submitToForm ( event )
|
||||
* Compile the DataTable data into the right form element
|
||||
*/
|
||||
this.submitToForm
|
||||
= function (e) {
|
||||
var elem = this.form.elements[ this.options.inputName ];
|
||||
elem.value = this.getJson();
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* updateSchema callback
|
||||
*/
|
||||
this.updateSchema
|
||||
= function () {
|
||||
var i = 0;
|
||||
var data = this.schemaDialog.getData();
|
||||
while ( data[ "newKey_" + i ] ) {
|
||||
var oldKey = data[ "oldKey_" + i ];
|
||||
var newKey = data[ "newKey_" + i ];
|
||||
var format = data[ "format_" + i ][0];
|
||||
var col = this.dataTable.getColumn( oldKey );
|
||||
|
||||
// Don't allow adding multiple columns with same key
|
||||
if ( oldKey != newKey && this.dataTable.getColumn( newKey ) ) {
|
||||
// TODO: Log an error
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the key has changed, update the row data
|
||||
if ( col && col.key != newKey ) {
|
||||
var rows = this.dataTable.getRecordSet().getRecords();
|
||||
for ( var i = 0; i < rows.length; i++ ) {
|
||||
rows[ i ].setData( newKey, rows[ i ].getData( oldKey ) );
|
||||
rows[ i ].setData( oldKey, undefined );
|
||||
}
|
||||
}
|
||||
|
||||
// Change the column info
|
||||
var newCol = {
|
||||
key : newKey,
|
||||
formatter : format,
|
||||
resizeable : ( col ? col.resizeable : 1 ),
|
||||
sortable : ( col ? col.sortable : 1 )
|
||||
};
|
||||
var newIndex = col ? col.getKeyIndex() : undefined;
|
||||
|
||||
// Set the editor
|
||||
if ( format == "date" ) {
|
||||
newCol.editor = "date";
|
||||
}
|
||||
else {
|
||||
newCol.editor = "textbox";
|
||||
}
|
||||
|
||||
this.dataTable.insertColumn( newCol, newIndex );
|
||||
if ( col ) {
|
||||
// Get a new reference so we remove the right column
|
||||
var delCol;
|
||||
if ( oldKey == newKey ) {
|
||||
delCol = this.dataTable.getColumn( oldKey )[1];
|
||||
}
|
||||
else {
|
||||
delCol = this.dataTable.getColumn( oldKey );
|
||||
}
|
||||
this.dataTable.removeColumn( delCol );
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
this.dataTable.render();
|
||||
this.schemaDialog.cancel();
|
||||
}
|
||||
|
||||
};
|
||||
86
www/extras/yui-webgui/build/i18n/i18n.js
vendored
Normal file
86
www/extras/yui-webgui/build/i18n/i18n.js
vendored
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
|
||||
// Initialize namespace
|
||||
if (typeof WebGUI == "undefined") {
|
||||
var WebGUI = {};
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* WebGUI.i18n ( { options } )
|
||||
* Initialize an i18n object. Options is an object with the following keys:
|
||||
* - url : (Optional) Specify a URL to a WebGUI site. Do not include the query string
|
||||
* - namespaces : (Optional) Object of arrays of namespaces to preload. Keys are namespace names,
|
||||
* and array members are i18n entries to get.
|
||||
* - onpreload : (Optional) Callback object for after the i18n is loaded.
|
||||
* fn : The function to call
|
||||
* obj : An object to pass to the function
|
||||
* override : If true, the function will be called in "obj" scope
|
||||
* Requires: YUI Event, YUI Connect, and YUI JSON
|
||||
* Events:
|
||||
* - preload : Fired when preloading is complete
|
||||
*/
|
||||
WebGUI.i18n
|
||||
= function ( opt ) {
|
||||
this.url = opt.url || "";
|
||||
this.namespaces = {};
|
||||
|
||||
this.evPreload = this.createEvent( "preload" );
|
||||
if ( opt.onpreload ) {
|
||||
this.subscribe( "preload", opt.onpreload.fn, opt.onpreload.obj, opt.onpreload.override );
|
||||
}
|
||||
|
||||
if ( opt.namespaces ) {
|
||||
this.load( opt.namespaces, true );
|
||||
}
|
||||
};
|
||||
|
||||
YAHOO.lang.augmentProto( WebGUI.i18n, YAHOO.util.EventProvider );
|
||||
|
||||
/****************************************************************************
|
||||
* get( ns, key )
|
||||
* Return the string referenced by namespace and key. If the namespace and key
|
||||
* have not yet been retrieved, get it from the WebGUI server.
|
||||
*/
|
||||
WebGUI.i18n.prototype.get
|
||||
= function ( ns, key ) {
|
||||
if ( typeof this.namespaces[ ns ][ key ] == "undefined" ) {
|
||||
this.load( ns, [ key ] );
|
||||
}
|
||||
return this.namespaces[ ns ][ key ];
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* load( { ns : keys, ns : keys, ... }, preload )
|
||||
* Grab the requested namespace / keys from the WebGUI server.
|
||||
* keys is an array of keys to get.
|
||||
* If preload is defined, will fire off the preload event
|
||||
*/
|
||||
WebGUI.i18n.prototype.load
|
||||
= function ( obj, preload ) {
|
||||
var requestUrl = this.url + "?op=ajaxGetI18N"
|
||||
var callback = {
|
||||
failure : function ( o, preload ) {
|
||||
// TODO: YUI logger for this
|
||||
console.log( "Could not load i18n" );
|
||||
},
|
||||
success : function ( o ) {
|
||||
var responseObj = YAHOO.lang.JSON.parse( o.responseText );
|
||||
for ( var ns in responseObj ) {
|
||||
for ( var key in responseObj[ ns ] ) {
|
||||
if ( !this.namespaces[ ns ] ) {
|
||||
this.namespaces[ ns ] = {};
|
||||
}
|
||||
this.namespaces[ ns ][ key ] = responseObj[ ns ][ key ];
|
||||
}
|
||||
}
|
||||
if ( o.argument.preload ) {
|
||||
this.fireEvent( "preload" );
|
||||
}
|
||||
},
|
||||
scope : this,
|
||||
argument : { preload : preload }
|
||||
};
|
||||
|
||||
var postJson = 'request=' + YAHOO.lang.JSON.stringify( obj );
|
||||
|
||||
YAHOO.util.Connect.asyncRequest( "POST", requestUrl, callback, postJson );
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue