Projekt

Allgemein

Profil

Herunterladen (25,3 KB) Statistiken
| Zweig: | Markierung: | Revision:
8177c150 Moritz Bunkus
package SL::Template::Plugin::L;

use base qw( Template::Plugin );
use Template::Plugin;
0bf192cd Moritz Bunkus
use Data::Dumper;
e3f1b7c3 Sven Schöling
use List::MoreUtils qw(apply);
7714d4d0 Sven Schöling
use List::Util qw(max);
b9894fd0 Sven Schöling
use Scalar::Util qw(blessed);
8177c150 Moritz Bunkus
d4458803 Moritz Bunkus
use SL::Presenter;
5e9aaf1c Moritz Bunkus
use SL::Util qw(_hashify);
d4458803 Moritz Bunkus
8177c150 Moritz Bunkus
use strict;

22ae0bf0 Sven Schöling
{ # This will give you an id for identifying html tags and such.
# It's guaranteed to be unique unless you exceed 10 mio calls per request.
# Do not use these id's to store information across requests.
my $_id_sequence = int rand 1e7;
sub _tag_id {
ca9e9f88 Sven Schöling
return "id_" . ( $_id_sequence = ($_id_sequence + 1) % 1e7 );
22ae0bf0 Sven Schöling
}
}

47978b5b Moritz Bunkus
sub _H {
my $string = shift;
return $::locale->quote_special_chars('HTML', $string);
}

