File Coverage

blib/lib/HTML/StickyForm.pm
Criterion Covered Total %
statement 40 248 16.1
branch 18 100 18.0
condition 2 30 6.6
subroutine 10 24 41.6
pod 18 18 100.0
total 88 420 20.9


line stmt bran cond sub pod time code
1              
2             =head1 NAME
3              
4             HTML::StickyForm - Lightweight general-purpose HTML form generation, with sticky values
5              
6             =head1 SYNOPSIS
7              
8             # mod_perl example
9              
10             use HTML::StickyForm;
11             use Apache::Request;
12              
13             sub handler{
14             my($r)=@_;
15             $r=Apache::Request->new($r);
16             my $f=HTML::StickyForm->new($r);
17              
18             $r->send_http_header;
19             print
20             '',
21             $form->form_start,
22              
23             "Text field:",
24             $f->text(name => 'field1', size => 40, default => 'default value'),
25              
26             "
Text area:",
27             $f->textarea(name => 'field2', cols => 60, rows => 5, default => 'stuff'),
28              
29             "
Single radio button:",
30             $f->radio(name => 'field3', value => 'xyz', checked => 1),
31              
32             "
Radio buttons:",
33             $f->radio_group(name => 'field4', values => [1,2,3],
34             labels => { 1=>'one', 2=>'two', 3=>'three' }, default => 2),
35              
36             "
Single checkbox:",
37             $f->checkbox(name => 'field5', value => 'xyz', checked => 1),
38              
39             "
Checkbox group:",
40             $f->checkbox_group(name => 'field6', values => [4,5,6],
41             labels => { 4=>'four', 5=>'five', 6=>'six' }, default => [5,6]),
42              
43             "
Password field:",
44             $f->password(name => 'field7', size => 20),
45              
46             '
",
47             $f->submit(value => ' Hit me! '),
48              
49             $f->form_end,
50             '',
51             ;
52             return OK;
53             }
54              
55             =head1 DESCRIPTION
56              
57             This module provides a simple interface for generating HTML form
58             elements, with default values chosen from the previous form submission. This
59             module was written with mod_perl (L) in mind, but works
60             equally well with CGI.pm, including the new 3.x version, or any other module
61             which implements a param() method, or even completely standalone.
62              
63             The module does not provide methods for generating all possible HTML elements,
64             only those which are used in form construction.
65             In addition, this module's interface is much less flexible than CGI.pm's; all
66             routines work only as methods, and there is only one way of passing parameters
67             to each method. This was done for two reasons: to keep the API simple and
68             consistent, and to keep the code size down to a minimum.
69              
70             =cut
71              
72              
73             package HTML::StickyForm;
74             BEGIN {
75 7     7   169502 $HTML::StickyForm::VERSION = '0.08';
76             }
77 7     7   58 use strict;
  7         13  
  7         201  
78 7     7   33 use warnings;
  7         14  
  7         20772  
