File Coverage

blib/lib/HTML/Obj2HTML/Plugin/SemanticUIForms.pm
Criterion Covered Total %
statement 6 32 18.7
branch 0 12 0.0
condition n/a
subroutine 2 4 50.0
pod n/a
total 8 48 16.6


line stmt bran cond sub pod time code
1             package HTML::Obj2HTML::Plugin::SemanticUI;
2              
3 1     1   633 use strict;
  1         2  
  1         27  
4 1     1   4 use warnings;
  1         2  
  1         2494  
5              
6             my @semanticnumbers = qw(zero one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen);
7             HTML::Obj2HTML::register_extension("form", {
8             attr => { class => "ui form" }
9             });HTML::Obj2HTML::register_extension("select", {
10             attr => { class => "ui dropdown" }
11             });
12             HTML::Obj2HTML::register_extension("checkbox", {
13             tag => "",
14             before => sub {
15             my $obj = shift;
16             my $readonly = HTML::Obj2HTML::get_opt("readonly") || $obj->{readonly};
17             delete($obj->{readonly});
18             if ($readonly) {
19             return HTML::Obj2HTML::gen([ div => [
20             if => { cond => $obj->{checked}, true => [ icon => 'green check' ], false => [ icon => 'red close' ]},
21             _ => " ".$obj->{label}
22             ]]);
23             } else {
24             my $label = $obj->{label}; delete($obj->{label});
25             if (!$label && $obj->{checkboxlabel}) { $label = $obj->{checkboxlabel}; delete($obj->{checkboxlabel}); }
26             if (!$obj->{value}) { $obj->{value} = 1; }
27             $obj->{if} = { cond => $obj->{checked}, true => { checked => 1 } }; delete($obj->{checked});
28             $obj->{type} = "checkbox";
29             return HTML::Obj2HTML::gen([
30             div => { class => 'ui checkbox', _ => [
31             input => $obj, label => $label
32             ] }
33             ]);
34             }
35             }
36             });
37             HTML::Obj2HTML::register_extension("radio", {
38             tag => "",
39             before => sub {
40             my $obj = shift;
41             my $readonly = HTML::Obj2HTML::get_opt("readonly") || $obj->{readonly};
42             delete($obj->{readonly});
43             if ($readonly) {
44             return HTML::Obj2HTML::gen([ div => [
45             if => { cond => $obj->{checked}, true => [ icon => 'check' ] },
46             _ => " ".$obj->{label}
47             ]]);
48             } else {
49             my $label = $obj->{label}; delete($obj->{label});
50             if (!$label && $obj->{radiolabel}) { $label = $obj->{radiolabel}; delete($obj->{radiolabel}); }
51             if (!$obj->{value}) { $obj->{value} = 1; }
52             $obj->{if} = { cond => $obj->{checked}, true => { checked => 1 } }; delete($obj->{checked});
53             $obj->{type} = "radio";
54             return HTML::Obj2HTML::gen([
55             div => { class => 'ui radio checkbox', _ => [
56             input => $obj, label => $label
57             ] }
58             ]);
59             }
60             }
61             });
62             HTML::Obj2HTML::register_extension("labeledinput", {
63             tag => "",
64             before => sub {
65             my $obj = shift;
66              
67             my $readonly = HTML::Obj2HTML::get_opt("readonly") || $obj->{readonly};
68             delete($obj->{readonly});
69             if ($readonly) {
70             return [ div => $obj->{value}." ".$obj->{label} ];
71             } else {
72             my $label = $obj->{label}; delete($obj->{label});
73              
74             # The has we were passed actually belongs to a child element, we need to copy and clear.
75             my $inputobj = {};
76             for (keys %$obj) { $inputobj->{$_} = $obj->{$_}; delete $obj->{$_}; }
77              
78             return [ div => { class => "ui right labeled input", _ => [
79             input => $inputobj,
80             div => { class => "ui basic label", _ => $label }
81             ]}];
82             }
83             }
84             });
85             HTML::Obj2HTML::register_extension("field", {
86             tag => 'div',
87             before => sub {
88             my $obj = shift;
89             if (ref $obj eq "HASH") {
90             if (!defined $obj->{_}) { $obj->{_} = []; }
91             my $label = genhelplabel($obj);
92             if ($label) {
93             unshift(@{$obj->{"_"}}, "label", $obj->{label});
94             }
95             }
96             return undef;
97             },
98             attr => { class => 'field' }
99             });
100              
101             HTML::Obj2HTML::register_extension("fields", {
102             tag => "div",
103             before => sub {
104             my $o = shift;
105             $o->{class} = "ui ".$semanticnumbers[$o->{num}]." fields";
106             delete($o->{num});
107             return "";
108             }
109             });
110             HTML::Obj2HTML::register_extension("checkboxfield", {
111             tag => "",
112             before => sub {
113             my $obj = shift;
114             return HTML::Obj2HTML::gen(commonfield($obj, [ checkbox => $obj ]));
115             }
116             });
117             HTML::Obj2HTML::register_extension("radiofield", {
118             tag => "",
119             before => sub {
120             my $obj = shift;
121             return HTML::Obj2HTML::gen(commonfield($obj, [ radio => $obj ]));
122             }
123             });
124              
125             HTML::Obj2HTML::register_extension("inputfield", {
126             tag => "",
127             before => sub {
128             my $obj = shift;
129             my $readonly = HTML::Obj2HTML::get_opt("readonly") || $obj->{readonly};
130             delete($obj->{readonly});
131             if ($readonly) {
132             return HTML::Obj2HTML::gen(commonfield($obj, [ span => $obj->{value} ]));
133             } else {
134             return HTML::Obj2HTML::gen(commonfield($obj, [ input => $obj ]));
135             }
136             }
137             });
138              
139             HTML::Obj2HTML::register_extension("textareafield", {
140             tag => "",
141             before => sub {
142             my $obj = shift;
143              
144             if (defined $obj->{value}) {
145             my $val = $obj->{value};
146             delete($obj->{value});
147             $val =~ s/^\s+//g;
148             $val =~ s/\s+$//g;
149             $obj->{_} = "$val";
150             } else {
151             $obj->{_} = "";
152             }
153              
154             my $readonly = HTML::Obj2HTML::get_opt("readonly") || $obj->{readonly};
155             delete($obj->{readonly});
156             if ($readonly) {
157             if ($obj->{class} =~ /editor/) {
158             return HTML::Obj2HTML::gen(commonfield($obj, [ div => [ raw => $obj->{_} ] ]));
159             } else {
160             return HTML::Obj2HTML::gen(commonfield($obj, [ div => [ md => $obj->{_} ] ]));
161             }
162             } else {
163             return HTML::Obj2HTML::gen(commonfield($obj, [ textarea => $obj ]));
164             }
165              
166             }
167             });
168             HTML::Obj2HTML::register_extension("htmlfield", {
169             tag => "",
170             before => sub {
171             my $obj = shift;
172             if ($obj->{class} !~ /editor/) {
173             if ($obj->{class}) { $obj->{class} .= " "; }
174             $obj->{class} .= "editor";
175             }
176             return [ textareafield => $obj ];
177             }
178             });
179              
180             HTML::Obj2HTML::register_extension("selectfield", {
181             tag => "",
182             before => sub {
183             my $obj = shift;
184              
185             my $readonly = HTML::Obj2HTML::get_opt("readonly") || $obj->{readonly};
186             delete($obj->{readonly});
187              
188             if ($obj->{class}) { $obj->{class}.=" "; }
189             $obj->{class}.= "ui dropdown";
190             # if ($obj->{multiple}) { $obj->{class}.= " fluid"; }
191              
192             my $db = $obj->{db} || $HTML::Obj2HTML::db;
193             delete($obj->{db});
194              
195             if ($obj->{options} && ref $obj->{options} eq "ARRAY") {
196             my @contents = ();
197             if ($obj->{inclblank}) { push(@contents, option => { value => "", _ => "" }); }
198             for (my $i = 0; $i <= $#{$obj->{hiddenoptions}}; $i+=2) {
199             my $v = $obj->{hiddenoptions}->[$i];
200             my $t = $obj->{hiddenoptions}->[$i+1];
201             if ((!$obj->{multiple} && defined $obj->{value} && "$obj->{value}" eq "$v") ||
202             ($obj->{multiple} && defined $obj->{value} && ($obj->{value} & $v))) {
203             if ($readonly) {
204             push(@contents, div => $t);
205             } else {
206             push(@contents, option => { value => $v, _ => $t, selected => 1 });
207             }
208             }
209             }
210             for (my $i = 0; $i <= $#{$obj->{options}}; $i+=2) {
211             my $v = $obj->{options}->[$i];
212             my $t = $obj->{options}->[$i+1];
213             my $opt = { value => $v, _ => $t };
214             if (!$obj->{multiple}) {
215             if (defined $obj->{value} && "$obj->{value}" eq "$v") { $opt->{selected} = 1; }
216             } else {
217             if (defined $obj->{value} && ($obj->{value} & $v)) { $opt->{selected} = 1; }
218             if (defined $obj->{values}) {
219             if (grep {"$_" eq "$v"} @{$obj->{values}}) { $opt->{selected} = 1; }
220             }
221             }
222              
223             if ($readonly) {
224             if ($opt->{selected}) {
225             push(@contents, div => $opt->{_});
226             }
227             } else {
228             push(@contents, option => $opt);
229             }
230             }
231             $obj->{_} = \@contents;
232             delete($obj->{values});
233             delete($obj->{options});
234             delete($obj->{hiddenoptions});
235             }
236             if ($obj->{optionsql} && ref $obj->{optionsql} eq "ARRAY") {
237             my @contents = ();
238             if ($obj->{inclblank}) { push(@contents, option => { value => "", _ => "" }); }
239             if (!$obj->{valuefield}) { $obj->{valuefield} = "id"; }
240             if (!$obj->{textfield}) { $obj->{textfield} = "name"; }
241             for (my $r = $db->for(@{$obj->{optionsql}}); $r->more; $r->next) {
242             my $opt = { value => $r->{$obj->{valuefield}}, _ => $r->{$obj->{textfield}} };
243             if (!$obj->{multiple}) {
244             if (defined $obj->{value} && "$obj->{value}" eq "$r->{$obj->{valuefield}}") { $opt->{selected} = 1; }
245             } else {
246             if (defined $obj->{selectedfield} && $r->{$obj->{selectedfield}}) {
247             $opt->{selected} = 1;
248             } elsif (defined $obj->{value} && ($obj->{value} & $r->{$obj->{valuefield}})) {
249             $opt->{selected} = 1;
250             }
251             if (defined $obj->{values}) {
252             if (grep({$_ eq $r->{$obj->{valuefield}}} @{$obj->{values}})) { $opt->{selected} = 1; }
253             }
254             }
255             if ($readonly) {
256             if ($opt->{selected}) {
257             push(@contents, div => $opt->{_});
258             }
259             } else {
260             push(@contents, option => $opt);
261             }
262             }
263             $obj->{_} = \@contents;
264             delete($obj->{values});
265             delete($obj->{optionsql});
266             delete($obj->{valuefield});
267             delete($obj->{textfield});
268             }
269             if (!$obj->{_}) { $obj->{_} = []; }
270             delete($obj->{value});
271             delete($obj->{inclblank});
272              
273             if ($readonly) {
274             return HTML::Obj2HTML::gen(commonfield($obj, $obj->{_}));
275             } else {
276             return HTML::Obj2HTML::gen(commonfield($obj, [ select => $obj ]));
277             }
278              
279             }
280             });
281             HTML::Obj2HTML::register_extension("dateinput", {
282             tag => "",
283             before => sub {
284             my $o = shift;
285             return HTML::Obj2HTML::gen([
286             div => { class => "ui calendar dateonly", _ => [
287             div => { class => "ui input left icon", _ => [
288             i => { class => "calendar icon", _ => [] },
289             input => $o
290             ]}
291             ]}
292             ]);
293             }
294             });
295             HTML::Obj2HTML::register_extension("datefield", {
296             tag => "",
297             before => sub {
298             my $obj = shift;
299              
300             my $readonly = HTML::Obj2HTML::get_opt("readonly") || $obj->{readonly};
301             delete($obj->{readonly});
302             if ($readonly) {
303             return HTML::Obj2HTML::gen(commonfield($obj, [ span => $obj->{value} ] ));
304             } else {
305             return HTML::Obj2HTML::gen(commonfield($obj, [
306             div => { class => "ui calendar ".$obj->{class}, _ => [
307             div => { class => "ui input left icon", _ => [
308             i => { class => "calendar icon", _ => [] },
309             input => { type => "text", name => $obj->{name}, placeholder => $obj->{placeholder}, value => $obj->{value} }
310             ]}
311             ]}
312             ]));
313             }
314             }
315             });
316             HTML::Obj2HTML::register_extension("hiddeninput", {
317             tag => "input",
318             attr => { type => "hidden" }
319             });
320             HTML::Obj2HTML::register_extension("submit", {
321             tag => "",
322             before => sub {
323             my $obj = shift;
324             my $readonly = HTML::Obj2HTML::get_opt("readonly") || $obj->{readonly};
325             delete($obj->{readonly});
326             if ($readonly) {
327             return [];
328             }
329             if (!ref $obj) { $obj = { value => $obj }; } else { $obj->{value} = $obj->{label}; delete($obj->{label}); }
330             if (defined $obj->{class}) { $obj->{class} .= " ui button"; } else { $obj->{class}.="ui positive button"; }
331             $obj->{type} = "submit";
332             return [ input => $obj ];
333             },
334             });
335              
336             HTML::Obj2HTML::register_extension("cancel", {
337             tag => "",
338             before => sub {
339             my $obj = shift;
340             my $readonly = HTML::Obj2HTML::get_opt("readonly") || $obj->{readonly};
341             delete($obj->{readonly});
342             if ($readonly) {
343             return [];
344             }
345             if (!ref $obj) { $obj = { value => $obj }; } else { $obj->{value} = $obj->{label}; delete($obj->{label}); }
346             if ($obj->{class}) { $obj->{class} .= " "; }
347             $obj->{class}.="ui negative button";
348             return [ a => $obj ];
349             },
350             });
351              
352             HTML::Obj2HTML::register_extension("helplabel", {
353             tag => "label",
354             before => sub {
355             my $o = shift;
356             $o->{_} = [ _ => $o->{label} ];
357             if ($o->{helptext}) {
358             push(@{$o->{_}}, help => { text => $o->{helptext} });
359             }
360             if ($o->{helphtml}) {
361             push(@{$o->{_}}, help => { html => $o->{helphtml} });
362             }
363             delete($o->{label});
364             delete($o->{helptext});
365             delete($o->{helphtml});
366             return "";
367             }
368             });
369              
370             sub genhelplabel {
371 0     0     my $obj = shift;
372 0 0         if ($obj->{label}) {
373 0           my $label = $obj->{label};
374 0 0         if ($obj->{helptext}) {
375 0           $label = [ _ => $label, i => { style => 'margin-left: 5px;', class => 'blue circular icon help', 'data-content' => $obj->{helptext}, _ => [] } ];
376 0           delete($obj->{helptext});
377             }
378 0 0         if ($obj->{helphtml}) {
379 0           $label = [ _ => $label, i => { style => 'margin-left: 5px;', class => 'blue circular icon help', 'data-html' => $obj->{helphtml}, _ => [] } ];
380 0           delete($obj->{helphtml});
381             }
382 0           delete($obj->{label});
383 0           return $label;
384             }
385 0           return;
386             }
387             sub commonfield {
388 0     0     my $obj = shift;
389 0           my $field = shift;
390              
391 0           my $class = "field";
392 0 0         if ($obj->{required}) {
393 0           $class .= " required";
394 0           delete($obj->{required});
395             }
396              
397 0           my $label = genhelplabel($obj);
398 0 0         if ($label) {
399 0           unshift(@{$field}, "label", $label);
  0            
400             };
401 0 0         if ($obj->{uiwidth}) {
402 0           $class .= " $semanticnumbers[$obj->{uiwidth}] wide";
403 0           delete($obj->{uiwidth});
404             }
405 0           return [ div => { class => $class, _ => $field }];
406             }
407             1;