9796c91f Moritz Bunkus
sub _J {
51d0274d Thomas Heck
my $string = shift;
$string =~ s/(\"|\'|\\)/\\$1/g;
9796c91f Moritz Bunkus
return $string;
}

8177c150 Moritz Bunkus
sub new {
e5205a23 Moritz Bunkus
my ($class, $context, @args) = @_;
8177c150 Moritz Bunkus
e5205a23 Moritz Bunkus
return bless {
CONTEXT => $context,
}, $class;
}

sub _context {
die 'not an accessor' if @_ > 1;
return $_[0]->{CONTEXT};
8177c150 Moritz Bunkus
}

4f15b8f0 Moritz Bunkus
sub _call_presenter {
d093f01c Moritz Bunkus
my ($method, $self, @args) = @_;
4f15b8f0 Moritz Bunkus
d093f01c Moritz Bunkus
my $presenter = $::request->presenter;
4f15b8f0 Moritz Bunkus
d093f01c Moritz Bunkus
if (!$presenter->can($method)) {
$::lxdebug->message(LXDebug::WARN(), "SL::Presenter has no method named '$method'!");
return '';
}
4f15b8f0 Moritz Bunkus
splice @args, -1, 1, %{ $args[-1] } if @args && (ref($args[-1]) eq 'HASH');

$presenter->$method(@args);
}

d093f01c Moritz Bunkus
sub name_to_id { return _call_presenter('name_to_id', @_); }
sub html_tag { return _call_presenter('html_tag', @_); }
sub select_tag { return _call_presenter('select_tag', @_); }
sub input_tag { return _call_presenter('input_tag', @_); }
sub truncate { return _call_presenter('truncate', @_); }
sub simple_format { return _call_presenter('simple_format', @_); }
9aaadfdc Sven Schöling
sub part_picker { return _call_presenter('part_picker', @_); }
8177c150 Moritz Bunkus
da2fecb4 Moritz Bunkus
sub _set_id_attribute {
my ($attributes, $name) = @_;
SL::Presenter::Tag::_set_id_attribute($attributes, $name);
}

6c558186 Sven Schöling
sub img_tag {
5e9aaf1c Moritz Bunkus
my ($self, %options) = _hashify(1, @_);
6c558186 Sven Schöling
$options{alt} ||= '';

return $self->html_tag('img', undef, %options);
}

11e4b8f3 Moritz Bunkus
sub textarea_tag {
5e9aaf1c Moritz Bunkus
my ($self, $name, $content, %attributes) = _hashify(3, @_);
11e4b8f3 Moritz Bunkus
da2fecb4 Moritz Bunkus
_set_id_attribute(\%attributes, $name);
993ce983 Sven Schöling
$attributes{rows} *= 1; # required by standard
$attributes{cols} *= 1; # required by standard
1a8f5fe0 Moritz Bunkus
$content = $content ? _H($content) : '';
11e4b8f3 Moritz Bunkus
return $self->html_tag('textarea', $content, %attributes, name => $name);
}

3cc77e53 Moritz Bunkus
sub checkbox_tag {
5e9aaf1c Moritz Bunkus
my ($self, $name, %attributes) = _hashify(2, @_);
3cc77e53 Moritz Bunkus
da2fecb4 Moritz Bunkus
_set_id_attribute(\%attributes, $name);
3cc77e53 Moritz Bunkus
$attributes{value} = 1 unless defined $attributes{value};
my $label = delete $attributes{label};
4edfabd2 Sven Schöling
my $checkall = delete $attributes{checkall};
fb0e4cdd Geoffrey Richardson
my $for_submit = delete $attributes{for_submit};
3cc77e53 Moritz Bunkus
if ($attributes{checked}) {
$attributes{checked} = 'checked';
} else {
delete $attributes{checked};
}
8177c150 Moritz Bunkus
fb0e4cdd Geoffrey Richardson
my $code = '';
$code .= $self->hidden_tag($name, 0, %attributes, id => $attributes{id} . '_hidden') if $for_submit;
$code .= $self->html_tag('input', undef, %attributes, name => $name, type => 'checkbox');
3cc77e53 Moritz Bunkus
$code .= $self->html_tag('label', $label, for => $attributes{id}) if $label;
4edfabd2 Sven Schöling
$code .= $self->javascript(qq|\$('#$attributes{id}').checkall('$checkall');|) if $checkall;
8177c150 Moritz Bunkus
3cc77e53 Moritz Bunkus
return $code;
}

11e4b8f3 Moritz Bunkus
sub radio_button_tag {
5e9aaf1c Moritz Bunkus
my ($self, $name, %attributes) = _hashify(2, @_);
11e4b8f3 Moritz Bunkus
da2fecb4 Moritz Bunkus
_set_id_attribute(\%attributes, $name);
5324155e Moritz Bunkus
$attributes{value} = 1 unless exists $attributes{value};
11e4b8f3 Moritz Bunkus
my $label = delete $attributes{label};

if ($attributes{checked}) {
$attributes{checked} = 'checked';
} else {
delete $attributes{checked};
}

my $code = $self->html_tag('input', undef, %attributes, name => $name, type => 'radio');
$code .= $self->html_tag('label', $label, for => $attributes{id}) if $label;

return $code;
}

9f75fa25 Sven Schöling
sub hidden_tag {
5e9aaf1c Moritz Bunkus
my ($self, $name, $value, %attributes) = _hashify(3, @_);
return $self->input_tag($name, $value, %attributes, type => 'hidden');
9f75fa25 Sven Schöling
}

e5205a23 Moritz Bunkus
sub div_tag {
my ($self, $content, @slurp) = @_;
return $self->html_tag('div', $content, @slurp);
}

sub ul_tag {
my ($self, $content, @slurp) = @_;
return $self->html_tag('ul', $content, @slurp);
}

sub li_tag {
my ($self, $content, @slurp) = @_;
return $self->html_tag('li', $content, @slurp);
}

sub link {
5e9aaf1c Moritz Bunkus
my ($self, $href, $content, %params) = _hashify(3, @_);
e5205a23 Moritz Bunkus
$href ||= '#';

return $self->html_tag('a', $content, %params, href => $href);
}

9f75fa25 Sven Schöling
sub submit_tag {
5e9aaf1c Moritz Bunkus
my ($self, $name, $value, %attributes) = _hashify(3, @_);
a30ad33e Moritz Bunkus
f2b76d67 Thomas Heck
if ( $attributes{confirm} ) {
$attributes{onclick} = 'return confirm("'. _J(delete($attributes{confirm})) .'");';
}
a30ad33e Moritz Bunkus
return $self->input_tag($name, $value, %attributes, type => 'submit', class => 'submit');
9f75fa25 Sven Schöling
}

7714d4d0 Sven Schöling
sub button_tag {
5e9aaf1c Moritz Bunkus
my ($self, $onclick, $value, %attributes) = _hashify(3, @_);
7714d4d0 Sven Schöling
da2fecb4 Moritz Bunkus
_set_id_attribute(\%attributes, $attributes{name}) if $attributes{name};
bd1e1e7d Sven Schöling
$attributes{type} ||= 'button';

341fbe8b Moritz Bunkus
$onclick = 'if (!confirm("'. _J(delete($attributes{confirm})) .'")) return false; ' . $onclick if $attributes{confirm};

bd1e1e7d Sven Schöling
return $self->html_tag('input', undef, %attributes, value => $value, onclick => $onclick);
7714d4d0 Sven Schöling
}

86a76ea5 Moritz Bunkus
sub ajax_submit_tag {
my ($self, $url, $form_selector, $text, @slurp) = @_;

$url = _J($url);
$form_selector = _J($form_selector);
17f39e02 Moritz Bunkus
my $onclick = qq|kivi.submit_ajax_form('${url}', '${form_selector}')|;
86a76ea5 Moritz Bunkus
return $self->button_tag($onclick, $text, @slurp);
}

1ec0f541 Moritz Bunkus
sub yes_no_tag {
5e9aaf1c Moritz Bunkus
my ($self, $name, $value, %attributes) = _hashify(3, @_);
1ec0f541 Moritz Bunkus
58966151 Thomas Heck
return $self->select_tag($name, [ [ 1 => $::locale->text('Yes') ], [ 0 => $::locale->text('No') ] ], default => $value ? 1 : 0, %attributes);
1ec0f541 Moritz Bunkus
}

22ae0bf0 Sven Schöling
sub javascript {
my ($self, $data) = @_;
return $self->html_tag('script', $data, type => 'text/javascript');
}

6df470c3 Moritz Bunkus
sub stylesheet_tag {
my $self = shift;
my $code = '';

foreach my $file (@_) {
$file .= '.css' unless $file =~ m/\.css$/;
$file = "css/${file}" unless $file =~ m|/|;

$code .= qq|<link rel="stylesheet" href="${file}" type="text/css" media="screen" />|;
}

return $code;
}

a56327d7 Moritz Bunkus
my $date_tag_id_idx = 0;
22ae0bf0 Sven Schöling
sub date_tag {
5e9aaf1c Moritz Bunkus
my ($self, $name, $value, %params) = _hashify(3, @_);
a56327d7 Moritz Bunkus
da2fecb4 Moritz Bunkus
_set_id_attribute(\%params, $name);
a56327d7 Moritz Bunkus
my @onchange = $params{onchange} ? (onChange => delete $params{onchange}) : ();
005e30ca Moritz Bunkus
my @classes = $params{no_cal} || $params{readonly} ? () : ('datepicker');
push @classes, delete($params{class}) if $params{class};
my %class = @classes ? (class => join(' ', @classes)) : ();
a56327d7 Moritz Bunkus
3ac83c61 Moritz Bunkus
$::request->presenter->need_reinit_widgets($params{id});

a56327d7 Moritz Bunkus
return $self->input_tag(
$name, blessed($value) ? $value->to_lxoffice : $value,
22ae0bf0 Sven Schöling
size => 11,
a56327d7 Moritz Bunkus
onblur => "check_right_date_format(this);",
22ae0bf0 Sven Schöling
%params,
005e30ca Moritz Bunkus
%class, @onchange,
a56327d7 Moritz Bunkus
);
d6bb5c26 Moritz Bunkus
}
62ba378c Moritz Bunkus
cb3a2467 Sven Schöling
sub customer_picker {
my ($self, $name, $value, %params) = @_;
my $name_e = _H($name);

1cd0721d Sven Schöling
$::request->{layout}->add_javascripts('autocomplete_customer.js');

$self->hidden_tag($name, (ref $value && $value->can('id') ? $value->id : ''), class => 'customer_autocomplete') .
a31ce8af Sven Schöling
$self->input_tag('', (ref $value && $value->can('name')) ? $value->name : '', id => $self->name_to_id("$name_e\_name"), %params);
cb3a2467 Sven Schöling
}

eb518737 Bernd Bleßmann
# simple version with select_tag
sub vendor_selector {
my ($self, $name, $value, %params) = @_;

my $actual_vendor_id = (defined $::form->{"$name"})? ((ref $::form->{"$name"}) ? $::form->{"$name"}->id : $::form->{"$name"}) :
(ref $value && $value->can('id')) ? $value->id : '';
e8a2b965 Moritz Bunkus
58966151 Thomas Heck
return $self->select_tag($name, SL::DB::Manager::Vendor->get_all(),
default => $actual_vendor_id,
title_sub => sub { $_[0]->vendornumber . " : " . $_[0]->name },
'with_empty' => 1,
%params);
eb518737 Bernd Bleßmann
}


# simple version with select_tag
sub part_selector {
my ($self, $name, $value, %params) = @_;

my $actual_part_id = (defined $::form->{"$name"})? ((ref $::form->{"$name"})? $::form->{"$name"}->id : $::form->{"$name"}) :
(ref $value && $value->can('id')) ? $value->id : '';
e8a2b965 Moritz Bunkus
58966151 Thomas Heck
return $self->select_tag($name, SL::DB::Manager::Part->get_all(),
default => $actual_part_id,
title_sub => sub { $_[0]->partnumber . " : " . $_[0]->description },
with_empty => 1,
%params);
eb518737 Bernd Bleßmann
}


62ba378c Moritz Bunkus
sub javascript_tag {
my $self = shift;
my $code = '';

foreach my $file (@_) {
$file .= '.js' unless $file =~ m/\.js$/;
$file = "js/${file}" unless $file =~ m|/|;

$code .= qq|<script type="text/javascript" src="${file}"></script>|;
}

return $code;
22ae0bf0 Sven Schöling
}

e5205a23 Moritz Bunkus
sub tabbed {
5e9aaf1c Moritz Bunkus
my ($self, $tabs, %params) = _hashify(2, @_);
f5db53cd Sven Schöling
my $id = $params{id} || 'tab_' . _tag_id();
e5205a23 Moritz Bunkus
$params{selected} *= 1;

die 'L.tabbed needs an arrayred of tabs for first argument'
unless ref $tabs eq 'ARRAY';

my (@header, @blocks);
for my $i (0..$#$tabs) {
my $tab = $tabs->[$i];

next if $tab eq '';

5f68c975 Moritz Bunkus
my $tab_id = "__tab_id_$i";
push @header, $self->li_tag($self->link('#' . $tab_id, $tab->{name}));
push @blocks, $self->div_tag($tab->{data}, id => $tab_id);
e5205a23 Moritz Bunkus
}

return '' unless @header;
5f68c975 Moritz Bunkus
my $ul = $self->ul_tag(join('', @header), id => $id);
return $self->div_tag(join('', $ul, @blocks), class => 'tabwidget');
e5205a23 Moritz Bunkus
}

sub tab {
5e9aaf1c Moritz Bunkus
my ($self, $name, $src, %params) = _hashify(3, @_);
e5205a23 Moritz Bunkus
$params{method} ||= 'process';

return () if defined $params{if} && !$params{if};

my $data;
if ($params{method} eq 'raw') {
$data = $src;
} elsif ($params{method} eq 'process') {
$data = $self->_context->process($src, %{ $params{args} || {} });
} else {
die "unknown tag method '$params{method}'";
}

return () unless $data;

return +{ name => $name, data => $data };
}

7714d4d0 Sven Schöling
sub areainput_tag {
5e9aaf1c Moritz Bunkus
my ($self, $name, $value, %attributes) = _hashify(3, @_);
7714d4d0 Sven Schöling
796598ed Sven Schöling
my ($rows, $cols);
7714d4d0 Sven Schöling
my $min = delete $attributes{min_rows} || 1;

796598ed Sven Schöling
if (exists $attributes{cols}) {
$cols = delete $attributes{cols};
$rows = $::form->numtextrows($value, $cols);
} else {
$rows = delete $attributes{rows} || 1;
}

7714d4d0 Sven Schöling
return $rows > 1
796598ed Sven Schöling
? $self->textarea_tag($name, $value, %attributes, rows => max($rows, $min), ($cols ? (cols => $cols) : ()))
: $self->input_tag($name, $value, %attributes, ($cols ? (size => $cols) : ()));
7714d4d0 Sven Schöling
}

04854ac2 Moritz Bunkus
sub multiselect2side {
5e9aaf1c Moritz Bunkus
my ($self, $id, %params) = _hashify(2, @_);
04854ac2 Moritz Bunkus
$params{labelsx} = "\"" . _J($params{labelsx} || $::locale->text('Available')) . "\"";
$params{labeldx} = "\"" . _J($params{labeldx} || $::locale->text('Selected')) . "\"";
$params{moveOptions} = 'false';

my $vars = join(', ', map { "${_}: " . $params{$_} } keys %params);
my $code = <<EOCODE;
<script type="text/javascript">
\$().ready(function() {
\$('#${id}').multiselect2side({ ${vars} });
});
</script>
EOCODE

return $code;
}

b7383969 Moritz Bunkus
sub sortable_element {
5e9aaf1c Moritz Bunkus
my ($self, $selector, %params) = _hashify(2, @_);
b7383969 Moritz Bunkus
1b522616 Moritz Bunkus
my %attributes = ( distance => 5,
helper => <<'JAVASCRIPT' );
b7383969 Moritz Bunkus
function(event, ui) {
ui.children().each(function() {
1b522616 Moritz Bunkus
$(this).width($(this).width());
b7383969 Moritz Bunkus
});
return ui;
}
JAVASCRIPT

3c0769d8 Moritz Bunkus
my $stop_event = '';

b7383969 Moritz Bunkus
if ($params{url} && $params{with}) {
my $as = $params{as} || $params{with};
my $filter = ".filter(function(idx) { return this.substr(0, " . length($params{with}) . ") == '$params{with}'; })";
$filter .= ".map(function(idx, str) { return str.replace('$params{with}_', ''); })";

cb604b36 Moritz Bunkus
my $params_js = $params{params} ? qq| + ($params{params})| : '';

3c0769d8 Moritz Bunkus
$stop_event = <<JAVASCRIPT;
cb604b36 Moritz Bunkus
\$.post('$params{url}'${params_js}, { '${as}[]': \$(\$('${selector}').sortable('toArray'))${filter}.toArray() });
3c0769d8 Moritz Bunkus
JAVASCRIPT
}

if (!$params{dont_recolor}) {
$stop_event .= <<JAVASCRIPT;
\$('${selector}>*:odd').removeClass('listrow1').removeClass('listrow0').addClass('listrow0');
\$('${selector}>*:even').removeClass('listrow1').removeClass('listrow0').addClass('listrow1');
JAVASCRIPT
}

if ($stop_event) {
b7383969 Moritz Bunkus
$attributes{stop} = <<JAVASCRIPT;
function(event, ui) {
3c0769d8 Moritz Bunkus
${stop_event}
b7383969 Moritz Bunkus
return ui;
}
JAVASCRIPT
}

7328cbd6 Moritz Bunkus
$params{handle} = '.dragdrop' unless exists $params{handle};
1b522616 Moritz Bunkus
$attributes{handle} = "'$params{handle}'" if $params{handle};

b7383969 Moritz Bunkus
my $attr_str = join(', ', map { "${_}: $attributes{$_}" } keys %attributes);

my $code = <<JAVASCRIPT;
<script type="text/javascript">
\$(function() {
1b522616 Moritz Bunkus
\$( "${selector}" ).sortable({ ${attr_str} })
b7383969 Moritz Bunkus
});
</script>
JAVASCRIPT

return $code;
}

f4f55336 Sven Schöling
sub dump {
my $self = shift;
return '<pre>' . Data::Dumper::Dumper(@_) . '</pre>';
}

9deadd1d Moritz Bunkus
sub sortable_table_header {
5e9aaf1c Moritz Bunkus
my ($self, $by, %params) = _hashify(2, @_);
9deadd1d Moritz Bunkus
my $controller = $self->{CONTEXT}->stash->get('SELF');
783342e0 Sven Schöling
my $models = $params{models} || $self->{CONTEXT}->stash->get('MODELS');
my $sort_spec = $models->get_sort_spec;
9deadd1d Moritz Bunkus
my $by_spec = $sort_spec->{$by};
783342e0 Sven Schöling
my %current_sort_params = $models->get_current_sort_params;
9deadd1d Moritz Bunkus
my ($image, $new_dir) = ('', $current_sort_params{dir});
1260ff14 Moritz Bunkus
my $title = delete($params{title}) || $::locale->text($by_spec->{title});
9deadd1d Moritz Bunkus
783342e0 Sven Schöling
if ($current_sort_params{sort_by} eq $by) {
my $current_dir = $current_sort_params{sort_dir} ? 'up' : 'down';
9deadd1d Moritz Bunkus
$image = '<img border="0" src="image/' . $current_dir . '.png">';
783342e0 Sven Schöling
$new_dir = 1 - ($current_sort_params{sort_dir} || 0);
9deadd1d Moritz Bunkus
}

783342e0 Sven Schöling
$params{ $models->sorted->form_params->[0] } = $by;
$params{ $models->sorted->form_params->[1] } = ($new_dir ? '1' : '0');
9deadd1d Moritz Bunkus
783342e0 Sven Schöling
return '<a href="' . $models->get_callback(%params) . '">' . _H($title) . $image . '</a>';
9deadd1d Moritz Bunkus
}

ef32afed Moritz Bunkus
sub paginate_controls {
43bcf835 Sven Schöling
my ($self, %params) = _hashify(1, @_);
ef32afed Moritz Bunkus
my $controller = $self->{CONTEXT}->stash->get('SELF');
783342e0 Sven Schöling
my $models = $params{models} || $self->{CONTEXT}->stash->get('MODELS');
my $pager = $models->paginated;
ec3a4636 Sven Schöling
# my $paginate_spec = $controller->get_paginate_spec;

783342e0 Sven Schöling
my %paginate_params = $models->get_paginate_args;
ef32afed Moritz Bunkus
my %template_params = (
5b22ebf0 Moritz Bunkus
pages => \%paginate_params,
ef32afed Moritz Bunkus
url_maker => sub {
5e9aaf1c Moritz Bunkus
my %url_params = _hashify(0, @_);
ec3a4636 Sven Schöling
$url_params{ $pager->form_params->[0] } = delete $url_params{page};
$url_params{ $pager->form_params->[1] } = delete $url_params{per_page} if exists $url_params{per_page};
ef32afed Moritz Bunkus
9d015fd3 Sven Schöling
return $models->get_callback(%url_params);
ef32afed Moritz Bunkus
},
43bcf835 Sven Schöling
%params,
ef32afed Moritz Bunkus
);

d4458803 Moritz Bunkus
return SL::Presenter->get->render('common/paginate', %template_params);
ef32afed Moritz Bunkus
}

8177c150 Moritz Bunkus
1;

__END__

=head1 NAME

SL::Templates::Plugin::L -- Layouting / tag generation

=head1 SYNOPSIS

Usage from a template:

[% USE L %]

58966151 Thomas Heck
[% L.select_tag('direction', [ [ 'left', 'To the left' ], [ 'right', 'To the right', 1 ] ]) %]
8177c150 Moritz Bunkus
58966151 Thomas Heck
[% L.select_tag('direction', [ { direction => 'left', display => 'To the left' },
{ direction => 'right', display => 'To the right' } ],
value_key => 'direction', title_key => 'display', default => 'right')) %]