79              
80             =head1 CLASS METHODS
81              
82             =over
83              
84             =item new([REQUEST])
85              
86             Creates a new form generation object. The single argument can be:
87              
88             =over
89              
90             =item *
91              
92             any object which responds to a C method in the same way that L and
93             L objects do. That is, with no arguments, the names of the
94             parameters are returned as a list. With a single argument, the value(s) of the
95             supplied parameter is/are returned; in scalar context the first value,
96             and in list context all values.
97              
98             =item *
99              
100             a plain arrayref. This will be used to construct an
101             L object, which responds as described above.
102             The array will be passed directly to the RequestHash constructor, so both
103             methods for specifying multiple values are allowed.
104              
105             =item *
106              
107             a plain hashref. This will be used to construct an
108             L object. Multiple values must be represented
109             as arrayref values.
110              
111             =item *
112              
113             a false value. This will be used to construct an
114             L object with no parameters set.
115              
116             =back
117              
118             The constructor dies if passed an unrecognised request object.
119              
120             If an appropriate object is supplied, parameters will be fetched from the
121             object on an as needed basis, which means that changes made to the request
122             object after the form object is constructed may affect the default values
123             used in generated form elements. However, once constructed, the form object's
124             sticky status does not get automatically updated, so if changes made to the
125             request object need to affect the form object's sticky status, set_sticky()
126             must be called between request object modification and form generation.
127              
128             In contrast, L objects created as part of form
129             object construction use copies of the parameters from the supplied hashref or
130             arrayref. This means that the changes made to the original data do not affect
131             the request object, so have absolutely no effect of the behaviour of the
132             form object.
133              
134             =cut
135              
136             sub new{
137 4     4 1 4914 my($class,$req)=@_;
138              
139             # Identify the type of request
140 4         7 my $type;
141 4 100       14 if(!$req){
    50          
    0          
    0          
142 2         6 $type='hash';
143 2         5 $req={};
144 2         8 }elsif(eval{ local $SIG{__DIE__}; $req->can('param'); }){
  2         9  
145 2         27 $type='object';
146             }elsif(ref($req) eq 'HASH'){
147 0         0 $type='hash';
148             }elsif(ref($req) eq 'ARRAY'){
149 0         0 $type='array';
150             }else{
151 0         0 require Carp;
152 0         0 Carp::croak(
153             "Unrecognised request passed to HTML::StickyForm constructor ($req)");
154             }
155 4 100 66     22 if($type eq 'hash' || $type eq 'array'){
156 2         1234 require HTML::StickyForm::RequestHash;
157 2 50       22 $req=HTML::StickyForm::RequestHash->new($type eq 'hash' ? %$req : @$req);
158             }
159              
160 4         25 my $self=bless {
161             req => $req,
162             values_as_labels => 0,
163             well_formed => ' /',
164             },$class;
165              
166             # Count submitted fields
167 4         14 $self->set_sticky;
168              
169 4         57 $self;
170             }
171              
172             =back
173              
174             =head1 METHODS
175              
176             =head2 Configuration methods
177              
178             =over
179              
180             =item set_sticky([BOOL])
181              
182             With no arguments, the request object's parameters are counted, and the form
183             object is made sticky if one or more parameters are present, non-sticky
184             otherwise. If an argument is given, its value as a boolean determines whether
185             the form object will be sticky or not. In both cases, the return value will be
186             the new value of the sticky flag.
187              
188             A non-sticky form object always uses the values supplied to methods when
189             constructing HTML elements, whereas a sticky form object will use the values
190             from the request.
191              
192             This method is called by the constructor when the form object is created, so it
193             is not usually necessary to call it explicitly. However, it may be necessary to
194             call this method if parameters are set with the C method after the
195             form object is created.
196              
197             =cut
198              
199             sub set_sticky{
200 9     9 1 393 my $self=shift;
201 9 100       41 return $self->{params}=!!$_[0] if @_;
202              
203 7         35 $self->{params}=!!(()=$self->{req}->param);
204             }
205              
206             =item get_sticky()
207              
208             Returns true if the form object is sticky.
209              
210             =cut
211              
212             sub get_sticky{
213 7     7 1 820 my($self)=@_;
214              
215 7         307 !!$self->{params};
216             }
217              
218             =item values_as_labels([BOOL])
219              
220             With no arguments, this method returns the C attribute,
221             which determines what should happen when a value has no label in the
222             checkbox_group(), radio_group() and select() methods. If this attribute
223             is false (the default), no labels will be automatically generated. If it is
224             true, labels will default to the corresponding value if they are not supplied
225             by the user.
226              
227             If an argument is passed, it is used to set the C attribute.
228              
229             =cut
230              
231             sub values_as_labels{
232 6     6 1 9 my $self=shift;
233 6 100       24 return $self->{values_as_labels}=!!$_[0] if @_;
234 4         17 $self->{values_as_labels};
235             }
236              
237             =item well_formed([BOOL])
238              
239             With no arguments, this method return the C attribute, which
240             determines whether to generate well-formed XML, by including the trailing
241             slash in non-container elements.
242             If true, all generated elements will be well-formed. If false, no slashes
243             are added - which is unfortunately required by some older browsers.
244              
245             If an argument is passed, it is used to set the C attribute.
246              
247             =cut
248              
249             sub well_formed{
250 6     6 1 9 my $self=shift;
251 6 100       27 return !!($self->{well_formed}=$_[0] ? ' /' : '') if @_;
    100          
252 4         19 !!$self->{well_formed};
253             }
254              
255             =back
256              
257             =head2 HTML generation methods
258              
259             Most of these methods are specified as taking PAIRLIST arguments. This means
260             that arguments must be passed as a list of name/value pairs. For example:
261              
262             $form->text(name => 'fred',value => 'bloggs');
263              
264             This represents two arguments; "name" with a value of "fred", and "value"
265             with a value of "bloggs".
266              
267             In cases where sticky values are useful, there are two ways of specifying the
268             values, depending on whether stickiness is required for the element being
269             generated. To set sticky value defaults, use the C argument.
270             Alternatively, to set values which are not affected by previous values entered
271             by the user, use the C argument (or C or C, depending
272             on the type of element being generated).
273              
274             =over
275              
276             =item form_start(PAIRLIST)
277              
278             Generates a CformE> start tag. All arguments are interpreted
279             as attributes for the element. All names and values are HTML escaped.
280             The following arguments are treated specially:
281              
282             C: Defaults to C
283              
284             =cut
285              
286             sub form_start{
287 0     0 1 0 my($self,$args)=&_args;
288 0 0       0 $args->{method}='GET' unless exists $args->{method};
289              
290 0         0 my $field='
291 0         0 while(my($name,$val)=each %$args){
292 0         0 _escape($name);
293 0         0 _escape($val);
294 0         0 $field.=qq( $name="$val");
295             }
296 0         0 $field.='>';
297              
298 0         0 $field;
299             }
300              
301             =item form_start_multipart(PAIRLIST)
302              
303             As form_start(), but the C argument defaults to C.
304              
305             =cut
306              
307             sub form_start_multipart{
308 0     0 1 0 my($self,$args)=&_args;
309 0   0     0 $args->{enctype}||='mutipart/form-data';
310 0         0 $self->form_start($args);
311             }
312              
313             =item form_end()
314              
315             Generates a CformE> end tag.
316              
317             =cut
318              
319             sub form_end{
320 0     0 1 0 '';
321             }
322              
323             =item text(PAIRLIST)
324              
325             Generates an CinputE> element. In general, arguments are interpreted
326             as attributes for the element. All names and values are HTML escaped. The
327             following arguments are treated specially:
328              
329             C: Defaults to C
330              
331             C: Unconditional value. If present, causes C and any sticky
332             value to be ignored.
333              
334             C: Conditional value, ignored if C is present. If the form is
335             sticky, the sticky value will be used for the C attribute's value.
336             Otherwise, the supplied C will be used.
337             A C attribute is never created.
338              
339             =cut
340              
341             sub text{
342 0     0 1 0 my($self,$args)=&_args;
343 0   0     0 my $type=delete $args->{type} || 'text';
344 0         0 my $name=delete $args->{name};
345 0         0 my $value;
346 0 0       0 if(exists $args->{value}){
347 0         0 $value=delete $args->{value};
348 0         0 delete $args->{default};
349             }else{
350 0         0 $value=delete $args->{default};
351 0 0       0 $value=$self->{req}->param($name) if $self->{params};
352             }
353              
354 0         0 _escape($type);
355 0         0 _escape($name);
356 0         0 _escape($value);
357              
358 0         0 my $field=qq(
359 0         0 while(my($key,$val)=each %$args){
360 0         0 _escape($key);
361 0         0 _escape($val);
362 0         0 $field.=qq( $key="$val");
363             }
364              
365 0         0 return "$field$self->{well_formed}>";
366             }
367              
368             =item hidden(PAIRLIST)
369              
370             As text(), but produces an input element of type C.
371              
372             =cut
373              
374             sub hidden{
375 0     0 1 0 my($self,$args)=&_args;
376 0   0     0 $args->{type}||='hidden';
377 0         0 $self->text($args);
378             }
379              
380             =item password(PAIRLIST)
381              
382             As text(), but produces an input element of type C.
383              
384             =cut
385              
386             sub password{
387 0     0 1 0 my($self,$args)=&_args;
388 0   0     0 $args->{type}||='password';
389 0         0 $self->text($args);
390             }
391              
392             =item textarea(PAIRLIST)
393              
394             Generates a EtextareaE container. All arguments are used directly
395             to generate attributes for the start tag, except for those listed below.
396             All values are HTML-escaped.
397              
398             C: Unconditional value. If present, specifies the contents of the
399             container, and causes C and any sticky value to be ignored. A
400             C attribute is never created.
401              
402             C: Conditional value, ignored if C is present. If the form is
403             stikcy, the sticky value wil be used for the container contents. Otherwise,
404             sticky, the supplied C will be used.
405             A C attribute is never created.
406              
407             =cut
408              
409             sub textarea{
410 0     0 1 0 my($self,$args)=&_args;
411 0         0 my $name=delete $args->{name};
412 0         0 my $value;
413 0 0       0 if(exists $args->{value}){
414 0         0 $value=delete $args->{value};
415 0         0 delete $args->{default};
416             }else{
417 0         0 $value=delete $args->{default};
418 0 0       0 $value=$self->{req}->param($name) if $self->{params};
419             }
420              
421 0         0 _escape($name);
422 0         0 _escape($value);
423              
424 0         0 my $field=qq(";
432             }
433              
434             =item checkbox(PAIRLIST)
435              
436             Generates a single C type CinputE> element. All arguments
437             are used directly to generate attributes for the tag, except for those listed
438             below. All values are HTML-escaped.
439              
440             C: Unconditional status. If present, used to decide whether to include
441             a checked attribute, and causes C and any sticky value to be ignored.
442              
443             C: Conditional status, ignored if C is present. If the form
444             is sticky, the sticky value will be used to determine whether to include a
445             checked attribute. Otherwise, the supplied C will be used.
446              
447             If the decision to include the C attribute is based on the sticky
448             value, the sticky parameter must include at least one value which is the same
449             as the supplied C argument. If the decision is based on the value of
450             the C or C arguments, the supplied argument need only be
451             true for the C attribute to be created.
452              
453             =cut
454              
455             sub checkbox{
456 0     0 1 0 my($self,$args)=&_args;
457 0   0     0 my $type=delete $args->{type} || 'checkbox';
458 0         0 my $name=delete $args->{name};
459 0         0 my $value=delete $args->{value};
460 0         0 my $checked;
461 0 0       0 if(exists $args->{checked}){
462 0         0 $checked=delete $args->{checked};
463 0         0 delete $args->{default};
464             }else{
465 0         0 $checked=delete $args->{default};
466 0 0       0 $value='' unless defined($value);
467 0 0       0 $checked=grep $_ eq $value,$self->{req}->param($name) if $self->{params};
468             }
469              
470 0         0 _escape($name);
471 0         0 _escape($value);
472              
473 0         0 my $field=qq(
474 0 0       0 $field.=' checked="checked"' if $checked;
475 0         0 while(my($key,$val)=each %$args){
476 0         0 _escape($key);
477 0         0 _escape($val);
478 0         0 $field.=qq( $key="$val");
479             }
480              
481 0         0 return "$field$self->{well_formed}>";
482             }
483              
484             =item checkbox_group(PAIRLIST)
485              
486             Generates a group of C type CinputE> elements. If called in
487             list context, returns a list of elements, otherwise a single string containing
488             all tags. All arguments are used directly to generate attributes in each tag,
489             except for those listed below. Arguments with scalar values result in that
490             value being used for each element, whereas hashref values result in the value
491             keyed by the element's C attribute being used.
492             Unless otherwise stated, all names and values are HTML-escaped.
493              
494             C: An arrayref of values.
495             One element will be generated for each element, in the order supplied.
496             If not supplied, the label keys will be used instead.
497              
498             C: A hashref of labels.
499             Each element generated will be followed by the label keyed
500             by the value. Values will be HTML-escaped unless a false C argument
501             is supplied. If no label is present for a given value and C
502             is true, the value will also be used for the label.
503              
504             C: If present and false, labels will not be HTML-escaped.
505              
506             C: Unconditional status. If present, used to decide whether each
507             checkbox is marked as checked, and causes C, C and any
508             sticky values to be ignored. May be a single value or arrayref of values.
509              
510             C: Conditional status, ignored if C is present.
511             If the form is sticky, individual checkboxes are marked as checked if the
512             sticky parameter includes at least one value which is the same as the individual
513             checkbox's value. Otherwise, the supplied C values are
514             used in the same way. May be a single value or arrayref of values.
515              
516             C: If true, each element/label will be followed by a CbrE>
517             element.
518              
519             C: If supplied, overrides the form object's
520             C attribute.
521              
522             =cut
523              
524             sub checkbox_group{
525 0     0 1 0 my($self,$args)=&_args;
526 0   0     0 my $type=delete $args->{type} || 'checkbox';
527 0         0 my $name=delete $args->{name};
528 0   0     0 my $labels=delete $args->{labels} || {};
529 0         0 my $escape_labels=1;
530 0 0       0 $escape_labels=delete $args->{escape_labels} if exists $args->{escape_labels};
531 0         0 my $values=delete $args->{values};
532 0   0     0 $values||=[keys %$labels];
533 0         0 my $checked=[];
534 0 0       0 if(exists $args->{checked}){
535 0         0 $checked=delete $args->{checked};
536 0 0       0 $checked=[$checked] if ref($checked) ne 'ARRAY';
537 0         0 delete $args->{default};
538             }else{
539 0 0       0 if(exists $args->{default}){
540 0         0 $checked=delete $args->{default};
541 0 0       0 $checked=[$checked] if ref($checked) ne 'ARRAY';
542             }
543 0 0       0 $checked=[$self->{req}->param($name)] if $self->{params};
544             }
545 0         0 my %checked=map +($_,'checked'),@$checked;
546 0 0       0 my $br=delete $args->{linebreak} ? "{well_formed}>" : '';
547 0         0 my $v_as_l=$self->{values_as_labels};
548 0 0       0 if(exists $args->{values_as_labels}){
549 0         0 $v_as_l=delete $args->{values_as_labels};
550             }
551              
552 0         0 _escape($type);
553 0         0 _escape($name);
554              
555 0         0 my $field=qq(
556 0         0 my %per_value=(
557             checked => \%checked,
558             value => {map +($_,$_),@$values},
559             );
560 0         0 while(my($key,$val)=each %$args){
561 0 0 0     0 if($val && ref($val) eq 'HASH'){
562 0         0 $per_value{$key}=$val;
563 0         0 next;
564             }
565 0         0 _escape($key);
566 0         0 _escape($val);
567 0         0 $field.=qq( $key="$val");
568             }
569              
570 0         0 my @checkboxes;
571 0         0 for my $value(@$values){
572 0         0 my $field=$field;
573 0         0 while(my($key,$hash)=each %per_value){
574 0 0       0 exists $hash->{$value}
575             or next;
576 0         0 _escape($key);
577 0         0 _escape(my $val=$hash->{$value});
578 0         0 $field.=qq( $key="$val");
579             }
580 0         0 $field.="$self->{well_formed}>";
581              
582 0 0       0 if(exists $labels->{$value}){
    0          
583 0         0 my $label=$labels->{$value};
584 0 0       0 _escape($label) if $escape_labels;
585 0         0 $field.=$label;
586             }elsif($v_as_l){
587 0         0 _escape(my $evalue=$value);
588 0         0 $field.=$evalue;
589             }
590 0         0 $field.=$br;
591 0         0 push @checkboxes,$field;
592             }
593              
594 0 0       0 return @checkboxes if wantarray;
595 0         0 return join '',@checkboxes;
596             }
597              
598             =item radio(PAIRLIST)
599              
600             As radio_group(), but setting C to C.
601              
602             =cut
603              
604             sub radio{
605 0     0 1 0 my($self,$args)=&_args;
606 0   0     0 $args->{type}||='radio';
607 0         0 $self->checkbox($args);
608             }
609              
610             =item radio_group(PAIRLIST)
611              
612             As checkbox_group(), but setting C to C.
613              
614             =cut
615              
616             sub radio_group{
617 0     0 1 0 my($self,$args)=&_args;
618 0   0     0 $args->{type}||='radio';
619 0         0 $self->checkbox_group($args);
620             }
621              
622             =item select(PAIRLIST)
623              
624             Generates a CselectE> element. Arguments starting with a dash
625             are used directly to generate attributes in the CoptionE> elements.
626             All other arguments are used directly to
627             generate attributes in the CselectE> element, except for those listed below.
628             Unless otherwise stated, all names and values are HTML-escaped.
629              
630             C: An arrayref of values and/or option groups.
631             Scalar values are used directly to create CoptionE> elements,
632             whereas arrayrefs represent option groups. The first element in an option
633             group is either the group's label or a hashref holding all of the group's
634             attributes, of which C is special cased to produce the attribute
635             value C if true, and no attribute if false.
636             Defaults to label keys.
637              
638             C: A hashref of labels.
639             Each CoptionE> tag generated will contain the
640             label keyed by its value. If no label is present for a given value, no label
641             will be generated. Defaults to an empty hashref.
642              
643             C: Unconditional status. If present, the supplied values will be
644             used to decide which options to mark as selected, and C and any
645             sticky values will be ignored. May be a single value or arrayref.
646              
647             C: Conditional status, ignored if C is
648             supplied. If the form is sticky, the sticky values will be used to decide which
649             options are selected. Otherwise, the supplied values will be used.
650             May be a single value or arrayref.
651              
652             C: If true, the C attribute is set to C.
653              
654             C: Overrides the form object's C attribute.
655             This is of little value, since it's the default behaviour of HTML in any case.
656              
657             =cut
658              
659             sub select{
660 0     0 1 0 my($self,$args)=_args(@_);
661 0         0 my $name=delete $args->{name};
662 0         0 my $multiple=delete $args->{multiple};
663 0   0     0 my $labels=delete $args->{labels} || {};
664 0   0     0 my $values=delete $args->{values} || [keys %$labels];
665 0         0 my $selected;
666 0 0       0 if(exists $args->{selected}){
667 0         0 $selected=delete $args->{selected};
668 0         0 delete $args->{default};
669             }else{
670 0         0 $selected=delete $args->{default};
671 0 0       0 $selected=[$self->{req}->param($name)] if $self->{params};
672             }
673 0 0       0 if(!defined $selected){ $selected=[]; }
  0 0       0  
674 0         0 elsif(ref($selected) ne 'ARRAY'){ $selected=[$selected]; }
675 0         0 my %selected=map +($_,'selected'),@$selected;
676 0         0 my $v_as_l=$self->{values_as_labels};
677 0 0       0 if(exists $args->{values_as_labels}){
678 0         0 $v_as_l=delete $args->{values_as_labels};
679             }
680              
681 0         0 my %option_args;
682 0         0 for my $key(keys %$args){
683 0 0       0 (my $option_key=$key)=~s/\A-// or next;
684 0         0 $option_args{$option_key}=delete $args->{$key};
685             }
686 0         0 $option_args{selected}=\%selected;
687              
688 0         0 _escape($name);
689 0         0 my $field=qq(
690 0         0 while(my($key,$val)=each %$args){
691 0         0 _escape($key);
692 0         0 _escape($val);
693 0         0 $field.=qq( $key="$val");
694             }
695 0 0       0 $field.=' multiple="multiple"' if $multiple;
696 0         0 $field.=">";
697              
698 0         0 $field.=_select_options($values,\%option_args,$labels,$v_as_l);
699 0         0 $field.="";
700              
701 0         0 $field;
702             }
703              
704              
705              
706             =item submit(PAIRLIST)
707              
708             Generates an CinputE> of type C. All of the supplied
709             arguments are HTML-escaped, and used directly as attributes. C
710             fields are not sticky.
711              
712             =cut
713              
714             sub submit{
715 0     0 1 0 my($self,$args)=_args(@_);
716 0 0       0 $args->{type}='submit' unless exists $args->{type};
717              
718 0         0 my $field='
719 0         0 while(my($key,$val)=each %$args){
720 0         0 _escape($key);
721 0         0 _escape($val);
722 0         0 $field.=qq( $key="$val");
723             }
724 0         0 $field.="$self->{well_formed}>";
725              
726 0         0 $field;
727             }
728              
729              
730             =back
731              
732              
733              
734              
735             =begin private
736              
737             =head1 PRIVATE SUBROUTINES
738              
739             These subs are only intended for internal use.
740              
741             =over
742              
743             =item _escape($string)
744              
745             Escape HTML-special characters in $string, in place. If $string is not defined,
746             it will be updated to an empty string.
747              
748             =cut
749              
750             sub _escape($){
751 7 100   7   3970 if(defined $_[0]){
752 6         38 $_[0]=~s/([<>&"]|[^\0-\177])/sprintf "&#%d;",ord $1/ge;
  9         50  
753             }else{
754 1         3 $_[0]='';
755             }
756             }
757              
758             =item _args(@_)
759              
760             Work out which of the two argument passing conventions is being used, and
761             return ($self,\%args). This essentially converts the public unrolled
762             PAIRLIST arguments into a single hashref, as used by the internal
763             interfaces.
764              
765             =cut
766              
767             sub _args{
768 4     4   4323 my $self=shift;
769 4 100       14 my $args=ref($_[0]) ? {%{$_[0]}} : {@_};
  2         7  
770 4         14 ($self,$args);
771             }
772              
773             =item _select_options(\@values,\%option_args,\%labels,$values_as_labels)
774              
775             Returns an HTML fragment containing C
776             list of option values. Values which are arrayrefs are used to represent
777             option groups, wherein the zeroth element is either the group name, or
778             a hashref holding the group's attributes.
779              
780             =cut
781              
782             sub _select_options{
783 0     0     my($values,$option_args,$labels,$v_as_l)=@_;
784 0           my $field='';
785 0           for my $value(@$values){
786 0 0         if(ref $value){
787             # Handle option group
788 0           my($_group,@subvalues)=@$value;
789 0 0         my %group=ref($_group) ? %$_group : (label => $_group);
790 0 0         if(delete $group{disabled}){
791 0           $group{disabled}='disabled';
792             }
793 0           $field.=qq(
794 0           while(my($name,$value)=each %group){
795 0           _escape($value);
796 0           $field.=qq( $name="$value");
797             }
798 0           $field.='>';
799 0           $field.=_select_options(\@subvalues,$option_args,$labels,$v_as_l);
800 0           $field.='';
801             }else{
802             # Handle single option
803 0           _escape(my $evalue=$value);
804 0           $field.=qq(
805 0           while(my($key,$val)=each %$option_args){
806 0 0         if(ref $val){
807 0 0         defined($val=$val->{$value})
808             or next;
809             }
810 0           _escape($val);
811 0           $field.=qq( $key="$val");
812             }
813 0           $field.=">";
814 0 0         if(exists $labels->{$value}){
    0          
815 0           my $label=$labels->{$value};
816 0           _escape($label);
817 0           $field.=$label;
818             }elsif($v_as_l){
819 0           $field.=$evalue;
820             }
821 0           $field.="";
822             }
823             }
824              
825 0           $field;
826             }
827              
828             =back
829              
830             =end private
831              
832             =cut
833              
834             # Return true to require
835             1;
836              
837              
838              
839             =head1 AUTHOR
840              
841             Copyright (C) Institute of Physics Publishing 2000-2011
842              
843             Peter Haworth
844              
845             You may use and distribute this module according to the same terms
846             that Perl is distributed under.
847              
848