lib/CGI/FormBuilder/Field/text.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 65 | 74 | 87.8 |
branch | 21 | 32 | 65.6 |
condition | 13 | 24 | 54.1 |
subroutine | 8 | 8 | 100.0 |
pod | 1 | 2 | 50.0 |
total | 108 | 140 | 77.1 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | |||||||
2 | ########################################################################### | ||||||
3 | # Copyright (c) Nate Wiger http://nateware.com. All Rights Reserved. | ||||||
4 | # Please visit http://formbuilder.org for tutorials, support, and examples. | ||||||
5 | ########################################################################### | ||||||
6 | |||||||
7 | # The majority of this module's methods (including new) are | ||||||
8 | # inherited directly from ::base, since they involve things | ||||||
9 | # which are common, such as parameter parsing. The only methods | ||||||
10 | # that are individual to different fields are those that affect | ||||||
11 | # the rendering, such as script() and tag() | ||||||
12 | |||||||
13 | package CGI::FormBuilder::Field::text; | ||||||
14 | |||||||
15 | 6 | 6 | 22 | use strict; | |||
6 | 6 | ||||||
6 | 138 | ||||||
16 | 6 | 6 | 19 | use warnings; | |||
6 | 5 | ||||||
6 | 137 | ||||||
17 | 6 | 6 | 15 | no warnings 'uninitialized'; | |||
6 | 4 | ||||||
6 | 159 | ||||||
18 | |||||||
19 | 6 | 6 | 16 | use CGI::FormBuilder::Util; | |||
6 | 4 | ||||||
6 | 586 | ||||||
20 | 6 | 6 | 23 | use CGI::FormBuilder::Field; | |||
6 | 6 | ||||||
6 | 112 | ||||||
21 | 6 | 6 | 19 | use base 'CGI::FormBuilder::Field'; | |||
6 | 4 | ||||||
6 | 3764 | ||||||
22 | |||||||
23 | |||||||
24 | our $VERSION = '3.10'; | ||||||
25 | |||||||
26 | sub script { | ||||||
27 | 218 | 218 | 0 | 172 | my $self = shift; | ||
28 | 218 | 335 | my $name = $self->name; | ||||
29 | |||||||
30 | # The way script() works is slightly backwards: First the | ||||||
31 | # type-specific JS DOM code is generated, then this is | ||||||
32 | # passed as a string to Field->jsfield, which wraps this | ||||||
33 | # in the generic handling. | ||||||
34 | |||||||
35 | # Holders for different parts of JS code | ||||||
36 | 218 | 199 | my $jsfunc = ''; | ||||
37 | 218 | 368 | my $jsfield = tovar($name); | ||||
38 | 218 | 191 | my $close_brace = ''; | ||||
39 | 218 | 384 | my $in = indent(my $idt = 1); # indent | ||||
40 | |||||||
41 | 218 | 405 | my $alertstr = escapejs($self->jsmessage); # handle embedded ' | ||||
42 | 218 | 203 | $alertstr .= '\n'; | ||||
43 | |||||||
44 | 218 | 100 | 349 | if ($self->growable) { | |||
45 | # special handling for growable, have to dynamically | ||||||
46 | # find out how many have been created | ||||||
47 | 2 | 8 | $jsfunc .= < | ||||
48 | // $name: growable text or file box | ||||||
49 | var $jsfield = null; | ||||||
50 | var entered_$jsfield = 0; | ||||||
51 | var i = 0; | ||||||
52 | while (1) { | ||||||
53 | var growel = document.getElementById('$jsfield'+'_'+i); | ||||||
54 | if (growel == null) break; // last element | ||||||
55 | $jsfield = growel.value; | ||||||
56 | entered_$jsfield++; | ||||||
57 | i++; | ||||||
58 | EOJS | ||||||
59 | |||||||
60 | 2 | 3 | $close_brace = < | ||||
61 | |||||||
62 | } // while $name | ||||||
63 | EOJS | ||||||
64 | |||||||
65 | # required? | ||||||
66 | 2 | 50 | 8 | $close_brace .= < |
|||
67 | if (! entered_$jsfield) { | ||||||
68 | alertstr += '$alertstr'; | ||||||
69 | invalid++; | ||||||
70 | } | ||||||
71 | EOJS | ||||||
72 | # indent the very last if/else tests so they're in the while loop | ||||||
73 | 2 | 5 | $in = indent($idt += 1); | ||||
74 | |||||||
75 | } else { | ||||||
76 | |||||||
77 | # get value from text or other straight input | ||||||
78 | # at least this part makes some sense | ||||||
79 | 216 | 381 | $jsfunc .= < | ||||
80 | // $name: standard text, hidden, password, or textarea box | ||||||
81 | var $jsfield = form.elements['$name'].value; | ||||||
82 | EOJS | ||||||
83 | |||||||
84 | } | ||||||
85 | |||||||
86 | 218 | 430 | return $self->jsfield($jsfunc, $close_brace, $in); | ||||
87 | } | ||||||
88 | |||||||
89 | *render = \&tag; | ||||||
90 | sub tag { | ||||||
91 | 240 | 240 | 1 | 519 | local $^W = 0; # -w sucks | ||
92 | 240 | 225 | my $self = shift; | ||||
93 | 240 | 451 | my $attr = $self->attr; | ||||
94 | |||||||
95 | 240 | 910 | my $jspre = $self->{_form}->jsprefix; | ||||
96 | |||||||
97 | 240 | 244 | my $tag = ''; | ||||
98 | 240 | 486 | my @value = $self->tag_value; # sticky is different in |
||||
99 | 240 | 470 | my @opt = $self->options; | ||||
100 | 240 | 557 | debug 2, "my(@opt) = \$field->options"; | ||||
101 | |||||||
102 | # Add in our "Other:" option if applicable | ||||||
103 | 240 | 50 | 414 | push @opt, [$self->othername, $self->{_form}{messages}->form_other_default] | |||
104 | if $self->other; | ||||||
105 | |||||||
106 | 240 | 564 | debug 2, "$self->{name}: generating $attr->{type} input type"; | ||||
107 | |||||||
108 | # We iterate over each value - this is the only reliable | ||||||
109 | # way to handle multiple form values of the same name | ||||||
110 | # (i.e., multiple or |
||||||
111 | 240 | 100 | 467 | @value = (undef) unless @value; # this creates a single-element array | |||
112 | |||||||
113 | # growable handling | ||||||
114 | 240 | 212 | my $count = 0; # for tracking the size of growable fields | ||||
115 | 240 | 175 | my $limit; # for providing (optional) limits to growable fields | ||||
116 | my $at_limit; # have we reached the limit of a growable field? | ||||||
117 | 240 | 50 | 66 | 426 | if ($self->growable && $self->growable ne 1) { | ||
118 | 0 | 0 | $limit = $self->growable; | ||||
119 | } | ||||||
120 | |||||||
121 | 240 | 321 | for my $value (@value) { | ||||
122 | 242 | 50 | 33 | 405 | if ($limit && $count == $limit) { | ||
123 | 0 | 0 | belch "Number of supplied values (" . @value . ")" | ||||
124 | . " for '$attr->{name}' exceeds growable limit $limit - discarding excess"; | ||||||
125 | 0 | 0 | $at_limit = 1; | ||||
126 | 0 | 0 | last; | ||||
127 | } | ||||||
128 | |||||||
129 | # setup the value | ||||||
130 | 242 | 366 | $attr->{value} = $value; # override | ||||
131 | 242 | 100 | 428 | delete $attr->{value} unless defined $value; | |||
132 | |||||||
133 | 242 | 100 | 100 | 399 | if ($self->growable && $self->javascript) { | ||
134 | # the inputs in growable fields need a unique id for fb_grow() | ||||||
135 | 2 | 8 | $attr->{id} = tovar("$attr->{name}_$count"); | ||||
136 | 2 | 3 | $count++; | ||||
137 | } | ||||||
138 | |||||||
139 | # render the tag | ||||||
140 | 242 | 436 | $tag .= htmltag('input', $attr); | ||||
141 | |||||||
142 | # | ||||||
143 | # If we have options, lookup the label instead of the true value. | ||||||
144 | # This code is reached if a field is marked 'static', since | ||||||
145 | # that is still rendered from ::text (here) but as a 'hidden' | ||||||
146 | # field. These options would be leftover from a former select | ||||||
147 | # or radio group that is now shown on a confirm() screen. Got it? | ||||||
148 | # | ||||||
149 | 242 | 409 | for (@opt) { | ||||
150 | 0 | 0 | my($o,$n) = optval($_); | ||||
151 | 0 | 0 | 0 | if ($o eq $value) { | |||
152 | 0 | 0 | 0 | $n ||= $attr->{labels}{$o} || ($self->nameopts ? toname($o) : $o); | |||
0 | |||||||
153 | 0 | 0 | $value = $n; | ||||
154 | 0 | 0 | last; | ||||
155 | } | ||||||
156 | } | ||||||
157 | |||||||
158 | 242 | 100 | 100 | 462 | if ($self->growable && $self->javascript) { | ||
159 | # put linebreaks between the input tags in growable fields | ||||||
160 | # this puts the "Additonal [label]" button on the same line | ||||||
161 | # as the last input tag | ||||||
162 | 2 | 50 | 7 | $tag .= ' ' unless $count == @value; |
|||
163 | } else { | ||||||
164 | 240 | 50 | 875 | $tag .= ' ' if $self->linebreaks; |
|||
165 | } | ||||||
166 | } | ||||||
167 | # check to see if we just hit the limit | ||||||
168 | 240 | 50 | 33 | 419 | $at_limit = 1 if $limit && $count == $limit; | ||
169 | |||||||
170 | # add the "Additional [label]" button | ||||||
171 | 240 | 100 | 100 | 364 | if ($self->growable && $self->javascript) { | ||
172 | $tag .= ' ' . htmltag('input', | ||||||
173 | id => $self->growname, | ||||||
174 | type => 'button', | ||||||
175 | onclick => "${jspre}grow('$attr->{name}')", | ||||||
176 | 2 | 50 | 9 | value => sprintf($self->{_form}{messages}->form_grow_default, $self->label), | |||
177 | ( $at_limit ? ( disabled => 'disabled') : () ), | ||||||
178 | ); | ||||||
179 | } | ||||||
180 | |||||||
181 | # add an additional tag for our _other field | ||||||
182 | 240 | 50 | 394 | $tag .= ' ' . $self->othertag if $self->other; | |||
183 | |||||||
184 | 240 | 558 | debug 2, "$self->{name}: generated tag = $tag"; | ||||
185 | 240 | 1232 | return $tag; # always return scalar tag | ||||
186 | } | ||||||
187 | |||||||
188 | 1; | ||||||
189 | |||||||
190 | __END__ |