[% L.select_tag('direction', [ { direction => 'left', display => 'To the left' },
{ direction => 'right', display => 'To the right', selected => 1 } ],
value_key => 'direction', title_key => 'display')) %]
8177c150 Moritz Bunkus
=head1 DESCRIPTION

A module modeled a bit after Rails' ActionView helpers. Several small
functions that create HTML tags from various kinds of data sources.

da2fecb4 Moritz Bunkus
The C<id> attribute is usually calculated automatically. This can be
overridden by either specifying an C<id> attribute or by setting
C<no_id> to trueish.

8177c150 Moritz Bunkus
=head1 FUNCTIONS

71f55f78 Moritz Bunkus
=head2 LOW-LEVEL FUNCTIONS

d093f01c Moritz Bunkus
The following items are just forwarded to L<SL::Presenter::Tag>:
71f55f78 Moritz Bunkus
d093f01c Moritz Bunkus
=over 2
71f55f78 Moritz Bunkus
d093f01c Moritz Bunkus
=item * C<name_to_id $name>
8177c150 Moritz Bunkus
d093f01c Moritz Bunkus
=item * C<stringify_attributes %items>
8177c150 Moritz Bunkus
d093f01c Moritz Bunkus
=item * C<html_tag $tag_name, $content_string, %attributes>
71f55f78 Moritz Bunkus
=back

