Skip to content

Commit

Permalink
Item11140: recoded to only instrument the table when the rows are act…
Browse files Browse the repository at this point in the history
…ually rolled over. Reduced the amount of HTML generated by the server enormously, by making some assumptions in the JS and leveraging the foswiki plugin

git-svn-id: http://svn.foswiki.org/trunk@13287 0b4bb1d4-4e5a-0410-9cc4-b2b747904278
  • Loading branch information
CrawfordCurrie authored and CrawfordCurrie committed Dec 3, 2011
1 parent fecb4ba commit 91ffef6
Show file tree
Hide file tree
Showing 9 changed files with 226 additions and 156 deletions.
11 changes: 6 additions & 5 deletions EditRowPlugin/data/System/EditRowPlugin.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ Features:
Javascript table editors to use the same interface to save.
1 (geeky) Tolerant to Javascript being disabled in the browser

Note that this plugin is designed for use with tables of up to ~1000 cells. Tables
larger than this will work, but they put huge stress on the browser and the server.
For manipulating larger tables, you are recommended to investigate
Note that this plugin is designed for use with tables of up to ~1000 rows. Tables
larger than this will work, but they put considerable stress on the browser
and the server. For manipulating larger tables, you are recommended to investigate
Foswiki:Extensions.JQGridPlugin.

---++ Usage
Expand Down Expand Up @@ -170,10 +170,10 @@ then="enabled in this site. Click on the buttons to try it out."}%

---+++ Javascript Editing
<img src="%ATTACHURLPATH%/screenshot2.png" style="float:right" />
When a table is editable and Javascript is enabled, then:
When a table is editable and Javascript is enabled, then when the user rolls the mouse over a table row:
* individual table cells have a yellow stain <img src="%ATTACHURL%/editbutton.png"> on the corner that can be clicked to open an in-place editor,
* table rows can be manually sorted using drag-and-drop, by dragging the %UICON%arrowthick-2-n-s%NOCIU% (though beware that a =TABLE= tag with an =initsort= will override this, which can be confusing),
* table columns can be sorted in the browser, by clicking the heading above the row.
Table columns can be sorted in the browser, by clicking the heading above the row.

%X% The Javascript editor works on the content of the cell _after it has been rendered_. This means that if you use TML inside table cells - for example, highlighting, or topic links - then you will be editing the expanded HTML and *not* the source TML. This is a tradeoff; Javascript gives high performance when editing large tables, at the cost of this feature.

