Skip to content

Commit

Permalink
Item8537: Several fixes
Browse files Browse the repository at this point in the history
- Plugin can now accept that you unselect all values in multi value fields
- Plugin is more robust against leading and trailing white space and non-prefect comma lists of values
- Documentation improved
- Removed the disabled handler codenow know I willw I will not need


git-svn-id: http://svn.foswiki.org/trunk/MultiTopicSavePlugin@6371 0b4bb1d4-4e5a-0410-9cc4-b2b747904278
  • Loading branch information
KennethLavrsen authored and KennethLavrsen committed Feb 16, 2010
1 parent 357cd49 commit 0771dce
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 222 deletions.
4 changes: 3 additions & 1 deletion data/System/MultiTopicSavePlugin.txt
Expand Up @@ -17,12 +17,13 @@ In the following example the plugin is used to
* Make a formatted search which finds a number of topics
* Display selected fields in editable form. The field types are text, textarea, radio, checkbox, and select (all the formats supported by the plugin)
* Note that with field types where we want to know the content a field from each found topic, we need to delay the expansion of MULTITOPICSAVEINPUT till after the SEARCH is complete and has produced its result. This is why the macro is escaped by $percnt and $quot for the types radio, checkbox, and select.
* Note that for textareas we cannot use the SEARCH feature =$formfield= because it encodes newlines as &lt;br /&gt; (to avoid breaking tables) which is not desired when you want to show the current value in a text box. The example below uses %<nop>FORMFIELD% instead which does not perform any translation. Linebreaks will not break TML defined tables when they are inside a textarea field.

<verbatim>
<form action='%SCRIPTURL{"rest"}%/MultiTopicSavePlugin/multitopicsave' method="post">

%SEARCH{"MultiTopicSaveTestTarget" scope="topic" nonoise="on"
format="| $topic | %MULTITOPICSAVEINPUT{"Option" type="text" size="20" web="$web" topic="$topic" value="$formfield(Option)"}% | %MULTITOPICSAVEINPUT{"Description" type="textarea" web="$web" topic="$topic" size="20x4" value="$percntFORMFIELD{$quotDescription$quot web=$quot$web$quot topic=$quot$topic$quot}$percnt" }% | $percntMULTITOPICSAVEINPUT{$quotType$quot type=$quotradio$quot size=$quot2$quot web=$quot$web$quot topic=$quot$topic$quot value=$quot$formfield(Type)$quot options=$quotBoolean, Integer, String, Discrete Strings$quot }$percnt | $percntMULTITOPICSAVEINPUT{$quotDefault$quot type=$quotcheckbox$quot size=$quot2$quot web=$quot$web$quot topic=$quot$topic$quot value=$quot$formfield(Default)$quot options=$quotabe, kat, elefant, mus$quot }$percnt | $percntMULTITOPICSAVEINPUT{$quotThird$quot type=$quotselect$quot size=$quot0$quot multiple=$quoton$quot web=$quot$web$quot topic=$quot$topic$quot value=$quot$formfield(Third)$quot options=$quotabe, kat, elefant, mus$quot }$percnt |"
format="| $topic | %MULTITOPICSAVEINPUT{"Option" type="text" size="20" web="$web" topic="$topic" value="$formfield(Option)"}% | %MULTITOPICSAVEINPUT{"Description" type="textarea" web="$web" topic="$topic" size="20x4" value="$percntFORMFIELD{$quotDescription$quot web=$quot$web$quot topic=$quot$topic$quot}$percnt" }% | $percntMULTITOPICSAVEINPUT{$quotType$quot type=$quotradio$quot size=$quot2$quot web=$quot$web$quot topic=$quot$topic$quot value=$quot$formfield(Type)$quot options=$quotBoolean, Integer, String, Discrete Strings$quot }$percnt | $percntMULTITOPICSAVEINPUT{$quotDefault$quot type=$quotcheckbox$quot size=$quot2$quot web=$quot$web$quot topic=$quot$topic$quot value=$quot$formfield(Default)$quot options=$quotape, cat, elephant, mouse$quot }$percnt | $percntMULTITOPICSAVEINPUT{$quotThird$quot type=$quotselect$quot size=$quot0$quot multiple=$quoton$quot web=$quot$web$quot topic=$quot$topic$quot value=$quot$formfield(Third)$quot options=$quotape, cat, elephant, mouse$quot }$percnt |"
}%

%MULTITOPICSAVESUBMIT{"Submit all changes"}%
Expand Down Expand Up @@ -74,6 +75,7 @@ To ease this task you can use the MULTITOPICSAVESUBMIT which creates a submit bu
* value = the value that is put in the field by default
* options = the values to choose between for types radio, select etc. This value is ignored for text and textarea. Options are separated by commas, example: options="dog, cat, horse"


