Auftrags-Controller: Speichern und schließen, …
[kivitendo-erp.git] / SL / Template / Plugin / JavaScript.pm
1 package SL::Template::Plugin::JavaScript;
2
3 use base qw( Template::Plugin );
4 use Template::Plugin;
5
6 use strict;
7
8 sub new {
9   my ($class, $context, @args) = @_;
10
11   return bless {
12     CONTEXT => $context,
13   }, $class;
14 }
15
16 #
17 # public interface
18 #
19
20 # see ecmascript spec section 7.8.4
21 my @escape_chars = ('\\', '\'', '"');
22 my %control_chars = (
23   "\n"   => 'n',
24   "\t"   => 't',
25   "\r"   => 'r',
26   "\f"   => 'f',
27   "\x08" => 'b',
28   "\x0B" => 'v', # noone uses vertical tab anyway...
29 );
30 my $re = join '', map { qr/($_)/s } join '|', keys(%control_chars), map { "\Q$_\E" } @escape_chars;
31
32 sub escape {
33   my $self = shift;
34   my $text = shift;
35
36   $text =~ s/$re/'\\' . ($control_chars{$1} || $1)/egs;
37
38   return $text;
39 }
40
41 sub replace_with {
42   return _replace_helper('replaceWith', @_);
43 }
44
45 sub replace_html_with {
46   return _replace_helper('html', @_);
47 }
48
49 #
50 # private methods
51 #
52
53 sub _context {
54   die 'not an accessor' if @_ > 1;
55   return $_[0]->{CONTEXT};
56 }
57
58 sub _replace_helper {
59   my ($method, $self, $selector, $template, $locals) = @_;
60
61   $template .= '.html' unless $template =~ m/\.html$/;
62   my $html   = $self->escape($self->_context->process($template, %{ $locals || { } }));
63   my $code = <<CODE;
64 \$('${selector}').${method}("$html");
65 CODE
66
67   return $code;
68 }
69
70 1;
71
72
73 __END__
74
75 =pod
76
77 =encoding utf8
78
79 =head1 NAME
80
81 SL::Template::Plugin::JavaScript - Template plugin for JavaScript helper functions
82
83 =head1 FUNCTIONS
84
85 =over 4
86
87 =item C<escape $value>
88
89 Returns C<$value> escaped for inclusion in a JavaScript string. The
90 value is not wrapped in quotes. Example:
91
92   <input type="submit" value="Delete"
93          onclick="if (confirm('Do you really want to delete this: [% JavaScript.escape(obj.description) %]') return true; else return false;">
94
95 =item C<replace_with $selector, $template, %locals>
96
97 Returns code replacing the DOM elements matched by C<$selector> with
98 the content rendered by Template's I<PROCESS> directive applied to
99 C<$template>. C<%locals> are passed as local parameters to I<PROCESS>.
100
101 Uses jQuery's C<obj.replaceWith()> function. Requires jQuery to be loaded.
102
103 Example:
104
105   <div>TODO:</div>
106   <ul>
107     <li id="item1">First item</li>
108     <li id="item2">Second item</li>
109     <li id="item3">Another item</li>
110   </ul>
111
112   <script type="text/javascript">
113     function do_work() {
114       [% JavaScript.replace_with('#item2', 'todo/single_item', item => current_todo_item) %]
115     }
116   </script>
117
118   <input type="submit" onclick="do_work(); return false;" value="Replace single item">
119
120 =item C<replace_html_with $selector, $template, %locals>
121
122 Returns code replacing the inner HTML of the DOM elements matched by
123 C<$selector> with the content rendered by Template's I<PROCESS>
124 directive applied to C<$template>. C<%locals> are passed as local
125 parameters to I<PROCESS>.
126
127 Uses jQuery's C<obj.html()> function. Requires jQuery to be loaded.
128
129   <div>TODO:</div>
130   <ul id="todo_list">
131     <li id="item1">First item</li>
132     <li id="item2">Second item</li>
133     <li id="item3">Another item</li>
134   </ul>
135
136   <script type="text/javascript">
137     function do_work() {
138       [% JavaScript.replace_html_with('#todo_list', 'todo/full_list', items => todo_items) %]
139     }
140   </script>
141
142   <input type="submit" onclick="do_work(); return false;" value="Replace list">
143
144 =back
145
146 =head1 BUGS
147
148 Nothing here yet.
149
150 =head1 AUTHOR
151
152 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
153
154 =cut