File Coverage

blib/lib/CGI/QuickForm.pm
Criterion Covered Total %
statement 16 152 10.5
branch 0 102 0.0
condition 0 71 0.0
subroutine 6 11 54.5
pod 0 2 0.0
total 22 338 6.5


line stmt bran cond sub pod time code
1             package CGI::QuickForm ; # Documented at the __END__.
2              
3             # $Id: QuickForm.pm,v 1.71 2002/04/30 11:20:03 mark Exp mark $
4              
5             require 5.004 ;
6              
7 1     1   1288 use strict ;
  1         2  
  1         38  
8              
9 1     1   6427 use CGI qw( :standard :html3 ) ;
  1         24732  
  1         10  
10             #use CGI::Carp qw( fatalsToBrowser ) ;
11              
12 1         137 use vars qw(
13             $VERSION @ISA @EXPORT @EXPORT_OK
14             %Translate
15 1     1   4579 ) ;
  1         11  
16              
17             $VERSION = '1.93' ;
18              
19 1     1   6 use Exporter() ;
  1         2  
  1         2127  
20              
21             @ISA = qw( Exporter ) ;
22              
23             @EXPORT = qw( show_form ) ;
24              
25              
26             # &colour is not documented because at some point it may be moved elsewhere.
27             @EXPORT_OK = qw( colour color ) ;
28             *color = \&colour ;
29 0     0 0   sub colour { qq{$_[1]} }
30              
31              
32             sub show_form {
33 0     0 0   my %form = (
34             -LANGUAGE => 'en', # Language to use for default messages
35             -USER_REQUIRED => undef,
36             -USER_INVALID => undef,
37             -REQUIRED_HTML => '+',
38             -INVALID_HTML => '*',
39             -TITLE => 'Quick Form', # Default page title and heading
40             -INTRO => undef,
41             -HEADER => undef,
42             -FOOTER => undef,
43             -NAME => '',
44             -JSCRIPT => {},
45             -ONSUBMIT => '',
46             -ACCEPT => \&_on_valid_form,
47             -VALIDATE => undef, # Call this to validate entire form
48             -SIZE => undef,
49             -MAXLENGTH => undef,
50             -ROWS => undef,
51             -COLUMNS => undef,
52             -BORDER => 0,
53             -CHECK => 1,
54             -SPACE => 0,
55             -MULTI_COLUMN => 0,
56             -STYLE_FIELDNAME => '',
57             -STYLE_FIELDVALUE => '',
58             -STYLE_BUTTONS => '',
59             -STYLE_ROW => '',
60             -STYLE_DESC => '',
61             -STYLE_WHY => '',
62             -TABLE_OPTIONS => '',
63             -FIELDS => [ { -LABEL => 'No Fields Specified' } ],
64             -BUTTONS => [ { -name => 'Submit' } ], # Default button
65             @_,
66             ) ;
67              
68             # Backward compatibility.
69 0 0         $form{-LANGUAGE} = 'en' if $form{-LANGUAGE} eq 'english' ;
70 0 0         $form{-BUTTONS}[0]{-name} = $form{-BUTTONLABEL} if $form{-BUTTONLABEL} ;
71              
72 0 0         if( $form{-LANGUAGE} eq 'user' ) {
73 0   0       $Translate{'user'}{-REQUIRED} =
74             $form{-USER_REQUIRED} || $Translate{'en'}{-REQUIRED} ;
75 0   0       $Translate{'user'}{-INVALID} =
76             $form{-USER_INVALID} || $Translate{'en'}{-INVALID} ;
77             }
78 0           $Translate{$form{-LANGUAGE}}{-REQUIRED} =~ s/~R~/$form{-REQUIRED_HTML}/go ;
79 0           $Translate{$form{-LANGUAGE}}{-INVALID} =~ s/~I~/$form{-INVALID_HTML}/go ;
80              
81 0           $form{-REQUIRED} = 0 ; # Assume no fields are required.
82              
83 0           foreach my $style ( qw( FIELDNAME FIELDVALUE BUTTONS DESC WHY ) ) {
84 0 0         $form{"-STYLE_$style"} = qq{ $form{"-STYLE_$style"}}
85             if $form{"-STYLE_$style"} ;
86             }
87 0 0         $form{"-STYLE_BUTTONS"} = 'center'
88             if $form{"-STYLE_BUTTONS"} =~ /^ CENT(?:ER|RE)$/oi ;
89              
90 0 0         $form{-TABLE_OPTIONS} = " $form{-TABLE_OPTIONS}" if $form{-TABLE_OPTIONS} ;
91 0           $form{-MULTIPART} = 0; # Assume single part forms
92              
93 0           my $i = 0 ;
94 0           foreach my $fieldref ( @{$form{-FIELDS}} ) {
  0            
95             # We have to write back to the original data, $fieldref only points to
96             # a copy.
97 0           foreach my $style ( qw( ROW FIELDNAME FIELDVALUE DESC ) ) {
98 0   0       my $value = $form{-FIELDS}[$i]{"-STYLE_$style"} || $form{"-STYLE_$style"} ;
99 0 0         $form{-FIELDS}[$i]{"-STYLE_$style"} = $value ? " $value" : '' ;
100             }
101 0 0 0       $form{-FIELDS}[$i]{-STYLE_FIELDVALUE} .=
102             qq{ colspan="$form{-FIELDS}[$i]{-COLSPAN}"}
103             if $form{-FIELDS}[$i]{-COLSPAN} and $form{-MULTI_COLUMN} ; #"
104              
105 0 0         $form{-FIELDS}[$i]{-LABEL} = $fieldref->{-name} unless $fieldref->{-LABEL} ;
106 0 0         $form{-FIELDS}[$i]{-name} = $fieldref->{-LABEL} unless $fieldref->{-name} ;
107 0 0         $form{-FIELDS}[$i]{-TYPE} = 'textfield' unless $fieldref->{-TYPE} ;
108 0 0         $form{-MULTIPART} = 1 if $form{-FIELDS}[$i]{-TYPE} eq 'filefield' ;
109              
110 0 0 0       $form{-FIELDS}[$i]{-START_ROW} = 1
      0        
111             if $i == 0 or $form{-FIELDS}[$i - 1]{-END_ROW} or not $form{-MULTI_COLUMN} ;
112              
113 0           $form{-FIELDS}[$i]{-END_ROW} = 1
114 0 0 0       if $i == $#{$form{-FIELDS}} or not $form{-MULTI_COLUMN} ;
115              
116 0 0         $form{-REQUIRED} = 1 if $fieldref->{-REQUIRED} ;
117 0 0         if( $form{-FIELDS}[$i]{-TYPE} eq 'textfield' ) {
    0          
118 0 0 0       if( $form{-SIZE} and not $fieldref->{-size} ) {
119 0           $form{-FIELDS}[$i]{-size} = $form{-SIZE} ;
120             }
121 0 0 0       if( $form{-MAXLENGTH} and not $fieldref->{-maxlength} ) {
122 0           $form{-FIELDS}[$i]{-maxlength} = $form{-MAXLENGTH} ;
123             }
124             }
125             elsif( $form{-FIELDS}[$i]{-TYPE} eq 'textarea' ) {
126 0 0 0       if( $form{-ROWS} and not $fieldref->{-rows} ) {
127 0           $form{-FIELDS}[$i]{-rows} = $form{-ROWS} ;
128             }
129 0 0 0       if( $form{-COLUMNS} and not $fieldref->{-columns} ) {
130 0           $form{-FIELDS}[$i]{-columns} = $form{-COLUMNS} ;
131             }
132             }
133 0           $i++ ;
134             }
135              
136 0 0 0       if( $form{-CHECK} and param() ) {
137 0           &_check_form( \%form ) ;
138             }
139             else {
140 0           &_show_form( \%form ) ;
141             }
142             }
143              
144              
145             sub _check_form {
146 0     0     my $formref = shift ;
147              
148 0           $formref->{-INVALID} = 0 ;
149 0           my %field ;
150              
151 0           my $i = 0 ;
152 0           foreach my $fieldref ( @{$formref->{-FIELDS}} ) {
  0            
153             # We have to write back to the original data, $fieldref only points to
154             # a copy.
155 0           my( $valid, $why ) =
156             defined $fieldref->{-VALIDATE} ?
157 0 0         &{$fieldref->{-VALIDATE}}( param( $fieldref->{-name} ) ) :
158             ( 1, '' ) ;
159 0 0 0       $formref->{-FIELDS}[$i]{-INVALID} = 1,
    0 0        
160              
161             $formref->{-FIELDS}[$i]{-WHY} = $valid ?
162             undef : "{-STYLE_WHY}>$why",
163              
164             $formref->{-INVALID}++
165             if ( $fieldref->{-REQUIRED} and not param( $fieldref->{-name} ) ) or
166             not $valid ;
167              
168 0           $field{$fieldref->{-name}} = param( $fieldref->{-name} ) ;
169 0           $i++ ;
170             }
171              
172 0 0 0       if( not $formref->{-INVALID} and defined $formref->{-VALIDATE} ) {
173             # If all the individual parts are valid, check that the record as a
174             # whole is valid. The parameters are presented in a name=>value hash.
175 0           my( $valid, $why ) = &{$formref->{-VALIDATE}}( %field ) ;
  0            
176 0           $formref->{-INVALID} = not $valid ;
177 0           $formref->{-WHY} = $why ;
178             }
179              
180 0 0         if( $formref->{-INVALID} ) {
181 0           &_show_form( $formref ) ;
182             }
183             else {
184             # Clean any fields that have a clean routine specified.
185 0           foreach my $fieldref ( @{$formref->{-FIELDS}} ) {
  0            
186 0           param( $fieldref->{-name},
187 0 0         &{$fieldref->{-CLEAN}}( param( $fieldref->{-name} ) ) )
188             if defined $fieldref->{-CLEAN} ;
189             }
190 0           &{$formref->{-ACCEPT}} ;
  0            
191             }
192             }
193              
194              
195             sub _show_form {
196 0     0     my $formref = shift ;
197              
198 0           my $invalid = delete $formref->{-INVALID} ;
199 0           my $why = delete $formref->{-WHY} ;
200 0 0         my $n = delete $formref->{-SPACE} ? "\n" : '' ;
201              
202 0 0         if( $formref->{-HEADER} ) {
203 0 0         if ( ref $formref->{-HEADER} eq 'CODE' ) {
204 0           &{$formref->{-HEADER}} ;
  0            
205             }
206             else {
207 0           print "$formref->{-HEADER}$n" ;
208             }
209             }
210             else {
211 0   0       print
212             header,
213             start_html(
214             -title => $formref->{-TITLE},
215             -script => $formref->{-JSCRIPT} ), $n,
216             h3( $formref->{-TITLE} ), $n,
217             p( $formref->{-INTRO} || $Translate{$formref->{-LANGUAGE}}{-INTRO} ), $n,
218             ;
219             }
220              
221 0 0 0       print "{-STYLE_WHY}>$why
$n"
222             if $invalid and defined $why ;
223 0 0         print "$Translate{$formref->{-LANGUAGE}}{-REQUIRED}$n"
224             if $formref->{-REQUIRED} ;
225 0 0 0       print " $Translate{$formref->{-LANGUAGE}}{-INVALID}$n"
226             if $invalid and not defined $why ;
227              
228 0 0         my $start_form = $formref->{-MULTIPART} ?
229             \&CGI::start_multipart_form : \&CGI::start_form ;
230 0 0 0       if( defined( $ENV{'GATEWAY_INTERFACE'} ) and
231             ( $ENV{'GATEWAY_INTERFACE'} =~ /^CGI-Perl/ ) ) {
232 0   0       print &$start_form(
      0        
233             -name => $formref->{-NAME},
234             -onSubmit => $formref->{-ONSUBMIT},
235             -action => ( script_name() || '' ) . ( path_info() || '' )
236             ), $n ;
237             }
238             else {
239 0           print &$start_form(
240             -name => $formref->{-NAME},
241             -onSubmit => $formref->{-ONSUBMIT}
242             ), $n ;
243             }
244              
245 0           print qq{$n{-TABLE_OPTIONS}>$n} ; #" $n} ; $n" ; $n" if $endrow ;
246              
247 0           my @hidden ;
248              
249 0           foreach my $fieldref ( @{$formref->{-FIELDS}} ) {
  0            
250 0           my %field = %$fieldref ;
251 0           my $type = delete $field{-TYPE} ;
252 0 0         push @hidden, $fieldref if $type eq 'hidden' ;
253 0 0 0       next if $type eq 'submit' or $type eq 'hidden' ;
254 0           my $required = delete $field{-REQUIRED} ;
255 0 0         $required = $required ? $formref->{-REQUIRED_HTML} : '' ;
256 0           my $invalid = delete $field{-INVALID} ;
257 0 0         $invalid = $invalid ? $formref->{-INVALID_HTML} : '' ;
258 0           my $why = delete $field{-WHY} ;
259 0           my $rowstyle = delete $field{-STYLE_ROW} ;
260 0           my $namestyle = delete $field{-STYLE_FIELDNAME} ;
261 0           my $valuestyle = delete $field{-STYLE_FIELDVALUE} ;
262 0           my $descstyle = delete $field{-STYLE_DESC} ;
263 0           my $endrow = delete $field{-END_ROW} ;
264 0 0         if( $field{-HEADLINE} ) {
265 0   0       $field{-COLSPAN} ||= 2 ;
266 0           $namestyle .= qq{ colspan="$field{-COLSPAN}"} ; #"
267             }
268 0 0         print qq{$n} if delete $field{-START_ROW} ;
269 0           print qq{$field{-LABEL}$required$invalid
270 0 0         unless( $field{-HEADLINE} ) {
271 0           print qq{} ;
272 0 0         print "$field{-DESC}
" if $field{-DESC} ;
273 0           delete @field{-LABEL,-VALIDATE,-CLEAN,-SIZE,-MAXLENGTH,
274             -ROWS,-COLUMNS,-COLSPAN} ;
275 1     1   7 no strict "refs" ;
  1         2  
  1         707  
276 0           local $^W = 0 ; # Switch off moans about undefined values.
277 0           print &{$type}( %field ) ;
  0            
278             # Prefer to say why immediately after the field rather than in a
279             # separate column.
280 0 0 0       print " $why" if $invalid and defined $why ;
281 0           print "
282             }
283 0 0         print "
284             }
285              
286 0 0         print "
$n", ( ( $formref->{-STYLE_BUTTONS} eq 'center' ) ?
287             '
' : "{-STYLE_BUTTONS}>" ) ;
288              
289 0           foreach my $fieldref ( @{$formref->{-BUTTONS}} ) {
  0            
290 0 0         if( $fieldref->{-DEFAULTS} ) {
291 0   0       print defaults( $fieldref->{-name} || 'Clear' ), " " ;
292             }
293             else {
294 0           print $n, submit( %$fieldref ), " " ;
295             }
296             }
297              
298 0 0         print ( ( $formref->{-STYLE_BUTTONS} eq 'center' ) ? '' : '' ) ;
299              
300 0           foreach my $fieldref ( @hidden ) {
301 0           my %field = %$fieldref ;
302 0           delete @field{-LABEL,-VALIDATE,-CLEAN,-SIZE,-MAXLENGTH,-ROWS,-COLUMNS,
303             -TYPE,-REQUIRED,-INVALID,-WHY} ;
304 0           print $n, hidden( %field ) ;
305             }
306              
307 0           print $n, end_form, $n ;
308              
309 0 0         if( $formref->{-FOOTER} ) {
310 0 0         if ( ref $formref->{-FOOTER} eq 'CODE' ) {
311 0           &{$formref->{-FOOTER}} ;
  0            
312             }
313             else {
314 0           print "$formref->{-FOOTER}$n" ;
315             }
316             }
317             else {
318 0           print hr, end_html ;
319             }
320             }
321              
322              
323             sub _on_valid_form {
324             # This is included for completeness - if you don't supply your own your
325             # form will simply throw away the user's data!
326              
327 0     0     print
328             header,
329             start_html( 'Quick Form' ),
330             h3( 'Quick Form' ),
331             p( "You must define your own &on_valid_form subroutine, otherwise " .
332             "the data will simply be thrown away." ),
333             end_html,
334             ;
335              
336             # If using pure mod_perl you should add:
337             # Apache::Constants::OK ;
338             # at the end of your on_valid_form routine and
339             # use Apache::Constants qw( :common ) ;
340             # along with the other 'use' commands in your program.
341             }
342              
343              
344             BEGIN {
345              
346 1     1   68 %Translate = (
347             'cy' => {
348             -INTRO => "Cofnodwch y wybodaeth.",
349             -REQUIRED => "Mae angen llenwi'r adrannau sydd wedi eu clustnodi " .
350             "gyda ~R~.",
351             -INVALID => "Mae'r adrannau sydd wedi eu clustnodi gyda ~I~ " .
352             "yn cynnwys camgymeriadau neu yn wag.",
353             },
354             'de' => {
355             -INTRO => "Tragen Sie bitte die Informationen ein.",
356             -REQUIRED => "Bitte mindestens die mit ~R~ " .
357             "gekennzeichneten Felder ausfüllen.",
358             -INVALID => "Die mit ~I~ gekennzeichneten Felder " .
359             "enthalten Fehler oder sind leer.",
360             },
361             'en' => {
362             -INTRO => "Please enter the information.",
363             -REQUIRED => "Data entry fields marked with ~R~ are required.",
364             -INVALID => "Data entry fields marked with ~I~ contain errors " .
365             "or are empty.",
366             },
367             'es' => {
368             -INTRO => "Favor de introducir la información.",
369             -REQUIRED => "Los campos marcados con ~R~ son requeridos.",
370             -INVALID => "Los campos marcados con ~I~ contienen " .
371             "errores o están en blanco.",
372             },
373             'fr' => {
374             -INTRO => "Veuillez écrire l'information.",
375             -REQUIRED => "Des zones de saisie de données " .
376             "identifiées par " .
377             "~R~ sont exigées.",
378             -INVALID => "Des zones de saisie de données " .
379             "identifiées par ~I~ contenez les " .
380             "erreurs ou soyez vide.",
381             },
382             'he' => {
383             -INTRO => "נא הזן נתונים",
384             -REQUIRED => " שדות חובה מסומנים ב ~R~ ",
385             -INVALID => " שדות שגויים או ריקים מסומנים ב ~I~",
386             },
387             ) ;
388             }
389              
390              
391             1 ;
392              
393              
394             __END__