<!--
One line description, required for extensions repository catalog.
* Set SHORTDESCRIPTION = %$SHORTDESCRIPTION%
Expand Down
249 changes: 28 additions & 221 deletions lib/Foswiki/Plugins/MultiTopicSavePlugin.pm
Expand Up @@ -133,7 +133,7 @@ sub _MULTITOPICSAVESUBMIT {
my $result = "<input type='hidden' name='redirectweb' value='%WEB%' />" .
"<input type='hidden' name='redirecttopic' value='%TOPIC%' />" .
"<input type='submit' value='";
$result .= $params->{_DEFAULT};
$result .= $params->{_DEFAULT} || "Submit All Changes";
$result .= "' />";

return $result;
Expand Down Expand Up @@ -167,10 +167,19 @@ sub _MULTITOPICSAVEINPUT {
$targettopic = "$targetweb.$targettopic";
my $multiple = $params->{multiple} || 0;
my $field = $params->{_DEFAULT};

# For single value we leave leading and trailing space. For multiple value
# fields it is better for the user that we remove leading and trailing
# spaces as they are most like unwanted in these cases.
my $value = defined $params->{value} ? $params->{value} : '';
my @values = split( / *, */, $value );
my @values = map { s/^\s*(.*?)\s*$/$1/; $_; } split( /\s*,\s*/, $value );

my @options = defined $params->{options} ? split(/ *, */, $params->{options} ) : ();
# We assume all leading and trailing spaces are unwanted.
my @options = ();
if ( defined $params->{options} ) {
@options = map { s/^\s*(.*?)\s*$/$1/; $_; }
split( /\s*,\s*/, $params->{options} );
}

if ( $type eq 'text' ) {
$result = "<input class='foswikiInputField' type='text' ";
Expand Down Expand Up @@ -211,6 +220,11 @@ sub _MULTITOPICSAVEINPUT {
}
$result .= "</tr>" if ( $counter != $initcounter );
$result .= "</table>";

# We need a dummy hidden field to be able to send
# none of the checkboxes selected from the browser
$result .= "<input type='hidden' name='multitopicsavefield{$targettopic}{$field}' value=''>"
if ($type eq 'checkbox');
}
elsif ( $type eq 'select' ) {
$result = "<select "
Expand All @@ -236,228 +250,16 @@ sub _MULTITOPICSAVEINPUT {
}

$result .= "</select>";

# We need a dummy hidden field to be able to send
# none of the checkboxes selected from the browser
$result .= "<input type='hidden' name='multitopicsavefield{$targettopic}{$field}' value=''>";
}
# else if the type is unknown we return nothing

return $result;
}

=BEGIN TML
---++ commonTagsHandler($text, $topic, $web, $included, $meta )
* =$text= - text to be processed
* =$topic= - the name of the topic in the current CGI query
* =$web= - the name of the web in the current CGI query
* =$included= - Boolean flag indicating whether the handler is
invoked on an included topic
* =$meta= - meta-data object for the topic MAY BE =undef=
This handler is called by the code that expands %<nop>MACROS% syntax in
the topic body and in form fields. It may be called many times while
a topic is being rendered.
Only plugins that have to parse the entire topic content should implement
this function. For expanding macros with trivial syntax it is *far* more
efficient to use =Foswiki::Func::registerTagHandler= (see =initPlugin=).
Internal Foswiki macros, (and any macros declared using
=Foswiki::Func::registerTagHandler=) are expanded _before_, and then again
_after_, this function is called to ensure all %<nop>MACROS% are expanded.
*NOTE:* when this handler is called, &lt;verbatim> blocks have been
removed from the text (though all other blocks such as &lt;pre> and
&lt;noautolink> are still present).
*NOTE:* meta-data is _not_ embedded in the text passed to this
handler. Use the =$meta= object.
*Since:* $Foswiki::Plugins::VERSION 2.0
=cut

#sub commonTagsHandler {
# my ( $text, $topic, $web, $included, $meta ) = @_;
#
# # If you don't want to be called from nested includes...
# # if( $included ) {
# # # bail out, handler called from an %INCLUDE{}%
# # return;
# # }
#
# # You can work on $text in place by using the special perl
# # variable $_[0]. These allow you to operate on $text
# # as if it was passed by reference; for example:
# # $_[0] =~ s/SpecialString/my alternative/ge;
#}

=begin TML
---++ beforeCommonTagsHandler($text, $topic, $web, $meta )
* =$text= - text to be processed
* =$topic= - the name of the topic in the current CGI query
* =$web= - the name of the web in the current CGI query
* =$meta= - meta-data object for the topic MAY BE =undef=
This handler is called before Foswiki does any expansion of its own
internal variables. It is designed for use by cache plugins. Note that
when this handler is called, &lt;verbatim> blocks are still present
in the text.
*NOTE*: This handler is called once for each call to
=commonTagsHandler= i.e. it may be called many times during the
rendering of a topic.
*NOTE:* meta-data is _not_ embedded in the text passed to this
handler.
*NOTE:* This handler is not separately called on included topics.
=cut

#sub beforeCommonTagsHandler {
# my ( $text, $topic, $web, $meta ) = @_;
#
# # You can work on $text in place by using the special perl
# # variable $_[0]. These allow you to operate on $text
# # as if it was passed by reference; for example:
# # $_[0] =~ s/SpecialString/my alternative/ge;
#}

=begin TML
---++ afterCommonTagsHandler($text, $topic, $web, $meta )
* =$text= - text to be processed
* =$topic= - the name of the topic in the current CGI query
* =$web= - the name of the web in the current CGI query
* =$meta= - meta-data object for the topic MAY BE =undef=
This handler is called after Foswiki has completed expansion of %MACROS%.
It is designed for use by cache plugins. Note that when this handler
is called, &lt;verbatim> blocks are present in the text.
*NOTE*: This handler is called once for each call to
=commonTagsHandler= i.e. it may be called many times during the
rendering of a topic.
*NOTE:* meta-data is _not_ embedded in the text passed to this
handler.
=cut

#sub afterCommonTagsHandler {
# my ( $text, $topic, $web, $meta ) = @_;
#
# # You can work on $text in place by using the special perl
# # variable $_[0]. These allow you to operate on $text
# # as if it was passed by reference; for example:
# # $_[0] =~ s/SpecialString/my alternative/ge;
#}

=begin TML
---++ preRenderingHandler( $text, \%map )
* =$text= - text, with the head, verbatim and pre blocks replaced
with placeholders
* =\%removed= - reference to a hash that maps the placeholders to
the removed blocks.
Handler called immediately before Foswiki syntax structures (such as lists) are
processed, but after all variables have been expanded. Use this handler to
process special syntax only recognised by your plugin.
Placeholders are text strings constructed using the tag name and a
sequence number e.g. 'pre1', "verbatim6", "head1" etc. Placeholders are
inserted into the text inside &lt;!--!marker!--&gt; characters so the
text will contain &lt;!--!pre1!--&gt; for placeholder pre1.
Each removed block is represented by the block text and the parameters
passed to the tag (usually empty) e.g. for
<verbatim>
<pre class='slobadob'>
XYZ
</pre>
</verbatim>
the map will contain:
<pre>
$removed->{'pre1'}{text}: XYZ
$removed->{'pre1'}{params}: class="slobadob"
</pre>
Iterating over blocks for a single tag is easy. For example, to prepend a
line number to every line of every pre block you might use this code:
<verbatim>
foreach my $placeholder ( keys %$map ) {
if( $placeholder =~ /^pre/i ) {
my $n = 1;
$map->{$placeholder}{text} =~ s/^/$n++/gem;
}
}
</verbatim>
__NOTE__: This handler is called once for each rendered block of text i.e.
it may be called several times during the rendering of a topic.
*NOTE:* meta-data is _not_ embedded in the text passed to this
handler.
Since Foswiki::Plugins::VERSION = '2.0'
=cut

#sub preRenderingHandler {
# my( $text, $pMap ) = @_;
#
# # You can work on $text in place by using the special perl
# # variable $_[0]. These allow you to operate on $text
# # as if it was passed by reference; for example:
# # $_[0] =~ s/SpecialString/my alternative/ge;
#}

=begin TML
---++ postRenderingHandler( $text )
* =$text= - the text that has just been rendered. May be modified in place.
*NOTE*: This handler is called once for each rendered block of text i.e.
it may be called several times during the rendering of a topic.
*NOTE:* meta-data is _not_ embedded in the text passed to this
handler.
Since Foswiki::Plugins::VERSION = '2.0'
=cut

#sub postRenderingHandler {
# my $text = shift;
# # You can work on $text in place by using the special perl
# # variable $_[0]. These allow you to operate on $text
# # as if it was passed by reference; for example:
# # $_[0] =~ s/SpecialString/my alternative/ge;
#}


=begin TML
---++ modifyHeaderHandler( \%headers, $query )
* =\%headers= - reference to a hash of existing header values
* =$query= - reference to CGI query object
Lets the plugin modify the HTTP headers that will be emitted when a
page is written to the browser. \%headers= will contain the headers
proposed by the core, plus any modifications made by other plugins that also
implement this method that come earlier in the plugins list.
<verbatim>
$headers->{expires} = '+1h';
</verbatim>
Note that this is the HTTP header which is _not_ the same as the HTML
&lt;HEAD&gt; tag. The contents of the &lt;HEAD&gt; tag may be manipulated
using the =Foswiki::Func::addToHEAD= method.
*Since:* Foswiki::Plugins::VERSION 2.0
=cut

#sub modifyHeaderHandler {
# my ( $headers, $query ) = @_;
#}


=begin TML
---++ restMultiTopicSave($session) -> $text
Expand Down Expand Up @@ -503,8 +305,13 @@ sub restMultiTopicSave {

my $topic = $1;
my $fieldName = $2;
my @fieldValues = $query->param($key);

$parameters{$topic}{$fieldName} = join(", ", $query->param($key) );
# Remove empty values, they are most likely dummy values used
# to indicate that no value in a multiple checkbox or select
# is selected
@fieldValues = grep( /.+/, @fieldValues);
$parameters{$topic}{$fieldName} = join(", ", @fieldValues );
}
}

Expand Down

0 comments on commit 0771dce

Please sign in to comment.