File Coverage

blib/lib/Tags/HTML/Table/View.pm
Criterion Covered Total %
statement 88 88 100.0
branch 14 14 100.0
condition 6 6 100.0
subroutine 14 14 100.0
pod 1 1 100.0
total 123 123 100.0


line stmt bran cond sub pod time code
1             package Tags::HTML::Table::View;
2              
3 7     7   231711 use base qw(Tags::HTML);
  7         14  
  7         4282  
4 7     7   96933 use strict;
  7         13  
  7         210  
5 7     7   42 use warnings;
  7         15  
  7         2631  
6              
7 7     7   52 use Class::Utils qw(set_params split_params);
  7         23  
  7         441  
8 7     7   43 use Error::Pure qw(err);
  7         12  
  7         366  
9 7     7   43 use List::Util 1.33 qw(none);
  7         127  
  7         497  
10 7     7   39 use Scalar::Util qw(blessed);
  7         14  
  7         385  
11 7     7   4142 use Tags::HTML::Element::A;
  7         15534  
  7         7542  
12              
13             our $VERSION = 0.07;
14              
15             # Constructor.
16             sub new {
17 13     13 1 1680593 my ($class, @params) = @_;
18              
19             # Create object.
20 13         72 my ($object_params_ar, $other_params_ar) = split_params(
21             ['css_table', 'header'], @params);
22 13         423 my $self = $class->SUPER::new(@{$other_params_ar});
  13         81  
23              
24             # Main CSS class.
25 13         491 $self->{'css_table'} = 'table';
26              
27             # Header is in first line.
28 13         64 $self->{'header'} = 1;
29              
30             # Process params.
31 13         46 set_params($self, @{$object_params_ar});
  13         43  
32              
33             # Object.
34 13         259 return $self;
35             }
36              
37             sub _cleanup {
38 1     1   20 my $self = shift;
39              
40 1         2 delete $self->{'_data'};
41 1         2 delete $self->{'_no_data'};
42 1         5 delete $self->{'_tags_html_a'};
43              
44 1         2 return;
45             }
46              
47             sub _init {
48 12     12   422 my ($self, $data_ar, $no_data_value) = @_;
49              
50 12         18 $self->{'_data'} = [@{$data_ar}];
  12         38  
51 12         41 $self->{'_no_data'} = $no_data_value;
52             $self->{'_tags_html_a'} = Tags::HTML::Element::A->new(
53             'css' => $self->{'css'},
54 12         96 'tags' => $self->{'tags'},
55             );
56              
57 12         561 return;
58             }
59              
60             # Process 'Tags'.
61             sub _process {
62 11     11   713 my $self = shift;
63              
64 11 100       46 if (! exists $self->{'_data'}) {
65 1         2 return;
66             }
67              
68             # Main content.
69             $self->{'tags'}->put(
70             ['b', 'table'],
71 10         73 ['a', 'class', $self->{'css_table'}],
72             );
73 10         860 my $columns_count = 0;
74 10 100       30 if ($self->{'header'}) {
75 3         15 $self->{'tags'}->put(
76             ['b', 'tr'],
77             );
78 3         108 my $header_ar = shift @{$self->{'_data'}};
  3         18  
79 3         6 foreach my $value (@{$header_ar}) {
  3         8  
80 6         29 $self->{'tags'}->put(
81             ['b', 'th'],
82             ['d', $value],
83             ['e', 'th'],
84             );
85 6         518 $columns_count++;
86             }
87 3         12 $self->{'tags'}->put(
88             ['e', 'tr'],
89             );
90             } else {
91 7         16 $columns_count++;
92             }
93 10         124 foreach my $row_ar (@{$self->{'_data'}}) {
  10         25  
94 8         34 $self->{'tags'}->put(
95             ['b', 'tr'],
96             );
97 8         309 foreach my $value (@{$row_ar}) {
  8         18  
98 16         486 $self->{'tags'}->put(
99             ['b', 'td'],
100             );
101 16         685 $self->_value($value);
102 14         41 $self->{'tags'}->put(
103             ['e', 'td'],
104             );
105             }
106 6         290 $self->{'tags'}->put(
107             ['e', 'tr'],
108             );
109             }
110              
111             # No data row.
112 8 100 100     278 if (! @{$self->{'_data'}} && defined $self->{'_no_data'}) {
  8         40  
113 1         8 $self->{'tags'}->put(
114             ['b', 'tr'],
115             ['b', 'td'],
116             ['a', 'colspan', $columns_count],
117             );
118 1         104 $self->_value($self->{'_no_data'});
119 1         4 $self->{'tags'}->put(
120             ['e', 'td'],
121             ['e', 'tr'],
122             );
123             }
124              
125 8         120 $self->{'tags'}->put(
126             ['e', 'table'],
127             );
128              
129 8         361 return;
130             }
131              
132             # Process 'CSS::Struct'.
133             sub _process_css {
134 1     1   26 my $self = shift;
135              
136             $self->{'css'}->put(
137             ['s', '.'.$self->{'css_table'}],
138             ['s', '.'.$self->{'css_table'}.' td'],
139             ['s', '.'.$self->{'css_table'}.' th'],
140             ['d', 'border', '1px solid #ddd'],
141             ['d', 'text-align', 'left'],
142             ['e'],
143              
144             ['s', '.'.$self->{'css_table'}],
145             ['d', 'border-collapse', 'collapse'],
146             ['d', 'width', '100%'],
147             ['e'],
148              
149             ['s', '.'.$self->{'css_table'}.' th'],
150 1         31 ['s', '.'.$self->{'css_table'}.' td'],
151             ['d', 'padding', '15px'],
152             ['e'],
153             );
154              
155 1         301 return;
156             }
157              
158             sub _value {
159 17     17   35 my ($self, $value) = @_;
160              
161 17 100 100     81 if (ref $value eq '') {
    100          
    100          
    100          
162 12         45 $self->{'tags'}->put(
163             ['d', $value],
164             );
165             } elsif (ref $value eq 'ARRAY') {
166 1         3 $self->{'tags'}->put(@{$value});
  1         5  
167             } elsif (ref $value eq 'CODE') {
168 1         6 $value->($self);
169             } elsif (blessed($value) && $value->isa('Data::HTML::Element::A')) {
170 1         9 $self->{'_tags_html_a'}->init($value);
171 1         28 $self->{'_tags_html_a'}->process;
172             } else {
173 2         58 err 'Bad value object.';
174             }
175              
176 15         746 return;
177             }
178              
179             1;
180              
181             __END__
182              
183             =pod
184              
185             =encoding utf8
186              
187             =head1 NAME
188              
189             Tags::HTML::Table::View - Tags helper for table view.
190              
191             =head1 SYNOPSIS
192              
193             use Tags::HTML::Table::View;
194              
195             my $obj = Tags::HTML::Table::View->new(%params);
196             $obj->cleanup;
197             $obj->init($data_ar, $no_data_value);
198             $obj->process;
199             $obj->process_css;
200              
201             =head1 METHODS
202              
203             =head2 C<new>
204              
205             my $obj = Tags::HTML::Table::View->new(%params);
206              
207             Constructor.
208              
209             Returns instance of object.
210              
211             =over 8
212              
213             =item * C<css>
214              
215             'L<CSS::Struct::Output>' object for L</process_css> processing.
216              
217             Default value is undef.
218              
219             =item * C<css_table>
220              
221             CSS class for table.
222              
223             Default value is 'table'.
224              
225             =item * C<header>
226              
227             Boolean flag, that means that header is in first line.
228              
229             Default value is 1.
230              
231             =item * C<tags>
232              
233             'L<Tags::Output>' object for L</process> processing.
234              
235             Default value is undef.
236              
237             =back
238              
239             =head2 C<cleanup>
240              
241             $obj->cleanup;
242              
243             Process cleanup after page run.
244              
245             Returns undef.
246              
247             =head2 C<init>
248              
249             $obj->init($data_ar, $no_data_value);
250              
251             Process initialization before page run.
252              
253             Variable C<$data_ar> are data for table. Each item in array could be:
254              
255             =over
256              
257             =item * Scalar
258              
259             Add scalar variable to field.
260              
261             =item * Array with scalars
262              
263             Add scalar variables to field.
264              
265             =item * Code
266              
267             Run this code with argument C<$self> of this module.
268              
269             =item * L<Data::HTML::Element::A> instance
270              
271             Serialize link to field.
272              
273             =back
274              
275             Variable C<$no_data_value> contain information for situation when data in table not
276             exists.
277              
278             Returns undef.
279              
280             =head2 C<process>
281              
282             $obj->process;
283              
284             Process L<Tags> structure for table view.
285              
286             Returns undef.
287              
288             =head2 C<process_css>
289              
290             $obj->process_css;
291              
292             Process L<CSS::Struct> structure for output.
293              
294             Returns undef.
295              
296             =head1 ERRORS
297              
298             new():
299             From Class::Utils::set_params():
300             Unknown parameter '%s'.
301             From Tags::HTML::new():
302             Parameter 'css' must be a 'CSS::Struct::Output::*' class.
303             Parameter 'tags' must be a 'Tags::Output::*' class.
304              
305             process():
306             From Tags::HTML::process():
307             Parameter 'tags' isn't defined.
308             Bad value object.
309              
310             process_css():
311             From Tags::HTML::process_css():
312             Parameter 'css' isn't defined.
313              
314             =head1 EXAMPLE1
315              
316             =for comment filename=print_table_with_data.pl
317              
318             use strict;
319             use warnings;
320              
321             use CSS::Struct::Output::Indent;
322             use Tags::HTML::Table::View;
323             use Tags::Output::Indent;
324              
325             # Object.
326             my $css = CSS::Struct::Output::Indent->new;
327             my $tags = Tags::Output::Indent->new;
328             my $obj = Tags::HTML::Table::View->new(
329             'css' => $css,
330             'tags' => $tags,
331             );
332              
333             # Table data.
334             my $table_data_ar = [
335             ['Country', 'Capital'],
336             ['Czech Republic', 'Prague'],
337             ['Russia', 'Moscow'],
338             ];
339              
340             # Process login button.
341             $obj->init($table_data_ar, 'No data.');
342             $obj->process_css;
343             $tags->put(['b', 'body']);
344             $obj->process;
345             $tags->put(['e', 'body']);
346             $obj->cleanup;
347              
348             # Print out.
349             print "CSS\n";
350             print $css->flush."\n\n";
351             print "HTML\n";
352             print $tags->flush."\n";
353              
354             # Output:
355             # CSS
356             # .table, .table td, .table th {
357             # border: 1px solid #ddd;
358             # text-align: left;
359             # }
360             # .table {
361             # border-collapse: collapse;
362             # width: 100%;
363             # }
364             # .table th, .table td {
365             # padding: 15px;
366             # }
367             #
368             # HTML
369             # <body>
370             # <table class="table">
371             # <tr>
372             # <th>
373             # Country
374             # </th>
375             # <th>
376             # Capital
377             # </th>
378             # </tr>
379             # <tr>
380             # <td>
381             # Czech Republic
382             # </td>
383             # <td>
384             # Prague
385             # </td>
386             # </tr>
387             # <tr>
388             # <td>
389             # Russia
390             # </td>
391             # <td>
392             # Moscow
393             # </td>
394             # </tr>
395             # </table>
396             # </body>
397              
398             =head1 EXAMPLE2
399              
400             =for comment filename=print_table_without_data.pl
401              
402             use strict;
403             use warnings;
404              
405             use CSS::Struct::Output::Indent;
406             use Tags::HTML::Table::View;
407             use Tags::Output::Indent;
408              
409             # Object.
410             my $css = CSS::Struct::Output::Indent->new;
411             my $tags = Tags::Output::Indent->new;
412             my $obj = Tags::HTML::Table::View->new(
413             'css' => $css,
414             'tags' => $tags,
415             );
416              
417             # Table data.
418             my $table_data_ar = [
419             ['Country', 'Capital'],
420             ];
421              
422             # Process login button.
423             $obj->init($table_data_ar, 'No data.');
424             $obj->process_css;
425             $tags->put(['b', 'body']);
426             $obj->process;
427             $tags->put(['e', 'body']);
428             $obj->cleanup;
429              
430             # Print out.
431             print "CSS\n";
432             print $css->flush."\n\n";
433             print "HTML\n";
434             print $tags->flush."\n";
435              
436             # Output:
437             # CSS
438             # .table, .table td, .table th {
439             # border: 1px solid #ddd;
440             # text-align: left;
441             # }
442             # .table {
443             # border-collapse: collapse;
444             # width: 100%;
445             # }
446             # .table th, .table td {
447             # padding: 15px;
448             # }
449             #
450             # HTML
451             # <body>
452             # <table class="table">
453             # <tr>
454             # <th>
455             # Country
456             # </th>
457             # <th>
458             # Capital
459             # </th>
460             # </tr>
461             # <tr>
462             # <td colspan="2">
463             # No data.
464             # </td>
465             # </tr>
466             # </table>
467             # </body>
468              
469             =head1 EXAMPLE3
470              
471             =for comment filename=print_table_with_data_object.pl
472              
473             use strict;
474             use warnings;
475              
476             use CSS::Struct::Output::Indent;
477             use Data::HTML::Element::A;
478             use Tags::HTML::Table::View;
479             use Tags::Output::Indent;
480              
481             # Object.
482             my $css = CSS::Struct::Output::Indent->new;
483             my $tags = Tags::Output::Indent->new;
484             my $obj = Tags::HTML::Table::View->new(
485             'css' => $css,
486             'tags' => $tags,
487             );
488              
489             # Table data.
490             my $prague = Data::HTML::Element::A->new(
491             'data' => ['Prague'],
492             'url' => 'https://prague.cz',
493             );
494             my $table_data_ar = [
495             ['Country', 'Capital'],
496             ['Czech Republic', $prague],
497             ['Russia', 'Moscow'],
498             ];
499              
500             # Process login button.
501             $obj->init($table_data_ar, 'No data.');
502             $obj->process_css;
503             $tags->put(['b', 'body']);
504             $obj->process;
505             $tags->put(['e', 'body']);
506             $obj->cleanup;
507              
508             # Print out.
509             print "CSS\n";
510             print $css->flush."\n\n";
511             print "HTML\n";
512             print $tags->flush."\n";
513              
514             # Output:
515             # CSS
516             # .table, .table td, .table th {
517             # border: 1px solid #ddd;
518             # text-align: left;
519             # }
520             # .table {
521             # border-collapse: collapse;
522             # width: 100%;
523             # }
524             # .table th, .table td {
525             # padding: 15px;
526             # }
527             #
528             # HTML
529             # <body>
530             # <table class="table">
531             # <tr>
532             # <th>
533             # Country
534             # </th>
535             # <th>
536             # Capital
537             # </th>
538             # </tr>
539             # <tr>
540             # <td>
541             # Czech Republic
542             # </td>
543             # <td>
544             # <a href="https://prague.cz">
545             # Prague
546             # </a>
547             # </td>
548             # </tr>
549             # <tr>
550             # <td>
551             # Russia
552             # </td>
553             # <td>
554             # Moscow
555             # </td>
556             # </tr>
557             # </table>
558             # </body>
559              
560             =head1 DEPENDENCIES
561              
562             L<Class::Utils>,
563             L<Error::Pure>,
564             L<List::Util>,
565             L<Scalar::Util>,
566             L<Tags::HTML>,
567             L<Tags::HTML::Element::A>.
568              
569             =head1 REPOSITORY
570              
571             L<https://github.com/michal-josef-spacek/Tags-HTML-Table-View>
572              
573             =head1 AUTHOR
574              
575             Michal Josef Špaček L<mailto:skim@cpan.org>
576              
577             L<http://skim.cz>
578              
579             =head1 LICENSE AND COPYRIGHT
580              
581             © 2021-2024 Michal Josef Špaček
582              
583             BSD 2-Clause License
584              
585             =head1 VERSION
586              
587             0.07
588              
589             =cut