diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index 0fe5c8bfe..59be7785e 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -4,6 +4,7 @@ (Amir Plivatsky) - fixed #12179: DataTable Field types get reset to "Text" in Edit Schema (Amir Plivatsky) + - added: FormField macro for rendering Form objects directly from templates 7.10.19 - fixed #12169: extras uploads symlink export diff --git a/etc/WebGUI.conf.original b/etc/WebGUI.conf.original index 2a9c48b41..eb8f4af0f 100644 --- a/etc/WebGUI.conf.original +++ b/etc/WebGUI.conf.original @@ -832,6 +832,7 @@ "FetchMimeType" : "FetchMimeType", "FilePump" : "FilePump", "FileUrl" : "FileUrl", + "FormField" : "FormField", "GroupAdd" : "GroupAdd", "GroupDelete" : "GroupDelete", "GroupText" : "GroupText", diff --git a/lib/WebGUI/Macro/FormField.pm b/lib/WebGUI/Macro/FormField.pm new file mode 100644 index 000000000..ed8080c00 --- /dev/null +++ b/lib/WebGUI/Macro/FormField.pm @@ -0,0 +1,64 @@ +package WebGUI::Macro::FormField; + +#------------------------------------------------------------------- +# 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; + +=head1 NAME + +Package WebGUI::Macro::FormField + +=head1 DESCRIPTION + +Renders an instance of a Form object. + +=head2 process( $session, $type, $field_name [, $default_value, @form_constructor_arguments ] ) + +C<$type> is one of the L subclasses in L. + +C<$field_name> is the name the field will be given in the HTML "name" attribute. + +C<$default_value> is the currently selected value to use for the form field if no GET/POST parameter or field of the +current asset of the same name has a value. + +A form posted form parameter of the same name as the C<$field_name>, if present, will be used instead of the default. +Failing that, an attribute of the current asset of the same name, if present, will be used instead of the default value. + +C<@form_constructor_arguments> get passed to the L subclass constructor. + +=cut + + +sub process { + my $session = shift; + my $type = shift; + my $name = shift; + my $default_value = shift || ''; + my @extras = @_; + + my $form_class = "WebGUI::Form::" . ucfirst $type; + + my $value = $session->form->get($name); + $value ||= $session->asset->get($name) if $session->asset; + $value ||= $default_value; + + my $control = eval { WebGUI::Pluggable::instanciate($form_class, 'new', [ $session, { name => $name, value => $value, @extras } ]) }; + if ($@) { + $session->log->warn("FormField Macro could not load class ``$form_class'': $@"); + return ''; + } + + return $control->toHtml; +} + +1; + + diff --git a/t/Macro/FormField.t b/t/Macro/FormField.t new file mode 100644 index 000000000..bdcc66073 --- /dev/null +++ b/t/Macro/FormField.t @@ -0,0 +1,114 @@ +#------------------------------------------------------------------- +# WebGUI is Copyright 2001-2011 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 WebGUI::Test; +use WebGUI::Session; +use WebGUI::Macro::AdminBar; +use HTML::TokeParser; +use HTML::Form; +use Tie::IxHash; +use WebGUI::Form_Checking; +use WebGUI::Macro::FormField; + +use Test::More; # increment this value for each test you create +use Test::Deep; + +use Data::Dumper; + +my $session = WebGUI::Test->session; + +# taken from t/Form/SelectList.t + +my $testBlock = [ + { + key => 'List1', + testValue => [qw/a/], + expected => 'a', + comment => 'single element array, scalar', + dataType => 'SCALAR' + }, + { + key => 'List2', + testValue => [qw/a/], + expected => 'EQUAL', + comment => 'single element array, array', + dataType => 'ARRAY' + }, + { + key => 'List3', + testValue => [qw/a b c/], + expected => "a\nb\nc", + comment => 'multi element array, scalar', + dataType => 'SCALAR' + }, + { + key => 'List4', + testValue => [qw/a b c/], + expected => 'EQUAL', + comment => 'multi element array, array', + dataType => 'ARRAY' + }, +]; + +my $formType = 'SelectList'; + +my $output; +$output = WebGUI::Macro::FormField::process( + $session, 'SelectList', 'ListMultiple', [ qw(a c e), ''], # args to macro + # args to particular Form subclass + options => { a=>'aa', b=>'bb', c=>'cc', d=>'dd', e=>'ee', ''=>'Empty' }, + value => [ qw(a c e), ''], + sortByValue => 1, +); + +warn $output; + +my $numTests = 11 + scalar @{ $testBlock } + 1; + +plan tests => $numTests; + +my ($header, $footer) = (WebGUI::Form::formHeader($session), WebGUI::Form::formFooter($session)); + +my $html = join "\n", $header, $output, $footer; + +my @forms = HTML::Form->parse($html, 'http://www.webgui.org'); + +##Test Form Generation + +is(scalar @forms, 1, '1 form was parsed'); + +my $form = $forms[0]; +use Data::Dumper; warn Data::Dumper::Dumper $form; # XXX +my @inputs = $form->inputs; +is(scalar @inputs, 8, 'The form has 8 inputs'); + +#Basic tests + +my @options = $form->find_input('ListMultiple'); + +is( scalar(grep {$_->type ne 'option'} @options), 0, 'All inputs are of type option'); + +is( scalar(grep {$_->{multiple} ne 'multiple'} @options), 0, 'All inputs have multiple'); + +my @names = map { $_->name } @options; +cmp_deeply( [@names], bag(('ListMultiple')x6), 'correct number of names and names'); + +cmp_set([ $form->param('ListMultiple') ], [qw(a c e), ''], 'preselected values in order'); + +my @values = map { $_->possible_values } @options; +cmp_bag([ @values ], [qw(a b c d e), '', (undef)x6], 'list of all options'); + +my @value_names = map { $_->value_names } @options; +cmp_bag([ @value_names ], [qw(aa bb cc dd ee Empty), ('off')x6], 'list of all displayed value names'); +