=head2 HIGH-LEVEL FUNCTIONS

d093f01c Moritz Bunkus
The following functions are just forwarded to L<SL::Presenter::Tag>:
58966151 Thomas Heck
d093f01c Moritz Bunkus
=over 2
58966151 Thomas Heck
d093f01c Moritz Bunkus
=item * C<input_tag $name, $value, %attributes>
58966151 Thomas Heck
d093f01c Moritz Bunkus
=item * C<select_tag $name, \@collection, %attributes>
58966151 Thomas Heck
=back

d093f01c Moritz Bunkus
Available high-level functions implemented in this module:
072c8215 Moritz Bunkus
=over 4

1ec0f541 Moritz Bunkus
=item C<yes_no_tag $name, $value, %attributes>

Creates a HTML 'select' tag with the two entries C<yes> and C<no> by
58966151 Thomas Heck
calling L<select_tag>. C<$value> determines
1ec0f541 Moritz Bunkus
which entry is selected. The C<%attributes> are passed through to
L<select_tag>.

93bae7aa Sven Schöling
=item C<hidden_tag $name, $value, %attributes>

Creates a HTML 'input type=hidden' tag named C<$name> with the value
C<$value> and with arbitrary HTML attributes from C<%attributes>. The
tag's C<id> defaults to C<name_to_id($name)>.

