Revision 3dc29e42
Von Sven Schöling vor etwa 8 Jahren hinzugefügt
SL/Layout/ActionBar/Action.pm | ||
---|---|---|
use SL::Presenter;
|
||
|
||
use Rose::Object::MakeMethods::Generic (
|
||
'scalar --get_set_init' => [ qw(id) ],
|
||
'scalar --get_set_init' => [ qw(id params text) ],
|
||
);
|
||
|
||
# subclassing interface
|
||
... | ... | |
}
|
||
|
||
sub script {
|
||
die 'needs to be implemented';
|
||
sprintf q|$('#%s').data('action', %s);|, $_[0]->id, JSON->new->allow_blessed->convert_blessed->encode($_[0]->params);
|
||
}
|
||
|
||
|
||
# static constructors
|
||
|
||
sub from_descriptor {
|
||
my ($class, $descriptor) = @_;a
|
||
my ($class, $descriptor) = @_;
|
||
require SL::Layout::ActionBar::Separator;
|
||
|
||
{
|
||
separator => SL::Layout::ActionBar::Separator->new,
|
||
... | ... | |
|
||
if ($params{submit}) {
|
||
require SL::Layout::ActionBar::Submit;
|
||
return SL::Layout::ActionBar::Submit->new(text => $text, %params);
|
||
return SL::Layout::ActionBar::Submit->new(text => $text, params => \%params);
|
||
}
|
||
|
||
if ($params{function}) {
|
||
require SL::Layout::ActionBar::ScriptButton;
|
||
return SL::Layout::ActionBar::ScriptButton->new(text => $text, %params);
|
||
return SL::Layout::ActionBar::ScriptButton->new(text => $text, params => \%params);
|
||
}
|
||
|
||
if ($params{combobox}) {
|
||
... | ... | |
1;
|
||
|
||
__END__
|
||
|
||
=head 1
|
||
|
||
planned options for clickables:
|
||
|
||
- checks => [ ... ] (done)
|
||
|
||
a list of functions that need to return true before submitting
|
||
|
||
- submit => [ form-selector, { params } ] (done)
|
||
|
||
on click submit the form specified by form-selector with the additional params
|
||
|
||
- function => function-name (done)
|
||
|
||
on click call the specified function (is this a special case of checks?)
|
||
|
||
- disabled => true/false (done)
|
||
|
||
TODO:
|
||
|
||
- runtime disable/enable
|
||
|
SL/Layout/ActionBar/ScriptButton.pm | ||
---|---|---|
use strict;
|
||
use parent qw(SL::Layout::ActionBar::Action);
|
||
|
||
use JSON;
|
||
|
||
use Rose::Object::MakeMethods::Generic (
|
||
'scalar --get_set_init' => [ qw(text function) ],
|
||
);
|
||
|
||
sub render {
|
||
$_[0]->p->html_tag('div', $_[0]->text,
|
||
id => $_[0]->id,
|
||
... | ... | |
);
|
||
}
|
||
|
||
sub script {
|
||
# store submit and form and stuff in data attribute
|
||
sprintf q|$('#%s').data('action', %s);|, $_[0]->id, JSON::to_json({
|
||
function => $_[0]->function,
|
||
});
|
||
}
|
||
|
||
1;
|
SL/Layout/ActionBar/Submit.pm | ||
---|---|---|
use strict;
|
||
use parent qw(SL::Layout::ActionBar::Action);
|
||
|
||
use JSON;
|
||
|
||
use Rose::Object::MakeMethods::Generic (
|
||
'scalar --get_set_init' => [ qw(text submit) ],
|
||
);
|
||
|
||
sub render {
|
||
$_[0]->p->html_tag('div', $_[0]->text,
|
||
id => $_[0]->id,
|
||
... | ... | |
);
|
||
}
|
||
|
||
sub script {
|
||
# store submit and form and stuff in data attribute
|
||
sprintf q|$('#%s').data('action', %s);|, $_[0]->id, JSON::to_json({
|
||
submit => $_[0]->submit,
|
||
});
|
||
}
|
||
|
||
1;
|
SL/Layout/Base.pm | ||
---|---|---|
|
||
=head1 BUGS
|
||
|
||
None yet, if you don't count the horrible stylesheet/javascript interface.
|
||
* stylesheet/javascript interface is a horrible mess.
|
||
|
||
* It's currently not possible to do compositor layouts without assupmtions
|
||
about the position of the content. That's because the content will return
|
||
control to the actual controller, so the layouts need to know where to split
|
||
pre- and post-content.
|
||
|
||
=head1 AUTHOR
|
||
|
css/lx-office-erp/main.css | ||
---|---|---|
}
|
||
|
||
div.layout-actionbar-action {
|
||
-webkit-touch-callout: none; /* iOS Safari */
|
||
-webkit-user-select: none; /* Chrome/Safari/Opera */
|
||
-khtml-user-select: none; /* Konqueror */
|
||
-moz-user-select: none; /* Firefox */
|
||
-ms-user-select: none; /* Internet Explorer/Edge */
|
||
user-select: none; /* don't select text on double click */
|
||
transition: background-color 0s;
|
||
-moz-transition: background-color 0s;
|
||
-webkit-transition: background-color 0s;
|
||
... | ... | |
-moz-border-radius: 2px;
|
||
border-radius: 2px;
|
||
}
|
||
|
||
div.layout-actionbar div.layout-actionbar-action-disabled,
|
||
div.layout-actionbar div.layout-actionbar-action-disabled:hover {
|
||
color: gray;
|
||
background-color: whitesmoke;
|
||
border-color: lightgray;
|
||
}
|
js/kivi.ActionBar.js | ||
---|---|---|
|
||
k.ActionBarAction = function(e) {
|
||
var data = $(e).data('action');
|
||
|
||
if (data.disabled)
|
||
$(e).addClass('layout-actionbar-action-disabled');
|
||
// dispatch as needed
|
||
if (data.submit) {
|
||
var form = data.submit[0];
|
||
var params = data.submit[1];
|
||
$(e).click(function(event) {
|
||
var $hidden, key;
|
||
var $hidden, key, func;
|
||
if (data.disabled) return;
|
||
if (data.confirm && !confirm(data.confirm)) return;
|
||
if (data.checks) {
|
||
for (var check in data.check) {
|
||
func = kivi.get_function_by_name(check);
|
||
if (!func()) return;
|
||
}
|
||
}
|
||
for (key in params) {
|
||
$hidden = $('<input type=hidden>')
|
||
$hidden.attr('name', key)
|
||
... | ... | |
// TODO: what to do with templated calls
|
||
console.log(data.function)
|
||
$(e).click(function(event) {
|
||
var func = kivi.get_function_by_name(data.function[0]);
|
||
var func;
|
||
if (data.disabled) return;
|
||
if (data.confirm && !confirm(data.confirm)) return;
|
||
if (data.checks) {
|
||
for (var check in data.check) {
|
||
func = kivi.get_function_by_name(check);
|
||
if (!func()) return;
|
||
}
|
||
}
|
||
func = kivi.get_function_by_name(data.function[0]);
|
||
func.apply(document, data.function.slice(1))
|
||
});
|
||
}
|
Auch abrufbar als: Unified diff
ActionBar: calling conventions geändert, +check/disabled/confirm