Expand Down Expand Up @@ -243,6 +243,7 @@ Another great Foswiki extension from the <a style="text-decoration:none" href="h
| Copyright: | &copy; 2007-2011 Wind<nop>River Inc. |
| License: | [[http://www.gnu.org/licenses/gpl.html][GPL (Gnu General Public License)]] |
| Change History: | <!-- versions below in reverse order -->&nbsp; |
| 3.0.0 (3 Dec 2011) | Foswiki:Tasks/Item11140: recoded to only instrument the table when the rows are actually rolled over. Reduced the amount of HTML generated by the server enormously. |
| 2.2.9 (7 Oct 2011) | Foswiki:Tasks/Item11140: optimisations for use with very large tables |
| 2.2.8 (8 Aug 2011) | Foswiki:Tasks/Item11028: JS date editor now picks up existing value Foswiki:Tasks/Item11029: JS date editor now uses consistent date formats |
| 2.2.7 (03 Aug 2011) | Foswiki:Tasks/Item11010: better default for editable cell width Foswiki:Tasks/Item11018: fixed date format in non-JS edit mode |
Expand Down
5 changes: 3 additions & 2 deletions EditRowPlugin/lib/Foswiki/Plugins/EditRowPlugin.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package Foswiki::Plugins::EditRowPlugin;
use strict;

our $VERSION = '$Rev$';
our $RELEASE = '2.2.9';
our $RELEASE = '3.0.0';
our $SHORTDESCRIPTION = 'Inline edit for tables';
our $NO_PREFS_IN_TOPIC = 1;

Expand Down Expand Up @@ -51,10 +51,11 @@ sub save {
# Replace content with a marker to prevent it being munged by Foswiki
our @refs;

# $dequote is true if the result is to be embedded in double-quotes
sub defend {
my ($text, $dequote) = @_;
my $n = scalar(@refs);
$text =~ s/"/&quot;/g if $dequote;
$text =~ s/"/&#34;/g if $dequote;
push( @refs, $text );
return "#\07$n\07#";
}
Expand Down
14 changes: 4 additions & 10 deletions EditRowPlugin/lib/Foswiki/Plugins/EditRowPlugin/Editor.pm
Original file line number Diff line number Diff line change
Expand Up @@ -77,27 +77,21 @@ sub jQueryMetadata {
} else {
$data->{size} = 10; # chars, must convert to px
}
# By default we respond to an internally-raised edit event, which is raised
# when the cell edit icon is clicked
$data->{event} = "erp_edit";
# Silence the noisy "Click to edit" placeholder
$data->{placeholder} = '<div class="erp_empty"></div>';
$data->{tooltip} = '';
return $data;
}

sub _addSaveButton {
my ($this, $data) = @_;
my $purl = Foswiki::Func::getPubUrlPath();
$data->{submit} =
"<button type'submit'><img src='$purl/System/EditRowPlugin/save.png' /></button>";
# JS will rewrite this URL to some HTML
$data->{submitimg} = "save.png";
}

sub _addCancelButton {
my ($this, $data) = @_;
my $purl = Foswiki::Func::getPubUrlPath();
$data->{cancel} =
"<button type'submit'><img src='$purl/System/EditRowPlugin/stop.png' /></button>";
# JS will rewrite this URL to some HTML
$data->{cancelimg} = "stop.png";
}

=begin TML
Expand Down
38 changes: 19 additions & 19 deletions EditRowPlugin/lib/Foswiki/Plugins/EditRowPlugin/Table.pm
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ sub render {
|| (!$editing &&
$opts->{with_controls} && $this->{attrs}->{disable} !~ /row/ ) ) );

$row_opts{first_row} = 1;
foreach my $row ( @{ $this->{rows} } ) {
my $isLard = ( $row->{isHeader} || $row->{isFooter} );
$n++ unless $isLard;
Expand All @@ -270,16 +271,17 @@ sub render {
# Get the row from the real_table, read raw from the topic
my $real_row = $opts->{real_table} ?
$opts->{real_table}->{rows}->[ $r - 1 ] : $row;
next unless $real_row;
$rowtext =
$real_row->render({ %row_opts,
for_edit => 1,
orient => $orientation });
if ( $real_row ) {
push( @out,
$real_row->render({ %row_opts,
for_edit => 1,
orient => $orientation}));
}
}
else {
$rowtext = $row->render(\%row_opts);
push( @out, $row->render(\%row_opts));
}
push( @out, $rowtext );
$row_opts{first_row} = 0 unless $isLard;
}
if ($editing) {
if ($wholeTable && $this->{attrs}->{js} ne 'assumed') {
Expand Down Expand Up @@ -346,12 +348,13 @@ sub render {
# erp_unchanged=1 prevents addRow from trying to
# save changes in the table. erp_active_row is set to -2
# so that addRow enters single row editing mode (see sub addRow)
$url = $this->getSaveURL(
erp_active_row => -2,
erp_unchanged => 1,
erp_action => 'addRow',
'#' => 'erp_' . $this->{id}
);
$url = Foswiki::Func::getScriptUrl(
'EditRowPlugin', 'save', 'rest',
%{$this->getURLParams(
erp_active_row => -2,
erp_unchanged => 1,
erp_action => 'addRow',
'#' => 'erp_' . $this->{id})});

# Full table disabled, but not row
push( @out, "<a href='$url' title='$title'>$button</a><br />" );
Expand All @@ -365,18 +368,15 @@ sub can_edit {
return $this->{editable};
}

# Override this if you want to use a different rest handler in a subclass
# or derived plugin.
sub getSaveURL {
sub getURLParams {
my ($this, %more) = @_;
# Get the active (most recent) version number for the topic with this table
my @ri = Foswiki::Func::getRevisionInfo($this->{web}, $this->{topic});
return Foswiki::Func::getScriptUrl(
'EditRowPlugin', 'save', 'rest',
return {
erp_active_topic => "$this->{web}.$this->{topic}",
erp_active_version => "$ri[2]_$ri[0]",
erp_active_table => $this->{id},
%more);
%more };
}

# Get the "type object" for this column definition (one of the Editor classes)
Expand Down
51 changes: 25 additions & 26 deletions EditRowPlugin/lib/Foswiki/Plugins/EditRowPlugin/TableCell.pm
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ sub render {

my $colDef = $opts->{col_defs}->[ $this->{number} - 1 ] || $defCol;
my $text = $this->{text};

if ( $text =~ s/%EDITCELL{(.*?)}%// ) {
my %p = Foswiki::Func::extractParameters($1);
my $cd = $this->{row}->{table}->parseFormat($p{_DEFAULT});
Expand Down Expand Up @@ -128,35 +127,34 @@ sub render {
my $data = $editor->jQueryMetadata($this, $colDef, $text);
# Editors can set "uneditable" if the cell is not to have an editor
unless ($data->{uneditable}) {
if ($opts->{js} ne 'ignored') {
# The "edit this cell" trigger button (yellow stain)
$trigger = CGI::div(
{
class =>'erpJS_editButton',
title => 'Click to edit'
}, '');
}
my $saveURL = $this->getSaveURL();
# Carve off the URL params and push to meta-data; they are wanted
# for ajax.
if ($saveURL =~ s/\?(.*)$//) {
$data->{erp_data} = {};
for my $tup (split(/[;&]/, $1)) {
$tup =~ /(.*?)=(.*)$/;
$data->{erp_data}->{$1} = $2;
#if ($opts->{js} ne 'ignored') {
# add any edit-specific HTML here
#}
my @css_classes = ('erpJS_cell');
# Because we generate a TML table, we have no way to attach table meta-data
# and row meta-data. So we attach it to the first cell in the table/row, and
# move it to the right place when JS loads.
if ($opts->{first_col}) {
$data->{trdata} = $this->{row}->getURLParams();
push( @css_classes, 'erpJS_trdata' );
if ($opts->{first_row}) {
my $tabledata = $this->{row}->{table}->getURLParams();
$data->{tabledata} = $tabledata;
push( @css_classes, 'erpJS_tabledata' );
}
}
$data->{url} = $saveURL;
# Add the cell data
$data = $this->getURLParams(%$data);
# Note: Any table row that has a cell with erpJS_cell will be made draggable
if ($opts->{js} ne 'ignored') {
$sopts->{class} = 'erpJS_cell '
. Foswiki::Plugins::EditRowPlugin::defend(JSON::to_json($data), 1);
$sopts->{class} = join(' ', @css_classes) . ' ' . JSON::to_json($data);
}
}
}
my $a = {};
$a->{class} = 'erpJS_container' unless $opts->{js} eq 'ignored';
$text = CGI::div($a, CGI::span( $sopts, " $text ") . $trigger);
#my $a = {};
#$a->{class} = 'erpJS_container' unless $opts->{js} eq 'ignored';
#$text = CGI::div($a, CGI::span( $sopts, " $text "));
$text = CGI::span( $sopts, " $text ");
}
}
return $this->{precruft} . $text . $this->{postcruft};
Expand All @@ -167,11 +165,12 @@ sub can_edit {
return $this->{row}->can_edit();
}

sub getSaveURL {
sub getURLParams {
my ($this, %more) = @_;
return $this->{row}->getSaveURL(
return {
%more,
noredirect => 1,
erp_active_col => $this->{number}, %more);
erp_active_col => $this->{number} };
}

1;
Expand Down
22 changes: 12 additions & 10 deletions EditRowPlugin/lib/Foswiki/Plugins/EditRowPlugin/TableRow.pm
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ sub can_edit {
return $this->{table}->can_edit();
}

sub getSaveURL {
sub getURLParams {
my ($this, %more) = @_;
return $this->{table}->getSaveURL(erp_active_row => $this->{number}, %more);
return { erp_active_row => $this->{number}, %more };
}

# col_defs - column definitions (required)
Expand Down Expand Up @@ -148,6 +148,7 @@ sub render {
my $hdrs = $this->{table}->getLabelRow();
my $col = 0;
my @rows;
my $first_col = 1;
foreach my $cell ( @{ $this->{cols} } ) {

# get the column label
Expand All @@ -156,11 +157,14 @@ sub render {
my $text = $cell->render({
col_defs => $opts->{col_defs},
in_row => $this,
for_edit => 1} );
for_edit => 1,
first_row => $opts->{first_row},
first_col => $first_col} );

push( @rows, "| $hdr|$text$anchor|$empties" );
$anchor = '';
$col++;
$first_col = 0;
}
if ($opts->{with_controls}) {
push( @rows, "| $buttons ||$empties" );
Expand All @@ -173,9 +177,11 @@ sub render {
my $text;

$opts->{in_row} = $this;
$opts->{first_col} = 1;
foreach my $cell ( @{ $this->{cols} } ) {

$text = $cell->render($opts);
$opts->{first_col} = 0;

# Add the row anchor for editing. It's added to the first non-empty
# cell or, failing that, the first cell. This is to minimise the
Expand Down Expand Up @@ -246,13 +252,9 @@ sub render {
$buttons .= $anchor;
$addAnchor = 0;
}
if ($opts->{js} ne 'ignored') {
# Add container wrapper for JS.
# We forcibly add the row-drag link here because adding it in JS is so
# slow.
# The JS must add ui-icon, though.
$buttons = "<div class='erpJS_container'><a href='#' class='ui-icon-arrow-2-n-s erp_drag_button' title='Click and drag to move row'>move</a>$buttons</div>";
}
#if ($opts->{js} ne 'ignored') {
# add any other HTML for handling rows here
#}
if ($buttons_right) {
push( @cols, $buttons );
} else {
Expand Down
3 changes: 2 additions & 1 deletion EditRowPlugin/lib/Foswiki/Plugins/EditRowPlugin/View.pm
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ sub process {

my $active_row = $urps->{erp_active_row};
unless ($table->{attrs}->{js} eq 'assumed') {
my $saveUrl = $_->getSaveURL();
my $saveUrl = Foswiki::Func::getScriptUrl(
'EditRowPlugin', 'save', 'rest', %{$_->getURLParams()});
$line .= CGI::start_form(
-method => 'POST',
-name => "erp_form_${macro}_$active_table",
Expand Down
9 changes: 7 additions & 2 deletions EditRowPlugin/pub/System/EditRowPlugin/erp_src.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
}

.erpJS_container {
position: relative; /* so it can be a container for erpJS_editButton */
position: relative;
margin: 0;
padding: 0;
}
Expand Down Expand Up @@ -48,7 +48,12 @@
position: absolute;
display: none;
left: -1.7em;
top: 0;
top: -1.25em;
}

a.erp_drag_button:hover {
background-image: url("ui-icons-famfamfam.png");
background-color: #FEE;
}

.erpNoJS_button {
Expand Down
Loading

0 comments on commit 91ffef6

Please sign in to comment.