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