Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision e0a3b19e

Von Sven Schöling vor fast 8 Jahren hinzugefügt

  • ID e0a3b19e35aed6f3f8ba84e25381a5d0e6ca61f4
  • Vorgänger ccf94c5d
  • Nachfolger 11dd62da

ActionBar: Funktionierender Prototyp mit submit und actionbutton

Unterschiede anzeigen:

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