File Coverage

blib/lib/HTML/Widget/Plugin/Calendar.pm
Criterion Covered Total %
statement 46 46 100.0
branch 8 18 44.4
condition 4 10 40.0
subroutine 9 9 100.0
pod 3 3 100.0
total 70 86 81.4


line stmt bran cond sub pod time code
1 1     1   31625 use strict;
  1         2  
  1         30  
2 1     1   5 use warnings;
  1         2  
  1         53  
3             package HTML::Widget::Plugin::Calendar;
4             # ABSTRACT: simple construction of jscalendar inputs
5             $HTML::Widget::Plugin::Calendar::VERSION = '0.022';
6 1     1   775 use parent qw(HTML::Widget::Plugin Class::Data::Inheritable);
  1         280  
  1         5  
7              
8 1     1   9452 use HTML::Element;
  1         27411  
  1         6  
9 1     1   1353 use HTML::TreeBuilder;
  1         8265  
  1         10  
10 1     1   964 use Data::JavaScript::Anon;
  1         9983  
  1         524  
11              
12             #pod =head1 SYNOPSIS
13             #pod
14             #pod $factory->calendar({
15             #pod name => 'date_of_birth',
16             #pod format => '%Y-%m-%d',
17             #pod value => $user->date_of_birth,
18             #pod });
19             #pod
20             #pod =head1 DESCRIPTION
21             #pod
22             #pod This module plugs in to HTML::Widget::Factory and provides a calendar widget
23             #pod using the excellent jscalendar.
24             #pod
25             #pod =head1 METHODS
26             #pod
27             #pod =head2 C< provided_widgets >
28             #pod
29             #pod This plugin provides the following widgets: calendar, calendar_js
30             #pod
31             #pod =cut
32              
33 1     1 1 17999 sub provided_widgets { qw(calendar calendar_js) }
34              
35             #pod =head2 calendar
36             #pod
37             #pod =cut
38              
39             sub calendar {
40 1     1 1 1000 my ($self, $factory, $arg) = @_;
41 1   33     11 $arg->{attr}{name} ||= $arg->{attr}{id};
42              
43 1 50       15 Carp::croak "you must supply a widget id for calendar"
44             unless $arg->{attr}{id};
45              
46 1   50     10 $arg->{jscalendar} ||= {};
47 1 50       4 $arg->{jscalendar}{showsTime} = 1 if $arg->{time};
48              
49 1 0 33     4 $arg->{format}
50             ||= '%Y-%m-%d' . ($arg->{jscalendar}{showsTime} ? ' %H:%M' : '');
51              
52 1         7 my $widget = HTML::Element->new('input');
53 1         29 $widget->attr($_ => $arg->{attr}{$_}) for keys %{ $arg->{attr} };
  1         8  
54 1 50       27 $widget->attr(value => $arg->{value}) if exists $arg->{value};
55              
56 1         1 my $button;
57              
58 1 50       3 unless ($arg->{no_button}) {
59 1         6 $button = HTML::Element->new(
60             'button',
61             id => $arg->{attr}{id} . "_button"
62             );
63 1   50     37 $button->push_content($arg->{button_label} || '...');
64             }
65              
66 1         17 my $script = HTML::Element->new('script', type => 'text/javascript');
67 1         36 my $js
68             = sprintf "Calendar.setup(%s);",
69             Data::JavaScript::Anon->anon_dump({
70             inputField => $widget->attr('id'),
71             ifFormat => $arg->{format},
72             ($arg->{no_button} ? () : (button => $button->attr('id'))),
73 1 50       24 %{ $arg->{jscalendar} },
74             })
75             ;
76              
77             # we need to make this an HTML::Element literal to avoid escaping the JS
78 1         247 $js = HTML::Element->new('~literal', text => $js);
79              
80 1         25 $script->push_content($js);
81              
82 3         542 return join q{},
83             $self->calendar_js($factory, $arg),
84 1 50       17 map { $_->as_XML } ($widget, ($arg->{no_button} ? () : $button), $script),
85             ;
86             }
87              
88             #pod =head2 C< calendar_js >
89             #pod
90             #pod This method returns the JavaScript needed to use the calendar. It will only
91             #pod return the JavaScript the first time it's called.
92             #pod
93             #pod Normally it's called when the calendar widget is used, but it may be called
94             #pod manually to force the JavaScript to be placed in your document at the location
95             #pod of your choosing.
96             #pod
97             #pod =cut
98              
99             sub calendar_js {
100 1     1 1 3 my ($self, $factory, $arg) = @_;
101              
102 1 50       10 return '' if $factory->{$self}->{output_js}++;
103              
104 1         5 my $base = $self->calendar_baseurl;
105 1 50       9 Carp::croak "calendar_baseurl is not defined" if not defined $base;
106              
107 1         4 $base =~ s{/\z}{}; # to avoid baseurl//yourface or baseurlyourface
108              
109 1         7 my $scripts = <
110            
111            
112            
113             END_HTML
114              
115             }
116              
117             #pod =head2 C< calendar_baseurl >
118             #pod
119             #pod This method sets or returns the plugin's base URL for the jscalendar files.
120             #pod This must be set or calendar plugin creation will throw an exception.
121             #pod
122             #pod =cut
123              
124             __PACKAGE__->mk_classdata( qw(calendar_baseurl) );
125              
126             1;
127              
128             __END__