Revision e0a3b19e
Von Sven Schöling vor fast 8 Jahren hinzugefügt
SL/Layout/ActionBar.pm | ||
---|---|---|
3 | 3 |
use strict; |
4 | 4 |
use parent qw(SL::Layout::Base); |
5 | 5 |
|
6 |
use SL::Layout::ActionBar::Action; |
|
7 |
|
|
6 | 8 |
use constant HTML_CLASS => 'layout-actionbar'; |
7 | 9 |
|
8 | 10 |
use Rose::Object::MakeMethods::Generic ( |
... | ... | |
13 | 15 |
###### Layout overrides |
14 | 16 |
|
15 | 17 |
sub pre_content { |
16 |
$::request->presenter->html_tag('div', '', class => HTML_CLASS); |
|
18 |
my ($self) = @_; |
|
19 |
|
|
20 |
my $content = join '', map { $_->render } @{ $self->actions }; |
|
21 |
$::request->presenter->html_tag('div', $content, class => HTML_CLASS); |
|
17 | 22 |
} |
18 | 23 |
|
19 |
sub inline_javascript {
|
|
20 |
# data for bar
|
|
24 |
sub javascripts_inline {
|
|
25 |
join '', map { $_->script } @{ $_[0]->actions };
|
|
21 | 26 |
} |
22 | 27 |
|
23 | 28 |
sub javascripts { |
24 |
|
|
29 |
'kivi.ActionBar.js' |
|
25 | 30 |
} |
26 | 31 |
|
27 | 32 |
###### interface |
28 | 33 |
|
29 | 34 |
sub add_actions { |
30 | 35 |
my ($self, @actions) = @_; |
31 |
push @{ $self->actions }, @actions; |
|
36 |
push @{ $self->actions }, map { |
|
37 |
!ref $_ ? SL::Layout::ActionBar::Action->from_descriptor($_) |
|
38 |
: ref $_ && 'ARRAY' eq ref $_ ? SL::Layout::ActionBar::Action->simple($_) |
|
39 |
: ref $_ && $_->isa('SL::Layout::Action') ? $_ |
|
40 |
: do { die 'invalid action' }; |
|
41 |
} @actions; |
|
32 | 42 |
} |
33 | 43 |
|
34 | 44 |
sub init_actions { |
... | ... | |
93 | 103 |
|
94 | 104 |
This is accessable through |
95 | 105 |
|
96 |
$::request->layout->actionbar
|
|
106 |
$::request->layout->get('actionbar')
|
|
97 | 107 |
|
98 | 108 |
=head1 DOM MODEL |
99 | 109 |
|
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) ], |
|
10 |
); |
|
11 |
|
|
12 |
# subclassing interface |
|
13 |
|
|
14 |
sub render { |
|
15 |
die 'needs to be implemented'; |
|
16 |
} |
|
17 |
|
|
18 |
sub script { |
|
19 |
die 'needs to be implemented'; |
|
20 |
} |
|
21 |
|
|
22 |
|
|
23 |
# static constructors |
|
24 |
|
|
25 |
sub from_descriptor { |
|
26 |
my ($class, $descriptor) = @_;a |
|
27 |
|
|
28 |
{ |
|
29 |
separator => SL::Layout::ActionBar::Separator->new, |
|
30 |
} or die 'unknown descriptor'; |
|
31 |
} |
|
32 |
|
|
33 |
# TODO: this necessary? |
|
34 |
sub simple { |
|
35 |
my ($class, $data) = @_; |
|
36 |
|
|
37 |
my ($text, %params) = @$data; |
|
38 |
|
|
39 |
if ($params{submit}) { |
|
40 |
require SL::Layout::ActionBar::Submit; |
|
41 |
return SL::Layout::ActionBar::Submit->new(text => $text, %params); |
|
42 |
} |
|
43 |
|
|
44 |
if ($params{function}) { |
|
45 |
require SL::Layout::ActionBar::ScriptButton; |
|
46 |
return SL::Layout::ActionBar::ScriptButton->new(text => $text, %params); |
|
47 |
} |
|
48 |
|
|
49 |
if ($params{combobox}) { |
|
50 |
|
|
51 |
} |
|
52 |
} |
|
53 |
|
|
54 |
# shortcut for presenter |
|
55 |
|
|
56 |
sub p { |
|
57 |
SL::Presenter->get |
|
58 |
} |
|
59 |
|
|
60 |
# unique id to tie div and javascript together |
|
61 |
sub init_id { |
|
62 |
$_[0]->p->name_to_id('action[]') |
|
63 |
} |
|
64 |
|
|
65 |
|
|
66 |
1; |
|
67 |
|
|
68 |
__END__ |
SL/Layout/ActionBar/ScriptButton.pm | ||
---|---|---|
1 |
package SL::Layout::ActionBar::ScriptButton; |
|
2 |
|
|
3 |
use strict; |
|
4 |
use parent qw(SL::Layout::ActionBar::Action); |
|
5 |
|
|
6 |
use JSON; |
|
7 |
|
|
8 |
use Rose::Object::MakeMethods::Generic ( |
|
9 |
'scalar --get_set_init' => [ qw(text function) ], |
|
10 |
); |
|
11 |
|
|
12 |
sub render { |
|
13 |
$_[0]->p->html_tag('div', $_[0]->text, |
|
14 |
id => $_[0]->id, |
|
15 |
class => 'layout-actionbar-action layout-actionbar-scriptbutton', |
|
16 |
); |
|
17 |
} |
|
18 |
|
|
19 |
sub script { |
|
20 |
# store submit and form and stuff in data attribute |
|
21 |
sprintf q|$('#%s').data('action', %s);|, $_[0]->id, JSON::to_json({ |
|
22 |
function => $_[0]->function, |
|
23 |
}); |
|
24 |
} |
|
25 |
|
|
26 |
1; |
SL/Layout/ActionBar/Separator.pm | ||
---|---|---|
1 |
package SL::Layout::ActionBar::Separator; |
|
2 |
|
|
3 |
use strict; |
|
4 |
use parent qw(SL::Layout::ActionBar::Action); |
|
5 |
|
|
6 |
sub render { |
|
7 |
$_[0]->p->html_tag('div', '', class => 'layout-actionbar-separator'); |
|
8 |
} |
|
9 |
|
|
10 |
1; |
SL/Layout/ActionBar/Submit.pm | ||
---|---|---|
1 |
package SL::Layout::ActionBar::Submit; |
|
2 |
|
|
3 |
use strict; |
|
4 |
use parent qw(SL::Layout::ActionBar::Action); |
|
5 |
|
|
6 |
use JSON; |
|
7 |
|
|
8 |
use Rose::Object::MakeMethods::Generic ( |
|
9 |
'scalar --get_set_init' => [ qw(text submit) ], |
|
10 |
); |
|
11 |
|
|
12 |
sub render { |
|
13 |
$_[0]->p->html_tag('div', $_[0]->text, |
|
14 |
id => $_[0]->id, |
|
15 |
class => 'layout-actionbar-action layout-actionbar-submit', |
|
16 |
); |
|
17 |
} |
|
18 |
|
|
19 |
sub script { |
|
20 |
# store submit and form and stuff in data attribute |
|
21 |
sprintf q|$('#%s').data('action', %s);|, $_[0]->id, JSON::to_json({ |
|
22 |
submit => $_[0]->submit, |
|
23 |
}); |
|
24 |
} |
|
25 |
|
|
26 |
1; |
SL/Layout/Base.pm | ||
---|---|---|
7 | 7 |
use Time::HiRes qw(); |
8 | 8 |
|
9 | 9 |
use Rose::Object::MakeMethods::Generic ( |
10 |
'scalar --get_set_init' => [ qw(menu auto_reload_resources_param) ], |
|
10 |
'scalar --get_set_init' => [ qw(menu auto_reload_resources_param sub_layouts_by_name) ],
|
|
11 | 11 |
'scalar' => qw(focus), |
12 | 12 |
'array' => [ |
13 | 13 |
'add_stylesheets_inline' => { interface => 'add', hash_key => 'stylesheets_inline' }, |
... | ... | |
32 | 32 |
SL::Menu->new('user'); |
33 | 33 |
} |
34 | 34 |
|
35 |
sub init_sublayouts_by_name { |
|
36 |
{} |
|
37 |
} |
|
38 |
|
|
39 |
sub get { |
|
40 |
$_[0]->sub_layouts; |
|
41 |
$_[0]->sub_layouts_by_name->{$_[1]} |
|
42 |
} |
|
43 |
|
|
35 | 44 |
sub init_auto_reload_resources_param { |
36 | 45 |
return '' unless $::lx_office_conf{debug}->{auto_reload_resources}; |
37 | 46 |
return sprintf('?rand=%d-%d-%d', Time::HiRes::gettimeofday(), int(rand 1000000000000)); |
... | ... | |
69 | 78 |
|
70 | 79 |
sub init_sub_layouts { [] } |
71 | 80 |
|
81 |
sub init_sub_layouts_by_name { +{} } |
|
82 |
|
|
72 | 83 |
|
73 | 84 |
######################################### |
74 | 85 |
# Interface |
SL/Layout/Classic.pm | ||
---|---|---|
7 | 7 |
use SL::Layout::MenuLeft; |
8 | 8 |
use SL::Layout::None; |
9 | 9 |
use SL::Layout::Split; |
10 |
use SL::Layout::ActionBar; |
|
10 | 11 |
use SL::Layout::Content; |
11 | 12 |
|
12 | 13 |
sub init_sub_layouts { |
14 |
$_[0]->sub_layouts_by_name->{actionbar} = SL::Layout::ActionBar->new; |
|
15 |
|
|
13 | 16 |
[ |
14 | 17 |
SL::Layout::None->new, |
15 | 18 |
SL::Layout::Top->new, |
16 | 19 |
SL::Layout::Split->new( |
17 | 20 |
left => [ SL::Layout::MenuLeft->new ], |
18 |
right => [ SL::Layout::Content->new ], |
|
21 |
right => [ $_[0]->sub_layouts_by_name->{actionbar}, SL::Layout::Content->new ],
|
|
19 | 22 |
) |
20 | 23 |
] |
21 | 24 |
} |
SL/Layout/Split.pm | ||
---|---|---|
18 | 18 |
my $left = join '', map { $_->pre_content } @{ $_[0]->left || [] }; |
19 | 19 |
my $right = join '', map { $_->pre_content } @{ $_[0]->right || [] }; |
20 | 20 |
|
21 |
SL::Presenter->get->html_tag('div', $left, class => 't-layout-left')
|
|
22 |
.'<div class="t-layout-right html-menu">' . $right;
|
|
21 |
SL::Presenter->get->html_tag('div', $left, class => 'layout-split-left')
|
|
22 |
.'<div class="layout-split-right">' . $right;
|
|
23 | 23 |
} |
24 | 24 |
|
25 | 25 |
sub post_content { |
css/lx-office-erp/main.css | ||
---|---|---|
534 | 534 |
#bank_transactions_proposals span.invoice_number_highlight { |
535 | 535 |
background-color: #006400; |
536 | 536 |
color: #FFFFFF; |
537 |
|
|
538 |
} |
|
539 |
|
|
540 |
/* actionbar styling */ |
|
541 |
div.layout-actionbar { |
|
542 |
background-color: whitesmoke; |
|
543 |
} |
|
544 |
|
|
545 |
div.layout-actionbar-action { |
|
546 |
transition: background-color 0s; |
|
547 |
-moz-transition: background-color 0s; |
|
548 |
-webkit-transition: background-color 0s; |
|
549 |
} |
|
550 |
|
|
551 |
div.layout-actionbar div.layout-actionbar-submit, |
|
552 |
div.layout-actionbar div.layout-actionbar-scriptbutton, |
|
553 |
div.layout-actionbar div.layout-actionbar-submit:focus, |
|
554 |
div.layout-actionbar div.layout-actionbar-scriptbutton:focus { |
|
555 |
display: inline-block; |
|
556 |
box-sizing: border-box; |
|
557 |
border: 1px; |
|
558 |
border-color: darkgray; |
|
559 |
border-style: solid; |
|
560 |
padding: 4px 4px; |
|
561 |
-webkit-border-radius: 2px; |
|
562 |
-moz-border-radius: 2px; |
|
563 |
border-radius: 2px; |
|
564 |
background-color: whitesmoke; |
|
565 |
cursor:default; |
|
566 |
} |
|
567 |
|
|
568 |
div.layout-actionbar div.layout-actionbar-submit:hover, |
|
569 |
div.layout-actionbar div.layout-actionbar-scriptbutton:hover { |
|
570 |
border: 1px; |
|
571 |
background-color: lightgray; |
|
572 |
border-color: gray; |
|
573 |
border-style: solid; |
|
574 |
-webkit-border-radius: 2px; |
|
575 |
-moz-border-radius: 2px; |
|
576 |
border-radius: 2px; |
|
537 | 577 |
} |
js/kivi.ActionBar.js | ||
---|---|---|
1 |
namespace('kivi', function(k){ |
|
2 |
'use strict'; |
|
3 |
|
|
4 |
k.ActionBarAction = function(e) { |
|
5 |
var data = $(e).data('action'); |
|
6 |
// dispatch as needed |
|
7 |
if (data.submit) { |
|
8 |
var form = data.submit[0]; |
|
9 |
var params = data.submit[1]; |
|
10 |
$(e).click(function(event) { |
|
11 |
var $hidden, key; |
|
12 |
for (key in params) { |
|
13 |
$hidden = $('<input type=hidden>') |
|
14 |
$hidden.attr('name', key) |
|
15 |
$hidden.attr('value', params[key]) |
|
16 |
$(form).append($hidden) |
|
17 |
} |
|
18 |
$(form).submit() |
|
19 |
}) |
|
20 |
} else if (data.function) { |
|
21 |
// TODO: what to do with templated calls |
|
22 |
console.log(data.function) |
|
23 |
$(e).click(function(event) { |
|
24 |
var func = kivi.get_function_by_name(data.function[0]); |
|
25 |
func.apply(document, data.function.slice(1)) |
|
26 |
}); |
|
27 |
} |
|
28 |
} |
|
29 |
}); |
|
30 |
|
|
31 |
$(function(){ |
|
32 |
$('div.layout-actionbar .layout-actionbar-action').each(function(_, e) { |
|
33 |
kivi.ActionBarAction(e); |
|
34 |
}); |
|
35 |
}); |
Auch abrufbar als: Unified diff
ActionBar: Funktionierender Prototyp mit submit und actionbutton