=item C<submit_tag $name, $value, %attributes>

Creates a HTML 'input type=submit class=submit' tag named C<$name> with the
value C<$value> and with arbitrary HTML attributes from C<%attributes>. The
tag's C<id> defaults to C<name_to_id($name)>.

a30ad33e Moritz Bunkus
If C<$attributes{confirm}> is set then a JavaScript popup dialog will
be added via the C<onclick> handler asking the question given with
341fbe8b Moritz Bunkus
C<$attributes{confirm}>. The request is only submitted if the user
a30ad33e Moritz Bunkus
clicks the dialog's ok/yes button.

86a76ea5 Moritz Bunkus
=item C<ajax_submit_tag $url, $form_selector, $text, %attributes>

Creates a HTML 'input type="button"' tag with a very specific onclick
handler that submits the form given by the jQuery selector
C<$form_selector> to the URL C<$url> (the actual JavaScript function
17f39e02 Moritz Bunkus
called for that is C<kivi.submit_ajax_form()> in
C<js/client_js.js>). The button's label will be C<$text>.
86a76ea5 Moritz Bunkus
341fbe8b Moritz Bunkus
=item C<button_tag $onclick, $text, %attributes>

Creates a HTML 'input type="button"' tag with an onclick handler
C<$onclick> and a value of C<$text>. The button does not have a name
nor an ID by default.

