90eb8498ca002d589825735c1057cb0d1db8be81
[kivitendo-erp.git] / SL / Layout / ActionBar / Action.pm
1 package SL::Layout::ActionBar::Action;
2
3 use strict;
4 use parent qw(Rose::Object);
5
6 use SL::Presenter;
7
8 use Rose::Object::MakeMethods::Generic (
9   'scalar --get_set_init' => [ qw(id params text) ],
10 );
11
12 # subclassing interface
13
14 sub render {
15   die 'needs to be implemented';
16 }
17
18 sub script {
19   sprintf q|$('#%s').data('action', %s);|, $_[0]->id, JSON->new->allow_blessed->convert_blessed->encode($_[0]->params);
20 }
21
22 # this is mostly so that outside consumer don't need to load subclasses themselves
23 sub from_params {
24   my ($class, $data) = @_;
25
26   require SL::Layout::ActionBar::Submit;
27
28   my ($text, %params) = @$data;
29   return if exists($params{only_if}) && !$params{only_if};
30   return if exists($params{not_if})  &&  $params{not_if};
31   return SL::Layout::ActionBar::Submit->new(text => $text, params => \%params);
32 }
33
34 sub callable { 0 }
35
36 # shortcut for presenter
37
38 sub p {
39   SL::Presenter->get
40 }
41
42 sub init_params {
43   +{}
44 }
45
46 # unique id to tie div and javascript together
47 sub init_id {
48   $_[0]->params->{id} //
49   $_[0]->p->name_to_id('action[]')
50 }
51
52 1;
53
54 __END__
55
56 =encoding utf-8
57
58 =head1 NAME
59
60 SL::Layout::ActionBar::Action - base class for action bar actions
61
62 =head1 DESCRIPTION
63
64 This base class for actions can be used to implement elements that can be
65 added to L<SL::Layout::ActionBar>.
66
67 Elements can be interactive or simply used for layout. Most of the actual
68 semantics are handled in the corresponding javascript C<js/kivi.ActionBar.js>, so
69 this is only used to generate the DOM elements and to provide information for
70 request time logic decisions.
71
72
73 =head1 SYNOPSIS
74
75   # implement:
76   package SL::Layout::ActionBar::Custom;
77   use parent qw(SL::Layout::ActionBar::Action);
78
79   # unsugared use
80   SL::Layout::ActionBar::Custom->new(
81     text   => t8('Description'),
82     params => {
83       key => $attr,
84       key => $attr,
85       ...
86     },
87   );
88
89   # parse sugared version:
90   SL::Layout::ActionBar::Custom->from_params(
91     t8('Description'),
92     key => $attr,
93     key => $attr,
94     ...
95   );
96
97 =head1 INTERFACE
98
99 =over 4
100
101 =item * C<render>
102
103 Needs to be implemented. Should render only the bare minimum necessary to
104 identify the element at run time.
105
106 =item * C<script>
107
108 Will be called during layout rendering. Defaults to dumping the params section
109 into data field of the rendered DOM element.
110
111 =item * C<from_params>
112
113 Parse sugared version. Defaults for historic reasons to the implementation of
114 L<SL::Layout::ActionBar::Submit>, all others must implement their own.
115
116 =item * C<callable>
117
118 Used to determine whether an instance is callable or only a layout element.
119
120 =back
121
122 =head1 METHODS
123
124 =over 4
125
126 =item * C<p>
127
128 Returns the current request presenter.
129
130 =item * C<id>
131
132 Will get initialized to either the provided id from the params or to a
133 generated unique id. Should be used to tie the rendered DOM and script
134 together.
135
136 =back
137
138 =head1 RECOGNIZED PARAMETERS
139
140 =over 4
141
142 =item * C<< submit => [ $selector, \%params ] >>
143
144 On click, submit the form found with the first parameter. If params is present
145 and a hashref, the key value elements will be added to the form before
146 submitting. Beware that this will destroy the form if the user uses the browser
147 history to jump back to this page, so ony use parametrized submits for post
148 submits that redirect on completion.
149
150 =item * C<< link => $url >>
151
152 On click, will load the given url.
153
154 =item * C<< call => [ $function_name, @args ] >>
155
156 On click, will call the function name with the argument array. The return will
157 be discarded. It is assumed that the fucntion will trigger an asynchronous
158 action.
159
160 Contrast with C<checks>.
161
162 =item * C<< checks => \@function_names >>
163
164 Before any of C<submit>, C<link>, or C<call> are evaluated all
165 functions in C<check> are called. Only if all of them return a true value the
166 action will be triggered.
167
168 Checks are expected not to trigger asynchronous actions (contrast with C<call>),
169 but may change the DOM to indicate to the user why they fail.
170
171 Each must return a boolean value.
172
173 =item * C<< confirm => t8('Yes/No Question') >>
174
175 Before any of C<submit>, C<link>, or C<call> are evaluated, the user
176 will be asked to confirm. If checks are present and failed, confirm will not be
177 triggered.
178
179 =item * C<< only_if => $bool >>
180
181 Pseudo parameter. If present and false, the element will not be rendered.
182
183 =item * C<< not_if => $bool >>
184
185 Pseudo parameter. If present and true, the element will not be rendered.
186
187 =item * C<< only_once => 1 >>
188
189 If present, a click will C<disable> the action to prevent multiple activations.
190
191 =item * C<< accesskey => $text >>
192
193 Registers an accesskey for this element. While the most common accesskey is
194 'enter', in theory every other should work as well. Modifier keys can be added
195 to the accesskey string with 'ctrl+', 'alt+', or 'shift+'. 'shift+' is not
196 necessary for upper case letters.
197
198 =item * C<< disabled => t8('tooltip') >>
199
200 Renders the element disabled, ignores all actions (C<submit>, C<call>, C<link>)
201 and adds the given tooltip hopefully explaining why the element is disabled.
202
203 =item * C<< id => $id >>
204
205 Sets the DOM id of the rendered element. If missing, the element will get a
206 random id.
207
208 =item * C<< tooltip => t8('tooltip') >>
209
210 Sets a tooltip for the element.
211
212 =back
213
214 =head1 BUGS
215
216 None yet :)
217
218 =head1 AUTHOR
219
220 Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
221
222 =cut