X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;ds=sidebyside;f=SL%2FLayout%2FActionBar.pm;h=32c2f7d7ee9fe665f782d7dfc694459da7625bad;hb=826d79929635c726f7459296fafa7e630c00e72d;hp=3279ba8dcb19aa6bd25b5a320229d13d9eba893c;hpb=b459f8fedcdf0f7589862d11ca7b2fbaf2dfc91e;p=kivitendo-erp.git diff --git a/SL/Layout/ActionBar.pm b/SL/Layout/ActionBar.pm index 3279ba8dc..32c2f7d7e 100644 --- a/SL/Layout/ActionBar.pm +++ b/SL/Layout/ActionBar.pm @@ -85,60 +85,211 @@ __END__ SL::Layout::ActionBar - Unified action buttons for controllers +=head1 SYNOPSIS + + # short sugared syntax: + for my $bar ($::request->layout->get('actionbar')) { + $bar->add( + action => [ + t8('Description'), + call => [ 'kivi.Javascript.function', @arguments ], + accesskey => 'enter', + disabled => $tooltip_with_reason_or_falsish, + only_if => $precomputed_condition, + not_if => $precomputed_condition, + id => 'html-element-id', + ], + combobox => [ + action => [...], + action => [...], + action => [...], + action => [...], + ], + link => [ + t8('Description'), + link => $url, + ], + 'separator', + ); + } + + # full syntax without sugar + for my $bar ($::request->layout->get('actionbar')) { + $bar->add( + (SL::Layout::ActionBar::Action->new( + text => t8('Description'), + params => { + call => [ 'kivi.Javascript.function', @arguments ], + accesskey => 'enter', + disabled => $tooltip_with_reason_or_falsish, + }, + )) x(!!$only_id && !$not_if), + SL::Layout::ActionBar::ComboBox->new( + actions => [ + SL::Layout::ActionBar::Action->new(...), + SL::Layout::ActionBar::Action->new(...), + SL::Layout::ActionBar::Action->new(...), + SL::Layout::ActionBar::Action->new(...), + ], + ), + SL::Layout::ActionBar::Link->new( + text => t8('Description'), + params => { + link => $url, + }, + ), + SL::Layout::ActionBar::Separator->new, + ); + } + =head1 CONCEPT -This is a layout block that does a unified action bar for any controller who +This is a layout block that creates an action bar for any controller who wants to use it. It's designed to be rendered above the content and to be -fixed when scrolling. +fixed when scrolling. It's structured as a container for elements that can be +extended when needed. -While it can be used as a generic widget container, it's designed to be able to -provide commonly used functionality as a short cut. These shortcuts include: +=head1 METHODS =over 4 -=item * +=item * C -Calling a controller with parameters +Will be used during initialization of the layout. You should never have to +instanciate an action bar yourself. Get the current request instances from -=item * + $::request->layout->get('actionbar') -Submitting a form with added parameters +instead. -=item * +=item * C -Arrangement utility +Add new elements to the bar. Can be instances of +L or scalar strings matching the sugar syntax +which is described further down. =back +=head1 SYNTACTIC SUGAR -=head1 METHODS +Instead of passing full objects to L, you can instead pass the arguments +to be used for instantiation to make the code easier to read. The short syntax +looks like this: + + type => [ + localized_description, + param => value, + param => value, + ... + ] + +A string type, followed by the parameters needed for that type. Type may be one of: + +=over 4 + +=item * C + +=item * C + +=item * C + +=item * C + +=back + +C will use no parameters, the other three will expect one arrayref. + +Two additional pseudo parameters are supported for those: =over 4 -=item C +=item * C -to be documented +=item * C =back -=head1 ACCESS FROM CODE +These are meant to reduce enterprise operators (C<()x!!>) when conditionally adding lots +of elements. -This is accessable through +The combobox element is in itself a container and will simply expect the same +syntax in an arrayref. - $::request->layout->get('actionbar') +For the full list of parameters supported by the elements, see L. + + +=head1 GUIDELINES + +The current implementation follows these design guidelines: -=head1 DOM MODEL +=over 4 + +=item * + +Don't put too many elements into the action bar. Group into comboboxes if +possible. Consider seven elements a reasonable limit. + +=item * + +If you've got an update button, put it first and bind the enter accesskey to +it. + +=item * + +Put mutating actions (save, post, delete, check out, ship) before the separator +and non mutating actions (export, search, history, workflow) after the +separator. Combined actions (save and close) still mutate and go before the +separator. + +=item * + +Avoid abusing the actionbar as a secondary menu. As a principle every action +should act upon the current element or topic. -The entire block is rendered into a div with the class 'layout-actionbar'. +=item * + +Hide elements with C if they are known to be useless for the current +topic, but disable when they would be useful in principle but are not +applicable right now. For example C does not make sense in a creating +form, but makes still sense because the element can be deleted later. This +keeps the actionbar stable and reduces surprising elements that only appear in +rare situations. -=head1 ACTION WIDGETS +=item * -Each individual action must be an instance of C. +Always add a tooltip when disabling an action. + +=item * + +Try to always add a default action with accesskey enter. Since the actionbar +lies outside of the main form, the usual submit on enter does not work out of +the box. + +=back + +=head1 DOM MODEL AND IMPLEMENTATION DETAILS + +The entire block is rendered into a div with the class 'layout-actionbar'. Each +action will render itself and will get added to the div. To keep the DOM small +and reduce startup overhead, the presentation is pure CSS and only the sticky +expansion of comboboxes is done with javascript. + +To keep startup times and HTML parsing fast the action data is simply written +into the data elements of the actions and handlers are added in a ready hook. =head1 BUGS none yet. :) +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L, + =head1 AUTHOR Sven Schoeling Es.schoeling@linet-services.deE