If C<$attributes{confirm}> is set then a JavaScript popup dialog will
be prepended to the C<$onclick> handler asking the question given with
C<$attributes{confirm}>. The request is only submitted if the user
clicks the dialog's "ok/yes" button.

11e4b8f3 Moritz Bunkus
=item C<textarea_tag $name, $value, %attributes>

Creates a HTML 'textarea' tag named C<$name> with the content
C<$value> and with arbitrary HTML attributes from C<%attributes>. The
tag's C<id> defaults to C<name_to_id($name)>.

3cc77e53 Moritz Bunkus
=item C<checkbox_tag $name, %attributes>

Creates a HTML 'input type=checkbox' tag named C<$name> with arbitrary
HTML attributes from C<%attributes>. The tag's C<id> defaults to
C<name_to_id($name)>. The tag's C<value> defaults to C<1>.

If C<%attributes> contains a key C<label> then a HTML 'label' tag is
created with said C<label>. No attribute named C<label> is created in
that case.

4edfabd2 Sven Schöling
If C<%attributes> contains a key C<checkall> then the value is taken as a
JQuery selector and clicking this checkbox will also toggle all checkboxes
matching the selector.

a56327d7 Moritz Bunkus
=item C<date_tag $name, $value, %attributes>
22ae0bf0 Sven Schöling
Creates a date input field, with an attached javascript that will open a
a56327d7 Moritz Bunkus
calendar on click.
22ae0bf0 Sven Schöling
11e4b8f3 Moritz Bunkus
=item C<radio_button_tag $name, %attributes>

