diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index b38b13468..d474ae6dd 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -41,6 +41,7 @@ - Report errors on loading modules to Apache log during preload - fix: Use previous form value for Subscribe on CS preview - Use current subscription status on form for CS reply, unsubscribe if set to no + - add: WebGUI::Form::CheckList now has optional "Select All" button 7.4.5 - fix: Apostrophy incorrectly escaped as double quote in some places diff --git a/lib/WebGUI/Form/CheckList.pm b/lib/WebGUI/Form/CheckList.pm index 48fd981ce..6ee9e0b14 100644 --- a/lib/WebGUI/Form/CheckList.pm +++ b/lib/WebGUI/Form/CheckList.pm @@ -17,6 +17,8 @@ package WebGUI::Form::CheckList; use strict; use base 'WebGUI::Form::List'; use WebGUI::Form::Checkbox; +use WebGUI::Form::Button; +use WebGUI::International; =head1 NAME @@ -54,25 +56,61 @@ Boolean representing whether the checklist should be represented vertically or h Flag that tells the User Profile system that this is a valid form element in a User Profile +=head4 showSelectAllButton + +Flag that toggles a "Select All" toggle button on or off. + =cut sub definition { - my $class = shift; - my $session = shift; - my $definition = shift || []; - my $i18n = WebGUI::International->new($session); - push(@{$definition}, { - formName=>{ - defaultValue=>$i18n->get("941"), - }, - vertical=>{ - defaultValue=>0 - }, - profileEnabled=>{ - defaultValue=>1 - } - }); - return $class->SUPER::definition($session, $definition); + my $class = shift; + my $session = shift; + my $definition = shift || []; + my $i18n = WebGUI::International->new($session); + push @{$definition}, { + formName => { + defaultValue => $i18n->get("941"), + }, + vertical => { + defaultValue => 0, + }, + profileEnabled => { + defaultValue => 1, + }, + showSelectAll => { + defaultValue => 0, + }, + }; + return $class->SUPER::definition($session, $definition); +} + +#------------------------------------------------------------------- + +=head2 getSelectAllButton ( ) + +Returns the HTML / Script for the Select All button + +=cut + +sub getSelectAllButton { + my $self = shift; + my $formName = $self->get('name'); + my $i18n = WebGUI::International->new($self->session, "Form_CheckList"); + + $self->session->style->setScript( + $self->session->url->extras("yui-webgui/build/form/form.js") + ); + + return WebGUI::Form::Button->new($self->session, { + name => $self->privateName('selectAllButton'), + value => $i18n->get("selectAll label"), + extras => q{onclick="WebGUI.Form.toggleAllCheckboxesInForm(this.form,'} + . $formName + . q{')"} + . q{ class="selectAllButton" }, + })->toHtml + . q{
} + ; } #------------------------------------------------------------------- @@ -84,28 +122,35 @@ Renders a series of checkboxes. =cut sub toHtml { - my $self = shift; + my $self = shift; my $output; - my $alignment = $self->alignmentSeparator; - my %options; - tie %options, 'Tie::IxHash'; - %options = $self->orderedHash(); + my $alignment = $self->alignmentSeparator; + + # Add the select all button + if ($self->get("showSelectAll")) { + $output .= $self->getSelectAllButton; + } + + tie my %options, 'Tie::IxHash', $self->orderedHash(); foreach my $key (keys %options) { - my $checked = 0; - foreach my $item (@{ $self->get('value') }) { - if ($item eq $key) { - $checked = 1; - } - } - $output .= WebGUI::Form::Checkbox->new($self->session,{ - name=>$self->get('name'), - value=>$key, - extras=>$self->get('extras'), - checked=>$checked - })->toHtml; - $output .= ${$self->get('options')}{$key} . $alignment; - } - return $output; + my $checked = (grep { $_ eq $key } @{ $self->get('value') }) + ? 1 + : 0 + ; + + $output + .= WebGUI::Form::Checkbox->new($self->session, { + name => $self->get('name'), + value => $key, + extras => $self->get('extras'), + checked => $checked, + })->toHtml + . ${$self->get('options')}{$key} + . $alignment + ; + } + + return $output; } 1; diff --git a/lib/WebGUI/i18n/English/Form_CheckList.pm b/lib/WebGUI/i18n/English/Form_CheckList.pm new file mode 100644 index 000000000..9c74bc803 --- /dev/null +++ b/lib/WebGUI/i18n/English/Form_CheckList.pm @@ -0,0 +1,17 @@ +package WebGUI::i18n::English::Form_CheckList; + +our $I18N = { + 'selectAll label' => { + message => q{Select All}, + lastUpdated => 0, + context => q{Label for the Select All button}, + }, + + 'topicName' => { + message => q|WebGUI Form CheckList|, + lastUpdated => 1131394072, + }, + +}; + +1; diff --git a/t/Form/CheckList.t b/t/Form/CheckList.t new file mode 100644 index 000000000..ef341f734 --- /dev/null +++ b/t/Form/CheckList.t @@ -0,0 +1,101 @@ +#------------------------------------------------------------------- +# WebGUI is Copyright 2001-2007 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 FindBin; +use strict; +use lib "$FindBin::Bin/../lib"; + +use Tie::IxHash; + +use WebGUI::Test; +use WebGUI::Form; +use WebGUI::Form::CheckList; +use WebGUI::Session; +use HTML::Form; +use WebGUI::Form_Checking; + +# The goal of this test is to verify that CheckList form elements work + +use Test::More; # increment this value for each test you create + +my $session = WebGUI::Test->session; + +# put your tests here + +my $formClass = 'WebGUI::Form::CheckList'; +my $formType = 'Checkbox'; + +my $numTests = 15; + + +plan tests => $numTests; + +my ($header, $footer) = (WebGUI::Form::formHeader($session), WebGUI::Form::formFooter($session)); + +tie my %options, 'Tie::IxHash', ( + foo => "Foo", + bar => "Bar", + baz => "Baz", +); + +my $html = join "\n", + $header, + $formClass->new($session, { + name => 'CList1', + value => ['foo'], + options => \%options, + })->toHtml, + $footer; + +my @forms = HTML::Form->parse($html, 'http://www.webgui.org'); + +##Test Form Generation + +is(scalar @forms, 1, '1 form was parsed to test basic functionality'); + +my @inputs = $forms[0]->inputs; +is(scalar @inputs, 3, 'The form has 3 inputs'); + +#Basic tests + +is($inputs[0]->name, 'CList1', 'Checking input name for checkbox 1'); +is($inputs[0]->type, 'checkbox', 'Checking input type for checkbox 1'); +is($inputs[0]->value, 'foo', 'Checking default value for checkbox 1'); +is($inputs[1]->name, 'CList1', 'Checking input name for checkbox 2'); +is($inputs[1]->type, 'checkbox', 'Checking input type for checkbox 2'); +is($inputs[1]->value, undef, 'Checking default value for checkbox 2'); +is($inputs[2]->name, 'CList1', 'Checking input name for checkbox 3'); +is($inputs[2]->type, 'checkbox', 'Checking input type for checkbox 3'); +is($inputs[2]->value, undef, 'Checking default value for checkbox 3'); + + + +### Test Generation of Select All button +my $html = join "\n", + $header, + $formClass->new($session, { + name => "CList1", + value => ['foo'], + options => \%options, + showSelectAll => 1, + })->toHtml, + $footer; + +@forms = HTML::Form->parse($html, 'http://www.webgui.org'); +is(scalar @forms, 1, '1 form was parsed to test showSelectAll'); + +@inputs = $forms[0]->inputs; +is(scalar @inputs, 4, 'The form has 4 inputs (1 button + 3 checkboxes)'); + +is($inputs[0]->type, 'button', 'The Select All button is there and before all checkboxes'); +is( $inputs[0]->{value}, + WebGUI::International->new($session,"Form_CheckList")->get("selectAll label"), + 'The value is internationalized' +); diff --git a/www/extras/yui-webgui/build/form/form.js b/www/extras/yui-webgui/build/form/form.js new file mode 100644 index 000000000..eb4f3c7e0 --- /dev/null +++ b/www/extras/yui-webgui/build/form/form.js @@ -0,0 +1,48 @@ + +// Initialize namespace +if (typeof WebGUI == "undefined") { + var WebGUI = {}; +} +if (typeof WebGUI.Form == "undefined") { + WebGUI.Form = {}; +} + + +/** + * This object contains generic form modification functions + */ + +/**************************************************************************** + * WebGUI.Form.toggleAllCheckboxesInForm ( formElement [, checkboxesName] ) + * Toggles all the checkboxes in the form, optionally limited by name. + * Will automatically set them all to "checked" the first time + */ +WebGUI.Form.toggleAllCheckboxesInForm + = function (formElement, checkboxesName) { + // Get the state to set + var oldState = WebGUI.Form.toggleAllCheckboxesState[formElement+checkboxesName] + var state = oldState ? "" : "checked"; + + for (var i in formElement.elements) { + var input = formElement.elements[i]; + if (!/^check/.test(input.type)) + continue; + if (checkboxesName && input.name != checkboxesName) + continue; + + input.checked = state; + } + + // Update the saved state + WebGUI.Form.toggleAllCheckboxesState[formElement+checkboxesName] = state; + }; + + +/* + * WebGUI.Form.toggleAllCheckboxesState + * An object containing a hash of + : 0|1 to save + * the state of the toggled checkboxes. You can use this to set what the + * first run of toggleAllCheckboxesInForm will do. + */ +WebGUI.Form.toggleAllCheckboxesState = {}; +