File Coverage

blib/lib/HTML/Template/Associate/FormField.pm
Criterion Covered Total %
statement 144 191 75.3
branch 45 74 60.8
condition 17 34 50.0
subroutine 45 64 70.3
pod 5 5 100.0
total 256 368 69.5


line stmt bran cond sub pod time code
1             package HTML::Template::Associate::FormField;
2             #
3             # Masatoshi Mizuno E<lt>lusheE<64>cpan.orgE<gt>
4             #
5             # $Id: FormField.pm 298 2007-11-05 11:41:25Z lushe $
6             #
7 5     5   188183 use strict;
  5         12  
  5         351  
8 5     5   127 use warnings;
  5         10  
  5         174  
9 5     5   13149 use UNIVERSAL qw( isa );
  5         85  
  5         33  
10 5     5   18402 use CGI qw( :form );
  5         80112  
  5         38  
11 5     5   4523 use strict;
  5         12  
  5         299  
12              
13             our $VERSION= '0.12';
14              
15             {
16 5     5   28 no warnings 'redefine';
  5         10  
  5         635  
17             sub hidden {
18 2   66 2   19 $_[0]->{hidden} ||= do {
19 1         2 my $hidden;
20 1         16 $_[0]->{hidden}=
21             HTML::Template::Associate::FormField::Hidden->new($hidden);
22             };
23             };
24 5     5   27 no strict 'refs'; ## no critic
  5         9  
  5         11765  
25             for my $accessor (qw{ default defaults value }) {
26             *{__PACKAGE__."::_proc_$accessor"}= sub {
27 9     9   20 my($af, $attr)= @_;
28 9 50 33     58 if (! $attr->{override}
29             && ($attr->{$accessor}= $af->{query}->param($attr->{name}))) {
30 9         18 $attr->{override}= 1;
31             }
32 9         67 return $attr;
33             };
34             }
35             };
36              
37             sub init {
38 0     0 1 0 my ($af, $params)= @_;
39 0         0 $af->{query}= _new_query($params->{cgi});
40 0         0 $af->params($params->{form_fields});
41 0         0 return $af;
42             }
43             sub new {
44 2     2 1 91 my $class= shift;
45 2         12 my $af= bless {
46             query=> _new_query(shift),
47             param=> {},
48             }, $class;
49 2         12 $af->params(shift);
50 2         8 return $af;
51             }
52             sub param {
53 33     33 1 28913 my($af, $key, $value)= @_;
54 33 100       83 return keys %{$af->{param}} if @_< 2;
  1         101  
55 32         34 my $name;
56 32 100       289 if ($key=~/^\__(.+?)\__$/) {
57 16         39 $name= $1;
58             } else {
59 16         16 $name= $key;
60 16         31 $key= '__'. $key .'__';
61             }
62 32         51 $key= uc($key);
63 32 100 66     127 if (@_== 3 && ref($value) eq 'HASH') {
64 16         60 while (my($n, $v)= each %$value) {
65 22 50       65 $n=~/^\-/ and do {
66 0         0 $n=~s/^\-//;
67 0         0 $value->{$n}= $value->{"-$n"};
68 0         0 delete $value->{"-$n"};
69             };
70 22 50       175 $n=~/[A-Z]/ and do {
71 0         0 $value->{lc $n}= $value->{$n};
72 0         0 delete $value->{$n};
73             };
74             }
75 16 50       34 return "" unless $value->{type};
76 16 100       42 if ($value->{type}=~/[Ff][Oo][Rr][Mm]$/) {
77 2 50       6 $value->{name}= $value->{alias} if $value->{alias};
78             } else {
79 14   33     61 $value->{name}= $value->{alias} || $name;
80             }
81 16         46 $af->{param}{$key}= $value;
82 16 50       81 return wantarray ? %{$af->{param}{$key}}: $af->{param}{$key};
  0         0  
83             } else {
84 16         18 return $af->_field_conv(%{$af->{param}{$key}});
  16         93  
85             }
86             }
87             sub params {
88 2     2 1 6 my($af, $hash)= @_;
89 2 100 66     24 if ($hash && ref($hash) eq 'HASH') {
90 1         8 while (my($key, $value)= each %$hash) { $af->param($key, $value) }
  16         32  
91             }
92 2         9 return $af->{param};
93             }
94             sub hidden_out {
95 1     1 1 23 my($af, $hidden)= @_;
96 1         8 HTML::Template::Associate::FormField::Hidden->new($hidden);
97             }
98             sub _field_conv {
99 16 50   16   61 my($af, %attr)= @_; ! %attr and return "";
  16         90  
100 16   50     58 my $_type= lc($attr{type}) || return qq{ Can't find field type. };
101 16         112 my $type= '__'. $_type;
102 16 50       94 return qq{ Can't call "$_type" a field type. } unless $af->can($type);
103 16         33 for my $key (qw(type alias)) { delete $attr{$key} }
  32         151  
104 16         64 return $af->$type(\%attr);
105             }
106             sub _new_query {
107 2   50 2   44 my $query= shift || {};
108 2         6 my $type = ref($query);
109             $type ? do {
110 0         0 ($ENV{MOD_PERL} && isa $query, 'SCALAR') ? do { return $query }:
111 2         10 $type eq 'HASH' ? do { return _const_param($query) }:
112 0         0 ! (isa $query, 'HASH') ? do { $query= {}; return _const_param($query) }:
  0         0  
113 0         0 ! $query->can('param') ? do { return _const_param($query) }:
114 2 0 33     22 do { return $query };
  0 0       0  
    50          
    50          
115 2 50       9 }: do { $query= {}; return _const_param($query) };
  0         0  
  0         0  
116             }
117             sub _const_param {
118 2   50 2   17 my $query= shift || {};
119 2         18 HTML::Template::Associate::FormField::Param->new($query);
120             }
121             sub __startform {
122 1     1   3 my($af, $attr)= @_;
123 1 50 33     5 $attr->{enctype}= CGI->MULTIPART
124             if ($attr->{enctype} && $attr->{enctype}=~/[Uu][Pp][Ll][Oo][Aa][Dd]/);
125 1         7 my $form= startform($attr);
126 1 50       7033 $form.= $af->hidden->get if $af->hidden->exists;
127 1         13 return $form;
128             }
129 0     0   0 sub __form { &__startform }
130 0     0   0 sub __start_form { &__startform }
131             sub __start_multipart_form {
132 1     1   2 my($af, $attr)= @_;
133 1         9 my $form= start_multipart_form($attr);
134 1 50       3213 $form.= $af->hidden->get if $af->hidden->exists;
135 1         9 return $form;
136             }
137 0     0   0 sub __multipart_form { &__start_multipart_form }
138 0     0   0 sub __start_upload_form { &__start_multipart_form }
139 0     0   0 sub __upload_form { &__start_multipart_form }
140             sub __opt_multipart_form {
141 0     0   0 my($af, $attr)= @_;
142 0         0 my $form= start_multipart_form($attr);
143 0         0 $form=~s/(?:<[Ff][Oo][Rr][Mm]\s+|\s*>\n?)//g;
144 0         0 return $form;
145             }
146 0     0   0 sub __opt_upload_form { &__opt_multipart_form }
147             sub __opt_form {
148 0     0   0 my($af, $attr)= @_;
149 0         0 my $form= startform($attr);
150 0         0 $form=~s/(?:<[Ff][Oo][Rr][Mm]\s+|\s*>\n?)//g;
151 0         0 return $form;
152             }
153 0     0   0 sub __endform { q{</form>} }
154 0     0   0 sub __end_form { &__endform }
155 0     0   0 sub __hidden_out { shift->hidden->get }
156 0     0   0 sub __hidden_field { CGI::hidden(&_proc_value) }
157 0     0   0 sub __hidden { CGI::hidden(&_proc_value) }
158 1     1   5 sub __textfield { textfield(&_proc_value) }
159 0     0   0 sub __text { &__textfield }
160 1     1   4 sub __filefield { filefield(&_proc_value) }
161 0     0   0 sub __file { &__filefield }
162 1     1   4 sub __password_field { password_field(&_proc_value) }
163 1     1   4 sub __password { &__password_field }
164 1     1   4 sub __textarea { textarea(&_proc_value) }
165 1     1   7 sub __button { button($_[1]) }
166 1     1   11 sub __reset { reset($_[1]) }
167 1     1   9 sub __defaults { defaults($_[1]) }
168 1     1   5 sub __checkbox { checkbox(&_proc_defaults) }
169 1     1   5 sub __checkbox_group { checkbox_group(&_proc_defaults) }
170 1     1   4 sub __popup_menu { popup_menu(&_proc_defaults) }
171 1     1   4 sub __scrolling_list { scrolling_list(&_proc_defaults) }
172 0     0   0 sub __select { &__popup_menu }
173 1     1   3 sub __radio_group { radio_group(&_proc_default) }
174 0     0   0 sub __radio { &__radio_group }
175 1     1   12 sub __image_button { image_button($_[1]) }
176 0     0   0 sub __image { image_button($_[1]) }
177 1     1   8 sub __submit { submit($_[1]) }
178              
179              
180             package HTML::Template::Associate::FormField::Param;
181 5     5   64 use strict;
  5         13  
  5         842  
182              
183             sub new {
184 2     2   6 my($class, $hash)= @_;
185 2         170 return bless $hash, $class;
186             }
187             sub param {
188 15     15   788 my($q, $key, $value)= @_;
189 15 100       51 return keys %$q if @_< 2;
190 14 100       34 $q->{$key}= $value if @_== 3;
191 14         92 $q->{$key};
192             }
193              
194             package HTML::Template::Associate::FormField::Hidden;
195 5     5   42 use strict;
  5         9  
  5         3069  
196              
197             sub new {
198 2     2   8 my($class, $hidden)= @_;
199 2 100 66     17 $hidden= {} if (! $hidden || ref($hidden) ne 'HASH');
200 2         24 bless $hidden, $class;
201             }
202             sub set {
203 1     1   761 my($h, $key, $value)= @_;
204 1 50       7 if (@_== 3) {
205 1 50       7 if ($h->{$key}) {
206 0 0       0 if (ref($h->{$key}) eq 'ARRAY') {
207 0         0 push @{$h->{$key}}, $value;
  0         0  
208             } else {
209 0         0 $h->{$key}= [$h->{$key}, $value];
210             }
211             } else {
212 1         3 $h->{$key}= $value;
213             }
214             }
215 1         5 return();
216             }
217             sub unset {
218 2     2   488 my($h, $key)= @_;
219 2 50       8 delete $h->{$key} if @_== 2;
220 2         4 return();
221             }
222             sub get {
223 3     3   11 my($h, $key)= @_;
224 3 100       16 return _create_fields($h) if @_< 2;
225 1         8 return _create_field($key, $h->{$key});
226             }
227             sub exists {
228 6     6   514 my($h, $key)= @_;
229 6 100       20 if (@_== 2) {
230 2 50       7 if (ref($h->{$key}) eq 'ARRAY') {
231 0 0       0 return @{$h->{$key}} ? 1: 0;
  0         0  
232             } else {
233 2 100       9 return CORE::exists $h->{$key} ? 1: 0;
234             }
235             } else {
236 4 100       42 return %$h ? 1: 0;
237             }
238             }
239 1     1   2 sub clear { my $h= shift; %$h= () }
  1         3  
240              
241             sub _create_fields {
242 2   50 2   7 my $hidden= shift || return "";
243 2         2 my @hidden;
244 2         8 while (my($key, $value)= each %$hidden) {
245 3 50       8 push @hidden, _create_field($key, $value) if $value;
246             }
247 2 50       10 return @hidden ? join('', @hidden): "";
248             }
249             sub _create_field {
250 4     4   71 my $key = &CGI::escapeHTML(shift);
251 4         4538 my $value= shift;
252 4         4 my $result;
253 4 50       12 for my $val (ref($value) eq 'ARRAY' ? @$value: $value) {
254 4   50     82 $val= &CGI::escapeHTML($val) || next;
255 4         158 $result.= qq{<input type="hidden" name="$key" value="$val" />\n};
256             }
257 4         21 return $result;
258             }
259              
260             1;
261              
262             __END__
263              
264              
265             =head1 NAME
266              
267             HTML::Template::Associate::FormField
268              
269             - CGI Form for using by HTML::Template is generated.
270             - HTML::Template::Associate FormField plugin.
271              
272             =head1 SYNOPSIS
273              
274             use CGI;
275             use HTML::Template;
276             use HTML::Template::Associate::FormField;
277              
278             ## The form field setup. ( CGI.pm like )
279             my %formfields= (
280             StartForm=> { type=> 'opt_form' },
281             Name => { type=> 'textfield', size=> 30, maxlength=> 100 },
282             Email => { type=> 'textfield', size=> 50, maxlength=> 200 },
283             Sex => { type=> 'select', values=> [0, 1, 2],
284             labels=> { 0=> 'please select !!', 1=> 'man', 2=> 'gal' } },
285             ID => { type=> 'textfield', size=> 15, maxlength=> 15 },
286             Passwd=> { type=> 'password', size=> 15, maxlength=> 15,
287             default=> "", override=> 1 },
288             submit=> { type=> 'submit', value=> ' Please push !! ' },
289             );
290              
291             ## The template.
292             my $example_template= <<END_OF_TEMPLATE;
293             <html>
294             <head><title>Exsample template</title></head>
295             <body>
296             <h1>Exsample CGI Form</h1>
297             <form <tmpl_var name="__StartForm__">>
298             <table>
299             <tr><td>Name </td><td> <tmpl_var name="__NAME__"> </td></tr>
300             <tr><td>E-mail </td><td> <tmpl_var name="__EMAIL__"> </td></tr>
301             <tr><td>Sex </td><td> <tmpl_var name="__SEX__"> </td></tr>
302             <tr><td>ID </td><td> <tmpl_var name="__ID__"> </td></tr>
303             <tr><td>PASSWORD </td><td> <tmpl_var name="__PASSWD__"> </td></tr>
304             </table>
305             <tmpl_var name="__SUBMIT__">
306             </form>
307             </body>
308             </html>
309             END_OF_TEMPLATE
310              
311             ## The code.
312             my $cgi = CGI->new;
313             # Give CGI object and definition of field EEE
314             my $form= HTML::Template::Associate::FormField->new($cgi, \%formfields);
315             # Give ... ::Form Field object to associate
316             my $tp = HTML::Template->new(
317             scalarref=> \$example_template,
318             associate=> [$form],
319             );
320             # And output your screen
321             print $cgi->header, $tp->output;
322              
323             or, a way to use not give associateEEE
324              
325             my $cgi = CGI->new;
326             my $form= HTML::Template::Associate::FormField->new($cgi, \%formfields);
327             my $tp = HTML::Template->new(scalarref=> \$example_template);
328             # set up the parameter directly
329             $tp->param('__StartForm__', $form->param('StartForm'));
330             $tp->param('__NAME__', $form->param('Name'));
331             $tp->param('__EMAIL__', $form->param('Email'));
332             $tp->param('__SEX__', $form->param('Sex'));
333             $tp->param('__ID__', $form->param('ID'));
334             $tp->param('__PASSWD__', $form->param('Passwd'));
335             $tp->param('__SUBMIT__', $form->param('submit'));
336              
337             print $cgi->header, $tp->output;
338              
339              
340             # If you move it as a plug-in of HTML::Template::Associate.
341             # * The code is an offer from "Alex Pavlovic" who is the author of HTML::Template::Associate.
342              
343             use HTML::Template;
344             use HTML::Template::Associate;
345              
346             my $associate = HTML::Template::Associate->new ({
347             target => 'FormField',
348             cgi => $cgi,
349             form_fields => \%formfields
350             });
351              
352             my $template= HTML::Template->new (
353             scalarref=> \$example_template,
354             associate=> [ $associate ],
355             );
356              
357             print $cgi->header, $template->output;
358              
359             =head1 DESCRIPTION
360              
361             This is Form Field object using bridge associate option of HTML::Template.
362             Fill in the Form Field which made from object follow the template.
363             If the Form Field data which was input at the previous screen exist, it is
364             easy to make code, because process (CGI pm dependense) of fill in Form is
365             automatic.
366              
367             =head2 Form Field Setup
368              
369             =over 4
370              
371             =item *
372              
373             The Form of the definition data of Form Field is HASH. And, contents of each
374             key is HASH, too.
375              
376             =item *
377              
378             The name of each key is hadled as name of Form Field. Also, in case of hadling
379             by B<HTML::Template, the name of key become enclosed with '__'> .
380             For example, Field that was defined Foo correspomds to B<__FOO__> of template.
381              
382             =item *
383              
384             The contents of each key certainly be defined the key ,type, which shows type
385             of Form Field.
386              
387             =item *
388              
389             The value of designate to type is same as method for making Form Field of
390             CGI.pm. B<Please refer to document of CGI.pm for details>.
391              
392             B<startform> , B<start_multipart_form> , B<endform> , B<textfield> ,
393             B<filefield> , B<password_field> , B<textarea> , B<checkbox> , B<radio_group>
394             , B<popup_menu> , B<optgroup> , B<scrolling_list> , B<image_button> ,
395             B<defaults> , B<button> , B<reset>
396              
397             =item *
398              
399             And others, be possible to designate for extension Field type
400             at B<HTML::Template::Associate::FormField> are as follows:
401              
402             B<form> ... other name of startform. I<(%)>
403              
404             B<start_upload_form> ... other name of start_multipart_form. I<(%)>
405              
406             B<upload_form> ... other name of start_multipart_form. I<(%)>
407              
408             B<opt_form> ... return only a part of attribute of startform.
409              
410             B<opt_multipart_form> ... return only a part of attribute of start_multipart_form.
411              
412             B<opt_upload_form> ... other name of opt_multipart_form.
413              
414             B<hidden_field> ... return all of no indication Field which is seting up.
415              
416             B<hidden> ... other name of hidden_field
417              
418             B<text> ... other name of textfield.
419              
420             B<file> ... other name of filefield.
421              
422             B<password> ... other name of password_field.
423              
424             B<radio> ... other name of radio_group.
425              
426             B<select> ... other name of popup_menu.
427              
428             B<image> ... other name of image_button.
429              
430             I<(%) In case of no indication Field was set up ,
431             connect the no indication Field and return the value.>
432              
433             =item *
434              
435             In case of you'd like to acquire the name from CGI query - it is different name
436             of the key which definition of Form Field, designate for the name of CGI query
437             as alias to contents of each key.
438              
439             $cgi->param('Baz', 'Hello!!');
440             my %formfields= ( 'Foo'=> { alias=> 'Baz', type=> 'textfield' } );
441              
442             =back
443              
444             =head1 METHOD
445              
446             =head2 new
447              
448             Constructor
449              
450             =over 4
451              
452             =item 1
453              
454             Accept CGI object or HASH reference to the first parameter.
455              
456             =item 2
457              
458             Accept definition of CGI Form (HASH reference) to the second parameter.
459              
460             $form= HTML::Template::Associate::FormField-E<gt>B<new>($cgi, \%formfields);
461              
462             =back
463              
464             =head2 init
465              
466             Constructor for HTML::Template::Associate.
467              
468             =head2 param, params
469              
470             Set up or refer to definition parameter of CGI Form.
471              
472             =over 4
473              
474             =item *
475              
476             Get all keys which is defined as Form Field.
477              
478             (B<All keys which was able to get by this are enclosed by '__'>)
479              
480             $form-E<gt>B<param>;
481              
482             =item *
483              
484             Get the Form Field which was designated.
485              
486             $form-E<gt>B<param>('Foo');
487              
488             or
489              
490             $form-E<gt>B<param>('__FOO__');
491              
492             =back
493              
494             =head2 hidden
495              
496             Access to object which control no indication Field.
497              
498             =over 4
499              
500             =item *
501              
502             Add to no indication Field.
503              
504             $form-E<gt>B<hidden>-E<gt>set('Foo', 'Hoge');
505              
506             =item *
507              
508             Get all no indication Fields which was set beforehand.
509              
510             $form-E<gt>B<hidden>-E<gt>get;
511              
512             =item *
513              
514             Get no indication Field which was designated.
515              
516             $form-E<gt>B<hidden>-E<gt>get('Foo');
517              
518             =item *
519              
520             Erase the data of no indication field which was designated.
521              
522             $form-E<gt>B<hidden>-E<gt>unset('Foo');
523              
524             =item *
525              
526             Find out the no indication Field was set or not.
527              
528             $form-E<gt>B<hidden>-E<gt>exists ? 'true': 'false';
529              
530             =item *
531              
532             Erase all of no indication Field which was set.
533              
534             $form-E<gt>B<hidden>-E<gt>clear;
535              
536             =back
537              
538             =head2 hidden_out
539              
540             Export no indication Field, object.
541              
542             =over 4
543              
544             =item *
545              
546             Get no indication field, object.
547              
548             my %hash = ( 'Foo'=E<gt> 'Form Field !!' );
549              
550             B<$hidden> = $form-E<gt>B<hidden_out>(\%hash);
551              
552             =item *
553              
554             Usable methods are same as hidden.
555              
556             B<$hidden>-E<gt>set('Baz', 'Hoge');
557              
558             B<$hidden>-E<gt>get;
559              
560             B<$hidden>-E<gt>unset('Baz');
561              
562             =item *
563              
564             B<Hidden object> which was exported is not linked with startform and,
565             start_multipart_form. No indication field which was formed at this object is
566             please give to B<param method of HTML::Template>.
567              
568             $tp= HTML::Template-E<gt>new( ..... );
569              
570             $tp-E<gt>param('HIDDEN_FIELD', B<$hidden>-E<gt>get);
571              
572             =back
573              
574             =head1 ERRORS
575              
576             In case of errors in the definition of Form field, return this error message
577             instead of Form field.
578              
579             =over 4
580              
581             =item * Can't find field type.
582              
583             There is no designation of type in definition Form field.
584              
585             =item * Can't call "%s" a field type.
586              
587             Errors in definition form of type.
588              
589             =back
590              
591             =head1 BUGS
592              
593             When you call a function start_form without an action attribute by old CGI
594             module, you might find a caution "Use of uninitialized value". In this case,
595             let's upgrade to the latest CGI module.
596              
597             =head1 SEE ALSO
598              
599             HTML::Template, CGI
600              
601             =head1 CREDITS
602              
603             Generously contributed to English translation by:
604              
605             Ayumi Ohno
606              
607             Special Thanks!
608              
609             =head1 AUTHOR
610              
611             Masatoshi Mizuno E<lt>lusheE<64>cpan.orgE<gt>
612              
613             =head1 COPYRIGHT
614              
615             Copyright (C) 2004-2007 by Bee Flag, Corp. E<lt>L<http://egg.bomcity.com/>E<gt>, All Rights Reserved.
616              
617             This library is free software; you can redistribute it and/or modify
618             it under the same terms as Perl itself, either Perl version 5.8.6 or,
619             at your option, any later version of Perl 5 you may have available.
620              
621             =cut