File Coverage

blib/lib/HTML/FormWizard.pm
Criterion Covered Total %
statement 180 462 38.9
branch 82 314 26.1
condition 24 65 36.9
subroutine 22 34 64.7
pod 15 15 100.0
total 323 890 36.2


line stmt bran cond sub pod time code
1             package HTML::FormWizard;
2              
3 3     3   19 use vars qw($VERSION);
  3         6  
  3         141  
4              
5 3     3   17 use strict;
  3         5  
  3         23502  
6              
7             $VERSION="0.1.09";
8              
9             =head1 NAME
10              
11             HTML::FormWizard - Forms HTML made simple.
12              
13             =head1 SYNOPSIS
14              
15             # this script does almost the same that CGI.pm
16             # example. And, yes, I use CGI, that is,
17             # writes a form and write the submited values
18            
19             use CGI();
20             use HTML::FormWizard();
21              
22              
23             my $form = HTML::FormWizard->new(
24             -title => 'A simple Example',
25             -fields => [
26             { name => 'name',
27             description => "What's your name?"},
28             { name => 'words',
29             descritpion => "What's the combination?",
30             type => 'check',
31             value => ['eenie','meenie',
32             'minie',moe'],
33             defaults => ['eenie','minie'] },
34             { name => 'color',
35             description => "What's your favorite color?",
36             type => 'list',
37             value => ['red','green',
38             'blue','chartreuse']}
39             ]
40             );
41            
42             # Well, That almost it... But now, that do other things...
43            
44             # Append field another list field, this one with
45             # descriptions, for example... that you must select,
46             # initially saying "--Select Please--".
47            
48             $form->add(
49             { name => 'country',
50             description => 'Where did you born?',
51             type => 'list',
52             value =>
53             { pt => 'Portugal',
54             us => 'United States',
55             uk => 'United Kingdom',
56             fr => 'France',
57             '--' => 'Other',
58             '' => '--Select Please--'},
59             default => '',
60             needed => 1 }
61             );
62              
63             # And just one more... A password field, that must
64             # have 3 to 8 characters length, and you want to
65             # validate with a function you wrote...
66            
67             $form->add(
68             { name => 'password',
69             type => 'password',
70             minlen => 3,
71             maxlen => 8,
72             validate => sub {
73             my $pass = shift;
74             return 0 if (($pass =~ /\d/)
75             and ($pass =~ /[a-zA-Z]/)
76             and ($pass =~ /\W/));
77             return "The field password must have at least a number,".
78             " a letter and a symbol";
79             },
80             needed => 1
81             }
82             );
83            
84             # And now... let's get the results!!!
85            
86             if (my $data=$form->run) {
87             print
88             qq(
89             Your name id $$data{name}
90             The Keywords are: ),
91             join(", ", @{$$data{words}}),qq(
92             Your Favorite Color is $$data{color}
93             Your birth country is $$data{country}
94             And you password is $$data{password}
95             )
96             }
97              
98             =head1 DESCRIPTION
99              
100             There are to much libs that write forms, and only a few that
101             process both things, that is, write HTML forms, and retrieve
102             the data send by the user.
103              
104             Or... in a more correct way... That handles everything
105             between the first request and the correct data introduction.
106             Why should every program we devel ask some module to create
107             a form, and then ask some other to verify that the submit is
108             correct? Or why should it verify the data?
109              
110             HTML::FormWizard was wrote for that.
111              
112             It uses CGI to retrieve data from the requests,
113             and the HTML forms are produced using an object template
114             that if not provided, will be $self (a self reference).
115              
116             =head1 METHODS
117              
118             The following methods are available (for properties list, see above):
119              
120             =head2 $form = HTML::FormWizard->new([$property => $value]+);
121              
122             Constructor for the FormWizard. Returns a reference for a
123             HTML::FormWizard object.
124              
125             =cut
126              
127             my %validators=(
128             email => sub {
129             my $str=shift;
130             if ($str=~/^[a-zA-Z][\w\.\_\-]*\@[\w\.\-]+\.[a-zA-Z]{2,4}$/) {
131             return 0;
132             } else {
133             return "Invalid Email";
134             }
135             },
136             phone => sub {
137             my $str=shift;
138             if ($str=~
139             /^(\+\d{1,3})? ?([\(-\s])?\d{1,3}?([\s-\)])[\d\s\-]+$/) {
140             return 0;
141             } else {
142             return "This is not a valid phone number";
143             }
144             },
145             ccard => sub {
146             my $str=shift;
147             if ($str =~ /^\d{4}[\- ]?\d{4}[\- ]?\d{4}[\- ]?\d{4}$|^\d{4}[\- ]?\d{6}[\- ]?\d{5}$/) {
148             return 0;
149             } else {
150             return "The credit card number you type is not valid";
151             }
152             },
153             pt_cp => sub {
154             my $str=shift;
155             if ($str=~/^\d{4}(-\d{3})$/ ) {
156             return 0;
157             } else {
158             return "The Postal Code you typed isn't a valid Portuguese Postal Code.";
159             }
160             },
161             us_cp => sub {
162             my $str=shift;
163             if ($str=~/^\d{5}(-\d{4})?$/) {
164             return 0
165             } else {
166             return "The Postal Code you typed is not a US postal code.";
167             }
168             },
169             ipv4 => sub {
170             my $zbr=shift;
171             my @secs=split /./, $zbr;
172             if (scalar @secs!=4 or $secs[0]<1 or $secs[0]>255
173             or $secs[1]<0 or $secs[1]>255
174             or $secs[2]<0 or $secs[2]>255
175             or $secs[3]<1 or $secs[3]>255) {
176             return "This is not a value IPv4 value.";
177             } else {
178             return 0;
179             }
180             }
181             );
182              
183             my $error_field;
184             my $error_msg;
185              
186             sub new {
187 2     2 1 6 my $self={};
188 2         7 bless $self, shift;
189 2 100       10 if (scalar @_) {
190 1 50 33     14 if (((scalar @_ + 1) % 2) and ($_[0] =~ /^\-/)) {
191 1         2 my ($key,$val);
192 1         7 while (@_) {
193 1         2 $key = shift;
194 1 50       7 if ($key =~ /^\-(\w+)/) {
195 1         2 my $value = shift;
196 1         13 $self->{lc($1)} = $value;
197             } else {
198 0         0 die "Can't use init option parameters and init ".
199             "standard parameters together.";
200             }
201             }
202             } else {
203 0         0 my ($url, $method, $template, $title, $cgi, $fields) = @_;
204 0 0       0 $self->{url} = $url if $url;
205 0 0       0 $self->{method} = $method if $method;
206 0 0       0 $self->{template} = $template if $template;
207 0 0       0 $self->{title} = $title if $title;
208 0 0       0 $self->{cgi} = $cgi if $cgi;
209 0 0       0 $self->{fields} = $fields if $fields;
210             }
211             }
212            
213 2 50       14 $self->{url}="" unless $self->{url};
214 2 50       12 $self->{method}="POST" unless $self->{method};
215 2 50       11 $self->{template}=$self unless $self->{template};
216 2 100       11 $self->{title}="" unless $self->{title};
217 2 50       15 $self->{cgi}=undef unless $self->{cgi};
218 2 50       11 $self->{fields}=[()] unless $self->{fields};
219 2 50       14 $self->{actions}=[({ undef => 'Send' })] unless $self->{actions};
220 2 50       10 $self->{encoding}="multipart/form-data" unless $self->{encoding};
221              
222              
223 2         7 return $self;
224             }
225              
226             =head2 $form->set([$property => $value]+);
227              
228             This method allow you to set the properties that you didn't set initially
229             with new(). This methos only allow you to set a property for each call.
230              
231             With new() you can set as much properties as you want, but set was
232             thought to modify values predefined or values that you can't know when
233             you init the object.
234              
235             =cut
236              
237             sub set {
238 3     3 1 8 my $self = shift;
239 3         6 my $key = shift;
240 3         7 my $value=shift;
241 3 50       29 return 0 unless $key =~/^\-(\w+)/;
242            
243 3         17 $self->{lc($1)}=$value;
244             }
245              
246             =head2 $form->add([$field]+);
247              
248             This method allows you to add fields to the fields list at any time.
249              
250             For field properties see below.
251              
252             =cut
253              
254             sub add {
255 3     3 1 8 my $self = shift;
256 3         5 push @{$self->{fields}}, @_;
  3         21  
257             }
258              
259             =head2 HTML::FormWizard::validate($fieldsref,$dataref);
260            
261             This function allows validation of a datahash againt a fields list.
262             This allows you to create an hash of data received by email or
263             already on a database and verify that it is valid for a fields list.
264              
265             This function is used internally to verify that data. It's called by
266             run() method.
267              
268             =cut
269              
270             sub validate {
271 6     6 1 10 my $fields = shift;
272 6         9 my $data = shift;
273            
274 6         7 for my $field (@{$fields}) {
  6         18  
275 8 50       24 $error_msg = $$field{name} if $$field{name};
276 8 100       22 $error_msg = $$field{description} if $$field{description};
277 8         13 $error_field=$$field{name};
278 8 50       17 $$field{type}='line' unless $$field{type};
279 8 50 33     435 if ($$field{type} eq 'group') {
    50 33        
    50 33        
    50          
280 0 0       0 if ($$field{name}) {
281 0 0       0 return 0 unless validate($$field{parts},
282             $$data{lc($$field{name})});
283             } else {
284 0 0       0 return 0 unless validate($$field{parts}, $data);
285             }
286             } elsif (($$field{type} eq 'radio') or ($$field{type} eq 'list')){
287 0 0       0 if ($$field{name}) {
288 0 0       0 return 0 if ref $$data{lc($$field{name})};
289 0         0 my $ok=0;
290 0 0       0 if (my $rtype=ref($$field{value})) {
291 0         0 my @values;
292 0 0       0 if($rtype eq "ARRAY") {
293 0         0 @values = @{$$field{value}};
  0         0  
294             } else {
295 0         0 @values = keys %{$$field{value}};
  0         0  
296             }
297 0         0 for (@values) {
298 0 0       0 $ok = 1 if $_ eq $$data{lc($$field{name})};
299 0 0       0 last if $ok;
300             }
301             } else {
302 0         0 $ok = $$data{lc($$field{name})} eq $$field{value};
303             }
304 0 0 0     0 return 0 if ($$data{lc($$field{name})} and not $ok);
305 0 0 0     0 return 0 if ($$field{needed} and not $ok);
306             }
307             } elsif (($$field{type} eq 'checkbox') or ($$field{type} eq 'check')
308             or ($$field{type} eq 'mlist')) {
309 0 0       0 if ($$field{name}) {
310 0         0 my $ok=1;
311 0 0       0 if (ref $$data{lc($$field{name})}) {
312 0 0       0 if (my $rtype=ref $$field{value}) {
313 0         0 my @vals;
314 0 0       0 if ($rtype eq "ARRAY") {
315 0         0 @vals = @{$$field{value}};
  0         0  
316             } else {
317 0         0 @vals = keys %{$$field{value}};
  0         0  
318             }
319 0         0 my $vok;
320 0         0 for my $value (@{$$data{lc($$field{name})}}) {
  0         0  
321 0         0 $vok = 0;
322 0         0 for (@vals) {
323 0 0       0 $vok = 1 if $value eq $_;
324 0 0       0 last if $vok;
325             }
326 0 0       0 $ok = 0 unless $vok;
327 0 0       0 last unless $ok;
328             }
329             } else {
330 0         0 $ok = 0;
331             }
332             } else {
333 0         0 $ok=0;
334 0 0       0 if (my $rtype=ref($$field{value})) {
335 0         0 my @values;
336 0 0       0 if ($rtype eq "ARRAY") {
337 0         0 @values = @{$$field{value}};
  0         0  
338             } else {
339 0         0 @values = keys %{$$field{value}};
  0         0  
340             }
341 0         0 for (@values) {
342 0 0       0 $ok = 1 if $$data{lc($$field{name})} eq $_;
343 0 0       0 last if $ok;
344             }
345             } else {
346 0 0       0 $ok = 1 if ($$data{lc($$field{name})}
347             eq $$field{value});
348             }
349             }
350 0 0       0 return 0 unless $ok;
351             }
352             } elsif ($$field{type} eq 'file') {
353 0 0 0     0 return 0 unless $$data{lc($$field{name})} or !$$field{needed};
354             } else {
355 8 100 100     39 return 0 unless $$data{lc($$field{name})} or !$$field{needed};
356 6 50 33     35 return 0 if (($$field{minlen}
      33        
      33        
357             and length($$data{lc($$field{name})})<$$field{minlen})
358             or ($$field{maxlen}
359             and length($$data{lc($$field{name})})>$$field{maxlen}));
360             }
361 6 0 33     17 if (defined($$field{datatype})
      33        
362             and defined($validators{$$field{datatype}})
363             and $$data{lc($$field{name})}) {
364 0         0 my $zbr=$validators{$$field{datatype}}->($$data{lc($$field{name})});
365 0 0       0 if ($zbr) {
366 0         0 $error_msg = $zbr;
367 0         0 return 0;
368             }
369             }
370 6 100       18 if (defined($$field{validate})) {
371 3         12 my $zbr=$$field{validate}->($$data{lc($$field{name})});
372 3 100       11 if ($zbr) {
373 2         3 $error_msg = $zbr;
374 2         9 return 0;
375             }
376             }
377             }
378              
379 2         4 $error_field="";
380 2         9 return 1;
381             }
382              
383             =head2 my $dataref = $form->getdata([$field]+);
384              
385             Loads the data from the request and returns a reference to a datahash.
386              
387             This method receives a list of fields, so it can be called recursively
388             to handle group items.
389              
390             It returns a HASH with pair:
391              
392             { fieldname => fieldvalue }
393              
394             =head2 fieldvalue is an ARRAYREF
395              
396             This happens when fieldvalue is more than a value.
397             The values for mlist and checkboxes are frequently of this time.
398              
399             =head2 fieldvalue is an HASHREF
400              
401             This happens to every named group. One of the group type is group.
402              
403             In true, group is not an field, but a group of field. If a group have name
404             getdata will create an fieldpair with the key equal to the group name
405             property and the value equal to an HASHREF to an hash of VALUES, with the
406             same structure.
407              
408             =cut
409              
410             sub getdata {
411 6     6 1 7 my $self = shift;
412              
413 6         10 my $data = {};
414            
415 6         15 for my $field (@_) {
416 8 100       23 $$field{type}='line' unless $$field{type};
417 8 50       24 if ($$field{type} eq 'group') {
418 0         0 my $values = $self->getdata(@{$$field{parts}});
  0         0  
419 0 0       0 if ($$field{name}) {
420 0         0 $$data{lc($$field{name})} = $values;
421             } else {
422 0         0 for (keys %{$values}) {
  0         0  
423 0         0 $$data{$_} = $$values{$_};
424             }
425             }
426             } else {
427 8 50       19 if ($$field{name}) {
428 8         21 my $vals=[];
429 8         128 @{$vals} = $self->{cgi}->param($$field{name});
  8         33  
430 8 50       11 if (scalar @{$vals} <= 1) {
  8         18  
431 8   100     38 $$data{lc($$field{name})}=$$vals[0]||"";
432 8         20 chomp($$data{lc($$field{name})});
433             } else {
434 0         0 $$data{lc($$field{name})}=$vals;
435             }
436 8         24 $vals=undef;
437             }
438             }
439             }
440            
441 6         47 return $data;
442             }
443              
444             sub _set_fields {
445 4     4   4 my $fields=shift;
446 4         7 my $data = shift;
447 4         5 for my $field (@{$fields}) {
  4         8  
448 6 50 33     72 if ($$field{type} eq 'group') {
    50 33        
    50 33        
449 0 0       0 if ($$field{name}) {
450 0         0 _set_fields($$field{parts}, $$data{$$field{name}});
451             } else {
452 0         0 _set_fields($$field{parts}, $data);
453             }
454             } elsif (($$field{type} eq 'radio') or ($$field{type} eq 'list')) {
455 0         0 $$field{default} = $$data{lc($$field{name})};
456             } elsif (($$field{type} eq 'check') or ($$field{type} eq 'checkbox')
457             or ($$field{type} eq 'mlist')) {
458 0         0 $$field{defaults} = $$data{lc($$field{name})};
459             } else {
460 6         23 $$field{value}=$$data{lc($$field{name})};
461             }
462             }
463             }
464              
465             sub _set_defaults {
466 4     4   7 my $self = shift;
467 4         6 $self->{erro} = $error_msg;
468 4         6 $self->{fielderror}=$error_field;
469              
470 4         12 _set_fields($self->{fields}, $self->{data});
471            
472 4         8 return;
473             }
474              
475             =head2 my $data = $form->run();
476              
477             Verify when the request is a submission to the form or just a form
478             request, and in the first case it calls getdata and validade to verify
479             the data. If the data is valid return a reference to the datahash (see
480             getdata() for datahash format).
481              
482             =cut
483              
484             sub run {
485 8     8 1 12 my $self = shift;
486            
487 8 50       27 $self->{fields} = [] unless $self->{fields};
488            
489 8 100 100     174 if (($self->{cgi}) and ($self->{cgi}->param())) {
490 6 100 66     9 if (($self->{data}=$self->getdata(@{$self->{fields}}))
  6         20  
491             and (validate($self->{fields},$self->{data}))) {
492 2         6 return $self->{data};
493             } else {
494 4         11 $self->_set_defaults;
495             }
496             }
497 6         24 $self->write;
498 6         27 return undef;
499             }
500              
501             =head2 $form->write;
502              
503             Writes the HTML to the form. This function is called by $form->run. In true
504             it calls the functions from the template property to write the help.
505              
506             See more about the template above.
507              
508             =cut
509              
510             sub write {
511              
512 7     7 1 10 my $self = shift;
513 7         12 my $html="";
514              
515 7 50       28 $self->{template} = $self unless $self->{template};
516 7 50       23 $self->{method} = "POST" unless $self->{method};
517 7 50       19 $self->{encoding} = "multipart/form-data" unless $self->{encoding};
518 7 100       25 $self->{erro} = "" unless $self->{erro};
519 7 100       18 $self->{fielderror}="" unless $self->{fielderror};
520              
521 7         107 $html = $self->{template}->header;
522 7         48 $html .= $self->{template}->form_header(
523             $self->{title}, $self->{url}, $self->{method},
524             $self->{encoding}, $self->{erro},$self->{fielderror});
525              
526 7 50       23 $self->{fields} = [] unless $self->{fields};
527              
528 7         10 $html .= $self->_write_fields(@{$self->{fields}});
  7         31  
529              
530 7         13 $html .= $self->_write_actions(@{$self->{actions}});
  7         27  
531            
532 7         42 $html .= $self->{template}->form_footer;
533 7         31 $html .= $self->{template}->footer;
534            
535 7         19 $self->_print($html);
536             }
537              
538             sub _write_actions {
539 7     7   15 my $self = shift;
540              
541 7 50       17 @_ = ( { value => 'Send' } ) unless @_;
542              
543 7         12 my @html_buttons = ();
544              
545 7         16 for my $button (@_) {
546 7         15 my $html = "";
547              
548 7 50       29 $$button{type}="" unless $$button{type};
549            
550 7 50       29 if ($$button{type} eq "image") {
    50          
551 0         0 $html = _image_button($button);
552             } elsif ($$button{type} eq "reset") {
553 0         0 $html = _reset_button($button);
554             } else {
555 7         19 $html = _button($button);
556             }
557            
558 7         24 unshift @html_buttons, $html;
559             }
560            
561 7         515 my $html = $self->{template}->form_actions(@html_buttons);
562            
563 7         20 return $html;
564             }
565              
566             sub _image_button {
567 0     0   0 my $button = shift;
568              
569 0 0       0 return "" unless $$button{src};
570              
571 0         0 my $html="
572              
573 0 0       0 $html .= " ALT='$$button{alt}'" if $$button{alt};
574              
575 0         0 $html .= " SRC='$$button{src}'>";
576            
577 0         0 return $html;
578             }
579              
580             sub _reset_button {
581 0     0   0 my $button=shift;
582              
583 0         0 my $html = "
584              
585 0 0       0 $html .= " VALUE='$$button{value}'" if $$button{value};
586              
587 0         0 $html .= ">";
588              
589 0         0 return $html;
590             }
591              
592             sub _button {
593 7     7   11 my $button=shift;
594              
595 7         15 my $html = "
596              
597 7 50       18 $html .= " VALUE='$$button{value}'" if $$button{value};
598              
599 7         13 $html .= ">";
600              
601 7         12 return $html;
602             }
603              
604             sub _write_fields {
605 7     7   10 my $self = shift;
606 7         9 my $html="";
607 7 100       33 $self->{fielderror}="" unless $self->{fielderror};
608            
609 7         16 for my $field (@_) {
610              
611 7 100       29 $$field{description} = ucfirst($$field{name})
612             unless $$field{description};
613 7         15 my $erro=0;
614 7 100       23 $erro=1 if $$field{name} eq $self->{fielderror};
615 7 100       70 $$field{type}='line' unless $$field{type};
616 7 50 0     18 if ($$field{type} eq "line") {
    0 0        
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
617 7         24 $html .= $self->{template}->form_field($$field{description},
618             _input_line($field),$$field{needed},$erro);
619             } elsif (($$field{type} eq "passwd") or
620             ($$field{type} eq "password")) {
621 0         0 $html .= $self->{template}->form_field($$field{description},
622             _input_line($field,1),$$field{needed},$erro);
623             } elsif (($$field{type} eq "check") or ($$field{type} eq "checkbox")) {
624 0         0 $html .= $self->{template}->form_field($$field{description},
625             _checkbox($field),$$field{needed},$erro);
626             } elsif ($$field{type} eq "radio") {
627 0         0 $html .= $self->{template}->form_field($$field{description},
628             _radio($field),$$field{needed},$erro);
629             } elsif ($$field{type} eq "list") {
630 0         0 $html .= $self->{template}->form_field($$field{description},
631             _list($field),$$field{needed},$erro);
632             } elsif ($$field{type} eq "mlist") {
633 0         0 $html .= $self->{template}->form_field($$field{description},
634             _mlist($field),$$field{needed},$erro);
635             } elsif ($$field{type} eq "text") {
636 0         0 $html .= $self->{template}->form_field($$field{description},
637             _textarea($field),$$field{needed},$erro);
638             } elsif ($$field{type} eq "file") {
639 0         0 $html .= $self->{template}->form_field($$field{description},
640             _file($field),$$field{needed},$erro);
641             } elsif ($$field{type} eq "group") {
642 0         0 $html .= $self->_group($field);
643             } elsif ($$field{type} eq "hidden") {
644 0         0 $html .= $self->_hidden($field);
645             } else {
646 0         0 $html .= $self->{template}->form_field($$field{description},
647             _input_line($field),$$field{needed},$erro);
648             }
649             }
650 7         17 return $html;
651             }
652              
653             sub _group {
654 0     0   0 my $self = shift;
655 0         0 my $field = shift;
656              
657 0 0       0 $$field{title}="" unless $$field{title};
658              
659 0         0 my $html = $self->{template}->form_group_init($$field{title});
660              
661 0 0       0 $$field{parts} = [] unless $$field{parts};
662              
663 0         0 $html .= $self->_write_fields(@{$$field{parts}});
  0         0  
664              
665 0         0 $html .= $self->{template}->form_group_end;
666              
667 0         0 return $html;
668             }
669              
670             sub _hidden {
671 0     0   0 my $field = shift;
672              
673 0 0       0 return "" unless $$field{name};
674              
675 0         0 my $html="
676              
677 0 0       0 $html .= " VALUE='$$field{value}'" if $$field{value};
678              
679 0         0 $html .= ">";
680              
681 0         0 return $html;
682             }
683              
684             sub _input_line {
685 7     7   9 my $field = shift;
686 7         9 my $passwd = shift;
687              
688 7 50       19 return "" unless $$field{name};
689            
690 7         10 my $html="";
691              
692 7         20 $html .= "
693            
694 7 50       16 if ($passwd) {
695 0         0 $html .= " TYPE=PASSWORD";
696             } else {
697 7         11 $html .= " TYPE=TEXT";
698             }
699 7 100       18 if ($$field{value}) {
700 3         8 $html .= " VALUE='$$field{value}'";
701             }
702 7 50       17 if ($$field{size}) {
703 0         0 $html .= " SIZE=$$field{size}";
704             }
705 7 50       17 $$field{maxlen}=$$field{maxlength} if $$field{maxlength};
706 7 50       21 if ($$field{maxlen}) {
707 0         0 $html .=" MAXLENGTH=$$field{maxlen}";
708             }
709 7         11 $html .= ">";
710 7         41 return $html;
711             }
712              
713             sub _file {
714 0     0   0 my $field = shift;
715              
716 0 0       0 return "" unless $$field{name};
717              
718 0         0 my $html;
719              
720 0         0 $html = "
721              
722 0 0       0 $html .= " ACCEPT='$$field{mime}'" if $$field{mime};
723              
724 0 0       0 $html .= " SIZE=$$field{size}" if $$field{size};
725              
726 0         0 $html .= ">";
727              
728 0         0 return $html;
729             }
730              
731             sub _textarea {
732 0     0   0 my $field = shift;
733              
734 0 0       0 return "" unless $$field{name};
735              
736 0         0 my $html;
737              
738 0         0 $html = "";
750              
751 0         0 return $html;
752             }
753              
754             sub _checkbox {
755 0     0   0 my $field = shift;
756            
757 0 0       0 return "" unless $$field{name};
758            
759 0         0 my $html;
760              
761 0 0       0 if (!ref($$field{value})) {
    0          
    0          
762 0         0 $html = "
763 0 0       0 $html .= " CHECKED" if $$field{default};
764 0         0 $html .= "> $$field{description}";
765             } elsif (ref($$field{value}) eq "HASH") {
766 0 0       0 $$field{cols} = 4 unless defined($$field{cols});
767 0         0 $html .= ""; "; \n";
768 0         0 my $col=0;
769 0         0 for my $value (sort {$$field{value}->{$a} cmp $$field{value}->{$b}}
  0         0  
  0         0  
770             keys %{$$field{value}}) {
771 0         0 $html .= "
772 0         0 $html .= " VALUE=$value";
773 0         0 for (@{$$field{defaults}}) {
  0         0  
774 0 0       0 $html .= " CHECKED" if $value eq $_;
775             }
776 0         0 $html .= ">";
777 0         0 $html .= $$field{value}->{$value};
778 0         0 $html .= "
779 0         0 $col++;
780 0 0       0 if ($col==$$field{cols}) {
781 0         0 $html .= "
782 0         0 $col = 0;
783             }
784             }
785            
786 0         0 $html .= "
";
787             } elsif (ref($$field{value}) eq "ARRAY") {
788 0 0       0 $$field{cols} = 4 unless defined($$field{cols});
789 0         0 $html .= ""; "; \n";
790 0         0 my $col=0;
791 0         0 for my $value (sort @{$$field{value}}) {
  0         0  
792 0         0 $html .= "
793 0         0 $html .= " VALUE=$value";
794 0         0 for (@{$$field{defaults}}) {
  0         0  
795 0 0       0 $html .= " CHECKED" if $value eq $_;
796             }
797 0         0 $html .= ">";
798 0         0 $html .= ucfirst($value);
799 0         0 $html .= "
800 0         0 $col++;
801 0 0       0 if ($col==$$field{cols}) {
802 0         0 $html .= "
803 0         0 $col = 0;
804             }
805             }
806              
807 0         0 $html .= "
";
808             } else {
809 0         0 $html = "";
810             }
811 0         0 return $html;
812             }
813              
814             sub _mlist {
815 0     0   0 my $field = shift;
816              
817 0 0       0 return "" unless $$field{name};
818              
819 0         0 my $html;
820            
821 0 0       0 if (ref($$field{value}) eq "HASH") {
    0          
822 0         0 $html = "
823 0 0       0 $html .= " SIZE=$$field{size}" if $$field{size};
824 0         0 $html .= ">";
825 0         0 for my $value (keys %{$$field{value}}) {
  0         0  
826 0         0 $html .= "
827 0         0 for (@{$$field{defaults}}) {
  0         0  
828 0 0       0 $html .= " SELECTED" if $value eq $_;
829             }
830 0         0 $html .= ">";
831 0         0 $html .= $$field{value}->{$value};
832             }
833 0         0 $html .= "";
834             } elsif (ref($$field{value}) eq "ARRAY") {
835 0         0 $html = "
836 0 0       0 $html .= " SIZE=$$field{size}" if $$field{size};
837 0         0 $html .= ">";
838 0         0 for my $value (@{$$field{value}}) {
  0         0  
839 0         0 $html .= "
840 0         0 for (@{$$field{defaults}}) {
  0         0  
841 0 0       0 $html .= " SELECTED" if $value eq $_;
842             }
843 0         0 $html .= ">";
844 0         0 $html .= ucfirst($value);
845             }
846 0         0 $html .= "";
847             } else {
848 0         0 $html = "";
849             }
850            
851             }
852              
853             sub _list {
854 0     0   0 my $field = shift;
855              
856 0 0       0 return "" unless $$field{name};
857              
858 0         0 my $html;
859              
860 0 0       0 if (ref($$field{value}) eq "HASH") {
    0          
861 0         0 $html = "
862 0         0 for my $value (keys %{$$field{value}}) {
  0         0  
863 0         0 $html .= "
864 0 0       0 $html .= " SELECTED" if $$field{default} eq $value;
865 0         0 $html .= ">";
866 0         0 $html .= $$field{value}->{$value};
867             }
868 0         0 $html .= "";
869             } elsif (ref($$field{value}) eq "ARRAY") {
870 0         0 $html = "
871 0         0 for my $value (@{$$field{value}}) {
  0         0  
872 0         0 $html .= "
873 0 0       0 $html .= " SELECTED" if $$field{default} eq $value;
874 0         0 $html .= ">";
875 0         0 $html .= ucfirst($value);
876             }
877 0         0 $html .= "";
878             } else {
879 0         0 $html = "";
880             }
881 0         0 return $html;
882             }
883              
884             sub _radio {
885 0     0   0 my $field = shift;
886            
887 0 0       0 return "" unless $$field{name};
888            
889 0         0 my $html;
890              
891 0 0       0 if (!ref($$field{value})) {
    0          
    0          
892 0         0 $html = "
893 0 0       0 $html .= " CHECKED" if $$field{default};
894 0         0 $html .= "> $$field{description}";
895             } elsif (ref($$field{value}) eq "HASH") {
896 0 0       0 $$field{cols} = 4 unless defined($$field{cols});
897 0         0 $html .= ""; "; \n"; \n" if $col==$$field{cols};
898 0         0 my $col=0;
899 0         0 for my $value (sort {$$field{value}->{$a} cmp $$field{value}->{$b}}
  0         0  
  0         0  
900             keys %{$$field{value}}) {
901 0         0 $html .= "
902 0         0 $html .= " VALUE=$value";
903 0 0       0 $html .= " CHECKED" if $value eq $$field{default};
904 0         0 $html .= ">";
905 0         0 $html .= $$field{value}->{$value};
906 0         0 $html .= "
907 0         0 $col++;
908 0 0       0 if ($col==$$field{cols}) {
909 0         0 $html .= "
910 0         0 $col = 0;
911             }
912 0 0       0 $html .= "
913             }
914            
915 0         0 $html .= "
";
916             } elsif (ref($$field{value}) eq "ARRAY") {
917 0 0       0 $$field{cols} = 4 unless defined($$field{cols});
918 0         0 $html .= ""; "; \n";
919 0         0 my $col=0;
920 0         0 for my $value (sort @{$$field{value}}) {
  0         0  
921 0         0 $html .= "
922 0         0 $html .= " VALUE=$value";
923 0 0       0 $html .= " CHECKED" if $value eq $$field{default};
924 0         0 $html .= ">";
925 0         0 $html .= ucfirst($value);
926 0         0 $html .= "
927 0         0 $col++;
928 0 0       0 if ($col==$$field{cols}) {
929 0         0 $html .= "
930 0         0 $col = 0;
931             }
932             }
933              
934 0         0 $html .= "
";
935             } else {
936 0         0 $html = "";
937             }
938 0         0 return $html;
939             }
940              
941             =head1 Templates
942              
943             The template must return a complete HTML page with only the folling calls:
944              
945             print
946             $template->header(),
947             $template->form_header($title,$method,$url,$encoding,$erro),
948             $template->form_footer(),
949             $template->footer();
950              
951             This must write a complete HTML page.
952              
953             However, here are still missing some other methods.
954              
955             The important to remember now is ... Templates don't print, return. Why?
956              
957             That way it's up to the module when he really must print the HTML, and it
958             can be used to print to files, without the file handler been carry for
959             every single function.
960            
961             =head2 $template->header;
962              
963             This method must create the HTML header for every page. This Header is
964             mustn't open nothing that the footer method will not close.
965              
966             For example, if the header creates a table to preserve space for something
967             but the form, the table must be closed on the header itself or in the footer
968             method.
969              
970             It can be closed anywhere else.
971            
972             =cut
973              
974             sub header {
975 6     6 1 40 return q(
976            
977            
978             Magick Form
979            
985            
986            
987             );
988             }
989              
990             =head2 $template->form_header($title,$url[,$meth[,$enctype[,$erro]]]);
991              
992             This method receive up to five parameters:
993              
994             =head2 $title
995              
996             This is the value that should be the heading line for the form.
997              
998             =head2 $url
999              
1000             The URI where the submission should be done.
1001              
1002             =head2 $meth
1003              
1004             The HTTP Method to use.
1005              
1006             =head2 $enctype
1007              
1008             The Encoding that should be used to make the submission.
1009              
1010             =head2 $erro
1011              
1012             The field description for a invalid field value. Must be used to show
1013             a error message.
1014              
1015             =cut
1016              
1017             sub form_header {
1018 6     6 1 8 shift;
1019 6         10 my $title = shift;
1020 6         8 my $url=shift;
1021 6         7 my $meth=shift;
1022 6         6 my $encod = shift;
1023 6         7 my $erro=shift;
1024 6         8 my $field=shift;
1025 6         14 my $html = qq(

$title


);
1026 6 100       21 $html .= qq(
1027            

$erro


) if $erro;
1028 6 50 66     25 $html .= qq(
1029            

The value you introduced in the field '$field' is invalid.

)
1030             if $field and not $erro;
1031 6         15 $html .= qq(
1032            
1033 6 50       18 $html .= " METHOD=$meth" if $meth;
1034 6 50       17 $html .= " ENCTYPE='$encod'" if $encod;
1035 6         10 $html .= qq(>
1036             ";
1037             );
1038 6         17 return $html;
1039             }
1040              
1041             =head2 $template->form_field($fieldname,$fieldhtml);
1042              
1043             This method from the template must write a form field. It receive to
1044             parameters:
1045              
1046             =head2 $fieldname
1047              
1048             This is a description to the field. It's the label that the user must see
1049             associated to the field.
1050              
1051             =head2 $fieldhtml
1052              
1053             This is the HTML to the field. It is the final HTML, no the field
1054             properties to write the HTML.
1055              
1056             =cut
1057              
1058             sub form_field {
1059 6     6 1 8 shift;
1060 6         7 my $name=shift;
1061 6         7 my $field = shift;
1062 6         9 my $needed=shift;
1063 6         7 my $errado=shift;
1064 6 100       19 $name="$name" if $needed;
1065 6 100       15 $name="

$name

" if $errado;
1066             return
1067 6         41 qq(
$name
1068             $field
1069            
1070             );
1071             }
1072              
1073             =head2 $template->form_group_init($group);
1074              
1075             This method receive only the description for the group. The must start the
1076             group. The function $template->form_group_end() will be called to end
1077             everything form_group_init() leave open.
1078              
1079             =cut
1080              
1081             sub form_group_init {
1082 0     0 1 0 shift;
1083 0         0 my $group = shift;
1084              
1085             return
1086 0         0 qq(
$group
1087             );
1088             }
1089              
1090             =head2 $template->form_group_end()
1091              
1092             This function get no parameters, and must close any HTML tag that the
1093             previous open form_group_init() leave open, or return the HTML to show that
1094             the group ends here.
1095              
1096             =cut
1097              
1098             sub form_group_end {
1099 0     0 1 0 return "
1100             }
1101              
1102             =head2 $template->form_actions()
1103              
1104             This method receive a list of HTML strings, one for each action button or
1105             image that the form must have.
1106              
1107             =cut
1108              
1109             sub form_actions {
1110 6     6 1 5 shift;
1111 6         9 my $html=
1112             q(
);
1113 6         32 $html .= qq($_) for (@_);
1114 6         11 $html .=
1115             q(
1116             );
1117 6         11 return $html;
1118             }
1119              
1120             =head2 $template->form_footer();
1121              
1122             This must close any HTML tag that the call to $template->form_footer() leave.
1123              
1124             It receive no parameters.
1125              
1126             =cut
1127              
1128             sub form_footer {
1129             return
1130 6     6 1 23 q(
1131            
1132             );
1133             }
1134              
1135             =head2 $template->footer
1136              
1137             This function must complete the HTML document.
1138              
1139             =cut
1140              
1141             sub footer {
1142             return
1143 6     6 1 9 q(
1144            
1145             );
1146             }
1147              
1148              
1149             sub _print {
1150 7     7   13 my $self=shift;
1151 7 100       513 if ($self->{cgi}) {
1152 5         97 $self->{cgi}->print(@_);
1153             } else {
1154 2         2320 print @_;
1155             }
1156             }
1157              
1158             1;
1159              
1160             =head1 HTML::FormWizard Properties
1161              
1162             The list of properties listed new can be set on new(), or later with set().
1163             See this methods documentation for more informations about them.
1164              
1165             =head2 -title
1166              
1167             This is the title for the form, the heading that is write by
1168              
1169             $template->form_init();
1170              
1171             The value for this property must be a string. For exemple:
1172              
1173             $form->set(-title => 'Simple Test Form');
1174              
1175             =head2 -url
1176              
1177             This property defines the URL to where the post will be done.
1178              
1179             For example:
1180              
1181             $form->set(-url => 'http://www.camelot.co.pt/forms/zbr.html');
1182              
1183             =head2 -method
1184              
1185             This property defines the HTTP method that will be used to submit the
1186             data. The default to this value is POST.
1187              
1188             =head2 -encoding
1189              
1190             Encoding is the type of encoding that will be used for submitting the data
1191             from the client to the server. Once this library was written to work with
1192             itself, and CGI accepts "multipart/form-data" without problems,
1193             this is the default value for this property, set it if you will be submitting
1194             data to old CGI, or scripts that do not support that format.
1195              
1196             =head2 -template
1197              
1198             The property allows the definition of a diferent template for producing the
1199             HTML to the form. The default value for this value is the $self reference.
1200              
1201             The template is any object that have the functions listed in the previous
1202             section.
1203              
1204             =head2 -cgi
1205              
1206             This property must be a reference to CGI or any other lib that can
1207             param() and print in a compatible way with CGI.
1208              
1209             If this property is not defined, the values will never be returned and the
1210             form will always printed to STDOUT.
1211              
1212             =head2 -fields
1213              
1214             This is a reference for a list of form fields. See next section for details.
1215              
1216             =head2 -actions
1217              
1218             This is a reference to a list of buttons and image inputs.
1219             See after Fields Details for details about actions.
1220              
1221             =head1 Fields Details
1222              
1223             Diferent field types have diferents properties. The diferent valid types are:
1224              
1225             Each Field is an HASH, with the property name as key.
1226             The property that defines the type of field is type.
1227              
1228             For example:
1229              
1230             { type => 'line',
1231             name => 'zbr' }
1232              
1233             Defines a simple inputbox field named 'zbr'.
1234              
1235             =head2 type
1236              
1237             This defines the type of field. Valid values for type are:
1238              
1239             line
1240             passwd or password
1241             check or checkbox
1242             radio
1243             list
1244             mlist
1245             text
1246             file
1247             hidden
1248              
1249             or
1250              
1251             group
1252              
1253             Any other value will be ignored and line type will be created if possible.
1254              
1255             =head2 name
1256              
1257             Every field must have a property name, or will not be created. This field is
1258             needed to retrieve the data also, so it can't be omitted.
1259              
1260             There is only one exception to this: the groups don't need a name.
1261              
1262             BUT, if a group don't have name, the field values will be stay on the base
1263             data HASH, and not in a sub HASH.
1264              
1265             =head2 description
1266              
1267             This property is optional. If not defined, the module will create it with
1268             ucfirst(name).
1269              
1270             Used for the field label.
1271              
1272             =head2 validate
1273              
1274             This property is optional. If used, it must be a function that receives a
1275             string or an arrayref, depending on the type of field, and return false or
1276             an error string to be printed in the form requesting the repost.
1277              
1278             =head2 datatype
1279              
1280             This property is still experimental, and actually only validates 6 diferent
1281             kind of values:
1282              
1283             email => validate email address;
1284             phone => validate phone numbers;
1285             pt_cp => portuguese postal codes;
1286             us_cp => american postal codes;
1287             ipv4 => IP addresses;
1288             ccard => Credit cards.
1289              
1290             Others will be implementated as soon as possible.
1291              
1292             =head2 Type specific field properties
1293              
1294             Some of the properties listed on this section applies to more than one field
1295             type, but may differ on the final result.
1296              
1297             =head2 line and passwd
1298              
1299             This is normal inputbox (filled with * for passwd).
1300              
1301             Its properties are:
1302              
1303             value
1304              
1305             Must be a scalar, and will be the default value for the field.
1306              
1307             size
1308              
1309             Must be a number. Will be assigned to the SIZE property of the INPUT in HTML.
1310              
1311             maxlen
1312              
1313             Maxlen is the max number of character the field will receive. It is assign to
1314             the input box, but will also be verified be validate().
1315              
1316             minlen
1317              
1318             minlen isn't defined by HTML, so it will only be verified by validate
1319             function.
1320              
1321             =head2 radio
1322              
1323             This can be a single radio button or a group of radio buttons.
1324              
1325             value
1326              
1327             Depending on what you want, the value property for radio fields must be
1328             diferent things too.
1329              
1330             If you want s single radio button (I know, it's usual, but...), The value
1331             Property can be a scalar.
1332              
1333             If you want a group of radio buttons, the value property can be either an
1334             ARRAY or an HASH. In the first case the each element of the ARRAY will be
1335             used for the value of the radio and for the label associated with it. In the
1336             second case (when value is a HASH), the keys will be used as values and the
1337             values in the HASH will be uses as labels.
1338              
1339             default
1340              
1341             This must be a scalar containning the value initially selected.
1342              
1343             cols
1344              
1345             This sets the number of radio buttons for line.
1346              
1347             =head2 checkbox
1348              
1349             This is a checkbox or a group of checkboxes. See radio for details about
1350             properties.
1351              
1352             defaults
1353              
1354             This property is used when you have more than one checkbox. This is a list
1355             of all the default checked boxes.
1356              
1357              
1358             =head1 COPYRIGHT
1359              
1360             Copyright 2002 Merlin, The Mage - camelot.co.pt
1361              
1362             This library if open source, you can redistribute it and/or modify it under
1363             the same terms as Perl itself.
1364              
1365              
1366             =head1 AUTHOR
1367              
1368             Merlin, The Mage
1369              
1370             =cut