Creates a HTML 'input type=radio' tag named C<$name> with arbitrary
HTML attributes from C<%attributes>. The tag's C<value> defaults to
C<1>. The tag's C<id> defaults to C<name_to_id($name . "_" . $value)>.

If C<%attributes> contains a key C<label> then a HTML 'label' tag is
created with said C<label>. No attribute named C<label> is created in
that case.

62ba378c Moritz Bunkus
=item C<javascript_tag $file1, $file2, $file3...>

Creates a HTML 'E<lt>script type="text/javascript" src="..."E<gt>'
tag for each file name parameter passed. Each file name will be
postfixed with '.js' if it isn't already and prefixed with 'js/' if it
doesn't contain a slash.

6df470c3 Moritz Bunkus
=item C<stylesheet_tag $file1, $file2, $file3...>

Creates a HTML 'E<lt>link rel="text/stylesheet" href="..."E<gt>' tag
for each file name parameter passed. Each file name will be postfixed
with '.css' if it isn't already and prefixed with 'css/' if it doesn't
contain a slash.

e5205a23 Moritz Bunkus
=item C<tabbed \@tab, %attributes>

Will create a tabbed area. The tabs should be created with the helper function
ffdfdc7e Sven Schöling
C<tab>. Example:

[% L.tabbed([
L.tab(LxERP.t8('Basic Data'), 'part/_main_tab.html'),
L.tab(LxERP.t8('Custom Variables'), 'part/_cvar_tab.html', if => SELF.display_cvar_tab),
]) %]

7714d4d0 Sven Schöling
=item C<areainput_tag $name, $content, %PARAMS>

Creates a generic input tag or textarea tag, depending on content size. The
796598ed Sven Schöling
amount of desired rows must be either given with the C<rows> parameter or can
be computed from the value and the C<cols> paramter, Accepted parameters
7714d4d0 Sven Schöling
include C<min_rows> for rendering a minimum of rows if a textarea is displayed.

You can force input by setting rows to 1, and you can force textarea by setting
rows to anything >1.

04854ac2 Moritz Bunkus
=item C<multiselect2side $id, %params>

Creates a JavaScript snippet calling the jQuery function
C<multiselect2side> on the select control with the ID C<$id>. The
select itself is not created. C<%params> can contain the following
entries:

=over 2

=item C<labelsx>

The label of the list of available options. Defaults to the
translation of 'Available'.

=item C<labeldx>

The label of the list of selected options. Defaults to the
translation of 'Selected'.

=back

b7383969 Moritz Bunkus
=item C<sortable_element $selector, %params>

Makes the children of the DOM element C<$selector> (a jQuery selector)
sortable with the I<jQuery UI Selectable> library. The children can be
dragged & dropped around. After dropping an element an URL can be
postet to with the element IDs of the sorted children.

82dcbe71 Moritz Bunkus
If this is used then the JavaScript file C<js/jquery-ui.js> must be
included manually as well as it isn't loaded via C<$::form-gt;header>.

b7383969 Moritz Bunkus
C<%params> can contain the following entries:

=over 2

