Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision fa5899cf

Von Tamino Steinert vor mehr als 2 Jahren hinzugefügt

  • ID fa5899cf557e580c053f15d9430f72128e39928f
  • Vorgänger 7866dd56
  • Nachfolger 527e86b3

multi_level_select_tag hinzugefüht

Dieser Tag dient um aus verschachtelten Objekten mehrere
hierarchische select tags zu erzeugen

Unterschiede anzeigen:

SL/Presenter/Tag.pm
html_tag input_tag hidden_tag javascript man_days_tag name_to_id select_tag
checkbox_tag button_tag submit_tag ajax_submit_tag input_number_tag
stringify_attributes textarea_tag link_tag date_tag
div_tag radio_button_tag img_tag);
div_tag radio_button_tag img_tag multi_level_select_tag);
our %EXPORT_TAGS = (ALL => \@EXPORT_OK);
use Carp;
......
return $select_html;
}
sub multi_level_select_tag {
my ($name, $collection, $levels, %attributes) = @_;
_set_id_attribute(\%attributes, $name);
my $id = $attributes{id};
$collection = [] if defined($collection) && !ref($collection) && ($collection eq '');
my $surround_tag = delete(%attributes{surround_tag});
my $multi_level_select_tag = "";
my %level_keys = ();
my $base_attributes = delete($attributes{"level_1"}) || {};
my $base_name = delete($base_attributes->{name});
my $base_value_key = $base_attributes->{value_key} || 'id';
my $base_title_key = $base_attributes->{title_key} || $base_value_key;
my $base_default = $base_attributes->{default};
my $base_default_key = $base_attributes->{default_key};
$level_keys{1} = {
"value" => $base_value_key,
"title" => $base_title_key,
};
$base_attributes->{id} = $id . "_level_1";
$base_attributes->{onchange} = $id . "_on_chanche_level_1(this)";
my $current_select = select_tag(
$base_name,
$collection,
%{$base_attributes}
);
if ($surround_tag) {
$multi_level_select_tag .= html_tag($surround_tag, $current_select);
} else {
$multi_level_select_tag .= $current_select;
}
my $last_object;
if ($base_default) {
($last_object) = grep { $_->{$base_value_key} eq $base_default } @{$collection};
} elsif ($base_default_key) {
($last_object) = grep { $_->{$base_default_key} } @{$collection};
} else {
$last_object = $collection->[0];
}
foreach my $level (2 .. $levels) {
my $current_attributes = delete($attributes{"level_$level"}) || {};
my $current_name = delete($current_attributes->{name});
my $current_value_key = $current_attributes->{value_key} || 'id';
my $current_title_key = $current_attributes->{title_key} || $current_value_key;
my $current_default = $current_attributes->{default};
my $current_default_key = $current_attributes->{default_key};
my $current_object_key = delete($current_attributes->{object_key});
die "need object_key in level_$level in multi_level_select_tag" unless $current_object_key;
$level_keys{$level} = {
"value" => $current_value_key,
"title" => $current_title_key,
"object" => $current_object_key,
};
$current_attributes->{id} = $id . "_level_$level";
$current_attributes->{onchange} = $id . "_on_chanche_level_${level}(this)" unless $level eq $levels;
my $current_collection = $last_object->{$current_object_key};
my $current_select = select_tag(
$current_name,
$current_collection,
%{$current_attributes}
);
if ($surround_tag) {
$multi_level_select_tag .= html_tag($surround_tag, $current_select);
} else {
$multi_level_select_tag .= $current_select;
}
if ($current_default) {
($last_object) = grep { $_->{$current_value_key} eq $current_default } @{$current_collection};
} elsif ($current_default_key) {
($last_object) = grep { $_->{$current_default_key} } @{$current_collection};
} else {
$last_object = $current_collection->[0];
}
}
my $code = "";
if ($levels > 1) {
my $js_option_string = ""; # js hash map (level->value->{[value: 1, title: 'foo'], ...})
my @current_collections = @{$collection};
my @next_collections = ();
foreach my $level (1 .. ($levels - 1)) {
$js_option_string .= "'${level}': {";
foreach my $option (@current_collections) {
$js_option_string .= "'" . $option->{$level_keys{$level}{value}} . "': [";
map { $js_option_string .= "{ value: '" . $_->{$level_keys{$level + 1}{value}}
. "', title: '" . $_->{$level_keys{$level + 1}{title}}
. "'}," } @{$option->{$level_keys{$level + 1}{object}}};
$js_option_string .= "],";
push @next_collections, @{$option->{$level_keys{$level + 1}{object}}};
}
$js_option_string .= "},";
@current_collections = @next_collections;
@next_collections = ();
}
$code .= javascript( qq|
var ${id}_options = {
$js_option_string
};
|);
foreach my $level (1 .. ($levels - 1)) {
my $next_level = $level + 1;
$code .= javascript( qq|
function ${id}_on_chanche_level_${level}(select_${level}) {
var value = select_${level}.value;
for (var i = ${next_level}; i < $levels + 1; i++) {
var id = '${id}_level_' + i;
var select_i = document.getElementById(id);
while (select_i.options.length) {
select_i.options.remove(0);
}
select_i.disabled = true;
}
var id_${next_level} = '${id}_level_${next_level}';
var select_${next_level} = document.getElementById(id_${next_level});
for (var i=0; i < ${id}_options[${level}][value].length; i++) {
var option = new Option(${id}_options[${level}][value][i].title, ${id}_options[${level}][value][i].value)
select_${next_level}.options.add(option);
}
select_${next_level}.disabled = false;
select_${next_level}.selectedIndex = -1;
}
|);
}
}
return $multi_level_select_tag . $code;
}
sub checkbox_tag {
my ($name, %attributes) = @_;
......
# Later in the template:
[% L.select_tag('the_selection', COLLECTION, with_optgroups=1, title_key='name') %]
=item C<multi_level_select_tag $name, \@collection, $levels, %attributes>
Creates multiple HTML 'select' tags, one for each level. Each tag ist created
with C<select_tag>.
The parameters for C<select_tag> are created from the values stored in the
corrosponding level attributes. The attributes for each level are in
C<%attributes{level_i}>, starting with 1.
The following are used directly from each level:
=over 12
=item I<name> is deleted from level attributes.
The I<name> is used for the for the name of the 'select' tag.
=item I<object_key> is deleted from level attriutes.
The I<object_key> is used to get the level objects for the current level
from the object of the previous level, this is intended for the use of RSDB object.
Each level attributes musst contain I<object_key>, except level_1.
=item I<id> is overridden.
The I<id> is set to a specific value for use in JavaScript.
=item I<value_key> names the key for the value of level object. Defaults to
C<id>.
=item I<title_key> names the key for the titel of level object. Defaults to
C<$attributes{value_key}>.
=item I<default> is used to find the default level object.
=tiem I<default_key> names the key for the default feld of level object. Is
ignored if I<default> is set.
=back
<\@collection> is used for the level object of level 1. The objects of the next
level are taken from the previous level via the <object_key>. On each level the
objects must be a hash reference or a blessed reference.
A I<surround_tag> can be specified, which generates a C<html_tag> with the
corrosponding tag around evey C<select_tag>.
Example:
# First in a controller:
my @collection = (
{ 'description' => 'foo_1', 'id' => '1',
'key_1' => [
{ 'id' => 3, 'description' => "bar_1",
'key_2' => [
{ 'id' => 1, 'value' => "foobar_1", },
{ 'id' => 2, 'value' => "foobar_2", },
], },
{ 'id' => 4, 'description' => "bar_2",
'key_2' => [], },
], },
{ 'description' => 'foo_2', 'id' => '2',
'key_1' => [
{ 'id' => 1, 'description' => "bar_1",
'key_2' => [
{ 'id' => 3, 'value' => "foobar_3", },
{ 'id' => 4, 'value' => "foobar_4", },
], },
{ 'id' => 2, 'description' => "bar_2",
'stock' => [
{ 'id' => 5, 'value' => "test_5", },
], },
], },
);
# Later in the template (in a table):
[% L.multi_level_select_tag("multi_select_foo_bar_foobar", COLLECTION, 3,
surround_tag="td",
level_1={
name="foo.id",
value_key="id",
title_key="description",
default="2",
},
level_2={
object_key="key_1",
name="bar.id",
value_key="id",
title_key="description",
default="1",
},
level_3={
object_key="key_2",
name="foobar.id",
value_key="id",
title_key="value",
default="4",
},
) %]
=back
=head1 BUGS
SL/Template/Plugin/L.pm
sub img_tag { return _call_presenter('img_tag', @_); }
sub restricted_html { return _call_presenter('restricted_html', @_); }
sub stripped_html { return _call_presenter('stripped_html', @_); }
sub multi_level_select_tag { return _call_presenter('multi_level_select_tag', @_); }
sub _set_id_attribute {
my ($attributes, $name, $unique) = @_;

Auch abrufbar als: Unified diff