Revision cea0e38d
Von Sven Schöling vor mehr als 7 Jahren hinzugefügt
SL/Layout/ActionBar.pm | ||
---|---|---|
85 | 85 |
|
86 | 86 |
SL::Layout::ActionBar - Unified action buttons for controllers |
87 | 87 |
|
88 |
=head1 SYNOPSIS |
|
89 |
|
|
90 |
# short sugared syntax: |
|
91 |
for my $bar ($::request->layout->get('actionbar')) { |
|
92 |
$bar->add( |
|
93 |
action => [ |
|
94 |
t8('Description'), |
|
95 |
call => [ 'kivi.Javascript.function', @arguments ], |
|
96 |
accesskey => 'enter', |
|
97 |
disabled => $tooltip_with_reason_or_falsish, |
|
98 |
only_if => $precomputed_condition, |
|
99 |
not_if => $precomputed_condition, |
|
100 |
id => 'html-element-id', |
|
101 |
], |
|
102 |
combobox => [ |
|
103 |
action => [...], |
|
104 |
action => [...], |
|
105 |
action => [...], |
|
106 |
action => [...], |
|
107 |
], |
|
108 |
link => [ |
|
109 |
t8('Description'), |
|
110 |
link => $url, |
|
111 |
], |
|
112 |
'separator', |
|
113 |
); |
|
114 |
} |
|
115 |
|
|
116 |
# full syntax without sugar |
|
117 |
for my $bar ($::request->layout->get('actionbar')) { |
|
118 |
$bar->add( |
|
119 |
(SL::Layout::ActionBar::Action->new( |
|
120 |
text => t8('Description'), |
|
121 |
params => { |
|
122 |
call => [ 'kivi.Javascript.function', @arguments ], |
|
123 |
accesskey => 'enter', |
|
124 |
disabled => $tooltip_with_reason_or_falsish, |
|
125 |
}, |
|
126 |
)) x(!!$only_id && !$not_if), |
|
127 |
SL::Layout::ActionBar::ComboBox->new( |
|
128 |
actions => [ |
|
129 |
SL::Layout::ActionBar::Action->new(...), |
|
130 |
SL::Layout::ActionBar::Action->new(...), |
|
131 |
SL::Layout::ActionBar::Action->new(...), |
|
132 |
SL::Layout::ActionBar::Action->new(...), |
|
133 |
], |
|
134 |
), |
|
135 |
SL::Layout::ActionBar::Link->new( |
|
136 |
text => t8('Description'), |
|
137 |
params => { |
|
138 |
link => $url, |
|
139 |
}, |
|
140 |
), |
|
141 |
SL::Layout::ActionBar::Separator->new, |
|
142 |
); |
|
143 |
} |
|
144 |
|
|
88 | 145 |
=head1 CONCEPT |
89 | 146 |
|
90 |
This is a layout block that does a unified action bar for any controller who
|
|
147 |
This is a layout block that creates an action bar for any controller who
|
|
91 | 148 |
wants to use it. It's designed to be rendered above the content and to be |
92 |
fixed when scrolling. |
|
149 |
fixed when scrolling. It's structured as a container for elements that can be |
|
150 |
extended when needed. |
|
93 | 151 |
|
94 |
While it can be used as a generic widget container, it's designed to be able to |
|
95 |
provide commonly used functionality as a short cut. These shortcuts include: |
|
152 |
=head1 METHODS |
|
96 | 153 |
|
97 | 154 |
=over 4 |
98 | 155 |
|
99 |
=item * |
|
156 |
=item * C<new>
|
|
100 | 157 |
|
101 |
Calling a controller with parameters |
|
158 |
Will be used during initialization of the layout. You should never have to |
|
159 |
instanciate an action bar yourself. Get the current request instances from |
|
102 | 160 |
|
103 |
=item *
|
|
161 |
$::request->layout->get('actionbar')
|
|
104 | 162 |
|
105 |
Submitting a form with added parameters
|
|
163 |
instead.
|
|
106 | 164 |
|
107 |
=item * |
|
165 |
=item * C<add>
|
|
108 | 166 |
|
109 |
Arrangement utility |
|
167 |
Add new elements to the bar. Can be instances of |
|
168 |
L<SL::Layout::ActionBar::Action> or scalar strings matching the sugar syntax |
|
169 |
which is described further down. |
|
110 | 170 |
|
111 | 171 |
=back |
112 | 172 |
|
173 |
=head1 SYNTACTIC SUGAR |
|
113 | 174 |
|
114 |
=head1 METHODS |
|
175 |
Instead of passing full objects to L</add>, you can instead pass the arguments |
|
176 |
to be used for instantiation to make the code easier to read. The short syntax |
|
177 |
looks like this: |
|
178 |
|
|
179 |
type => [ |
|
180 |
localized_description, |
|
181 |
param => value, |
|
182 |
param => value, |
|
183 |
... |
|
184 |
] |
|
185 |
|
|
186 |
A string type, followed by the parameters needed for that type. Type may be one of: |
|
187 |
|
|
188 |
=over 4 |
|
189 |
|
|
190 |
=item * C<action> |
|
191 |
|
|
192 |
=item * C<combobox> |
|
193 |
|
|
194 |
=item * C<link> |
|
195 |
|
|
196 |
=item * C<separator> |
|
197 |
|
|
198 |
=back |
|
199 |
|
|
200 |
C<separator> will use no parameters, the other three will expect one arrayref. |
|
201 |
|
|
202 |
Two additional pseuso parameters are supported for those: |
|
115 | 203 |
|
116 | 204 |
=over 4 |
117 | 205 |
|
118 |
=item C<add LIST>
|
|
206 |
=item * C<only_if>
|
|
119 | 207 |
|
120 |
to be documented
|
|
208 |
=item * C<not_if>
|
|
121 | 209 |
|
122 | 210 |
=back |
123 | 211 |
|
124 |
=head1 ACCESS FROM CODE |
|
212 |
These are meant to reduce enterprise operators (C<()x!!>) when conditionally adding lots |
|
213 |
of elements. |
|
125 | 214 |
|
126 |
This is accessable through |
|
215 |
The combobox element is in itself a container and will simply expect the same |
|
216 |
syntax in an arrayref. |
|
127 | 217 |
|
128 |
$::request->layout->get('actionbar') |
|
218 |
For the full list of parameters supported by the elements, see L<SL::Layout::ActionBar::Action/RECOGNIZED PARAMETERS>. |
|
219 |
|
|
220 |
|
|
221 |
=head1 GUIDELINES |
|
222 |
|
|
223 |
The current implementation follows these design guidelines: |
|
129 | 224 |
|
130 |
=head1 DOM MODEL |
|
225 |
=over 4 |
|
226 |
|
|
227 |
=item * |
|
228 |
|
|
229 |
Don't put too many elements into the action bar. Group into comboboxes if |
|
230 |
possible. Consider seven elements a reasonable limit. |
|
231 |
|
|
232 |
=item * |
|
233 |
|
|
234 |
If you've got an update button, put it first and bind the enter accesskey to |
|
235 |
it. |
|
236 |
|
|
237 |
=item * |
|
238 |
|
|
239 |
Put mutating actions (save, post, delete, check out, ship) before the separator |
|
240 |
and non mutating actions (export, search, history, workflow) after the |
|
241 |
separator. Combined actions (save and close) still mutate and go before the |
|
242 |
separator. |
|
243 |
|
|
244 |
=item * |
|
245 |
|
|
246 |
Avoid abusing the actionbar as a secondary menu. As a principle every action |
|
247 |
should act upon the current element or topic. |
|
131 | 248 |
|
132 |
The entire block is rendered into a div with the class 'layout-actionbar'. |
|
249 |
=item * |
|
250 |
|
|
251 |
Hide elements with C<only_if> if they are known to be useless for the current |
|
252 |
topic, but disable when they would be useful in principle but are not |
|
253 |
applicable right now. For example C<delete> does not make sense in a creating |
|
254 |
form, but makes still sense because the element can be deleted later. This |
|
255 |
keeps the actionbar stable and reduces surprising elements that only appear in |
|
256 |
rare situations. |
|
133 | 257 |
|
134 |
=head1 ACTION WIDGETS
|
|
258 |
=item *
|
|
135 | 259 |
|
136 |
Each individual action must be an instance of C<SL::Layout::ActionBar::Action>. |
|
260 |
Always add a tooltip when disabling an action. |
|
261 |
|
|
262 |
=item * |
|
263 |
|
|
264 |
Try to always add a default action with accesskey enter. Since the actionbar |
|
265 |
lies outside of the main form, the usual submit on enter does not work out of |
|
266 |
the box. |
|
267 |
|
|
268 |
=back |
|
269 |
|
|
270 |
=head1 DOM MODEL AND IMPLEMENTATION DETAILS |
|
271 |
|
|
272 |
The entire block is rendered into a div with the class 'layout-actionbar'. Each |
|
273 |
action will render itself and will get added to the div. To keep the DOM small |
|
274 |
and reduce startup overhead, the presentation is pure CSS and only the sticky |
|
275 |
expansion of comboboxes is done with javascript. |
|
276 |
|
|
277 |
To keep startup times and HTML parsing fast the action data is simply written |
|
278 |
into the data elements of the actions and handlers are added in a ready hook. |
|
137 | 279 |
|
138 | 280 |
=head1 BUGS |
139 | 281 |
|
140 | 282 |
none yet. :) |
141 | 283 |
|
284 |
=head1 SEE ALSO |
|
285 |
|
|
286 |
L<SL::Layout::ActioBar::Base>, |
|
287 |
L<SL::Layout::ActioBar::Action>, |
|
288 |
L<SL::Layout::ActioBar::Submit>, |
|
289 |
L<SL::Layout::ActioBar::ComboBox>, |
|
290 |
L<SL::Layout::ActioBar::Separator>, |
|
291 |
L<SL::Layout::ActioBar::Link>, |
|
292 |
|
|
142 | 293 |
=head1 AUTHOR |
143 | 294 |
|
144 | 295 |
Sven Schoeling E<lt>s.schoeling@linet-services.deE<gt> |
Auch abrufbar als: Unified diff
ActionBar Dokumentation