=item C<url>

The URL to POST an AJAX request to after a dragged element has been
dropped. The AJAX request's return value is ignored. If given then
C<$params{with}> must be given as well.

=item C<with>

A string that is interpreted as the prefix of the children's ID. Upon
POSTing the result each child whose ID starts with C<$params{with}> is
considered. The prefix and the following "_" is removed from the
ID. The remaining parts of the IDs of those children are posted as a
single array parameter. The array parameter's name is either
C<$params{as}> or, missing that, C<$params{with}>.

=item C<as>

Sets the POST parameter name for AJAX request after dropping an
element (see C<$params{with}>).

1b522616 Moritz Bunkus
=item C<handle>

An optional jQuery selector specifying which part of the child element
7328cbd6 Moritz Bunkus
is dragable. If the parameter is not given then it defaults to
C<.dragdrop> matching DOM elements with the class C<dragdrop>. If the
parameter is set and empty then the whole child element is dragable,
and clicks through to underlying elements like inputs or links might
not work.
1b522616 Moritz Bunkus
3c0769d8 Moritz Bunkus
=item C<dont_recolor>

If trueish then the children will not be recolored. The default is to
recolor the children by setting the class C<listrow0> on odd and
C<listrow1> on even entries.

cb604b36 Moritz Bunkus
=item C<params>

An optional JavaScript string that is evaluated before sending the
POST request. The result must be a string that is appended to the URL.

b7383969 Moritz Bunkus
=back

Example:

82dcbe71 Moritz Bunkus
<script type="text/javascript" src="js/jquery-ui.js"></script>

b7383969 Moritz Bunkus
<table id="thing_list">
<thead>
<tr><td>This</td><td>That</td></tr>
</thead>
<tbody>
<tr id="thingy_2"><td>stuff</td><td>more stuff</td></tr>
<tr id="thingy_15"><td>stuff</td><td>more stuff</td></tr>
<tr id="thingy_6"><td>stuff</td><td>more stuff</td></tr>
</tbody>
<table>

[% L.sortable_element('#thing_list tbody',
3c0769d8 Moritz Bunkus
url => 'controller.pl?action=SystemThings/reorder',
with => 'thingy',
as => 'thing_ids',
recolor_rows => 1) %]
b7383969 Moritz Bunkus
After dropping e.g. the third element at the top of the list a POST
request would be made to the C<reorder> action of the C<SystemThings>
controller with a single parameter called C<thing_ids> -- an array
containing the values C<[ 6, 2, 15 ]>.

f4f55336 Sven Schöling
=item C<dump REF>

Dumps the Argument using L<Data::Dumper> into a E<lt>preE<gt> block.

9deadd1d Moritz Bunkus
=item C<sortable_table_header $by, %params>

Create a link and image suitable for placement in a table
header. C<$by> must be an index set up by the controller with
L<SL::Controller::Helper::make_sorted>.

The optional parameter C<$params{title}> can override the column title
displayed to the user. Otherwise the column title from the
controller's sort spec is used.

The other parameters in C<%params> are passed unmodified to the
underlying call to L<SL::Controller::Base::url_for>.

See the documentation of L<SL::Controller::Helper::Sorted> for an
overview and further usage instructions.

ef32afed Moritz Bunkus
=item C<paginate_controls>

Create a set of links used to paginate a list view.

See the documentation of L<SL::Controller::Helper::Paginated> for an
overview and further usage instructions.

71f55f78 Moritz Bunkus
=back

=head2 CONVERSION FUNCTIONS

=over 4

ffdfdc7e Sven Schöling
=item C<tab, description, target, %PARAMS>

Creates a tab for C<tabbed>. The description will be used as displayed name.
The target should be a block or template that can be processed. C<tab> supports
a C<method> parameter, which can override the process method to apply target.
C<method => 'raw'> will just include the given text as is. I was too lazy to
implement C<include> properly.

Also an C<if> attribute is supported, so that tabs can be suppressed based on
some occasion. In this case the supplied block won't even get processed, and
the resulting tab will get ignored by C<tabbed>:

L.tab('Awesome tab wih much info', '_much_info.html', if => SELF.wants_all)

4f15b8f0 Moritz Bunkus
=item C<truncate $text, [%params]>

See L<SL::Presenter::Text/truncate>.
46b49275 Moritz Bunkus
4f15b8f0 Moritz Bunkus
=item C<simple_format $text>
46b49275 Moritz Bunkus
4f15b8f0 Moritz Bunkus
See L<SL::Presenter::Text/simple_format>.
46b49275 Moritz Bunkus
8177c150 Moritz Bunkus
=back

=head1 MODULE AUTHORS

Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>

L<http://linet-services.de>