Revision 072c8215
Von Moritz Bunkus vor mehr als 11 Jahren hinzugefügt
SL/Template/Plugin/L.pm | ||
---|---|---|
128 | 128 |
my $with_empty = delete($attributes{with_empty}); |
129 | 129 |
my $empty_title = delete($attributes{empty_title}); |
130 | 130 |
|
131 |
my $with_optgroups = delete($attributes{with_optgroups}); |
|
132 |
|
|
131 | 133 |
my %selected; |
132 | 134 |
|
133 | 135 |
if ( ref($attributes{default}) eq 'ARRAY' ) { |
... | ... | |
142 | 144 |
delete($attributes{default}); |
143 | 145 |
|
144 | 146 |
|
145 |
my @options; |
|
146 |
|
|
147 |
if ( $with_empty ) { |
|
148 |
push(@options, [undef, $empty_title || '']); |
|
149 |
} |
|
147 |
my @all_options; |
|
148 |
push @all_options, [undef, $empty_title || ''] if $with_empty; |
|
150 | 149 |
|
151 | 150 |
my $normalize_entry = sub { |
152 |
|
|
153 | 151 |
my ($type, $entry, $sub, $key) = @_; |
154 | 152 |
|
155 |
if ( $sub ) { |
|
156 |
return $sub->($entry); |
|
157 |
} |
|
153 |
return $sub->($entry) if $sub; |
|
158 | 154 |
|
159 | 155 |
my $ref = ref($entry); |
160 | 156 |
|
161 | 157 |
if ( !$ref ) { |
162 |
|
|
163 |
if ( $type eq 'value' || $type eq 'title' ) { |
|
164 |
return $entry; |
|
165 |
} |
|
166 |
|
|
158 |
return $entry if $type eq 'value' || $type eq 'title'; |
|
167 | 159 |
return 0; |
168 | 160 |
} |
169 | 161 |
|
170 | 162 |
if ( $ref eq 'ARRAY' ) { |
171 |
|
|
172 |
if ( $type eq 'value' ) { |
|
173 |
return $entry->[0]; |
|
174 |
} |
|
175 |
|
|
176 |
if ( $type eq 'title' ) { |
|
177 |
return $entry->[1]; |
|
178 |
} |
|
179 |
|
|
180 |
return $entry->[2]; |
|
181 |
} |
|
182 |
|
|
183 |
if ( $ref eq 'HASH' ) { |
|
184 |
return $entry->{$key}; |
|
185 |
} |
|
186 |
|
|
187 |
if ( $type ne 'default' || $entry->can($key) ) { |
|
188 |
return $entry->$key; |
|
163 |
return $entry->[ $type eq 'value' ? 0 : $type eq 'title' ? 1 : 2 ]; |
|
189 | 164 |
} |
190 | 165 |
|
166 |
return $entry->{$key} if $ref eq 'HASH'; |
|
167 |
return $entry->$key if $type ne 'default' || $entry->can($key); |
|
191 | 168 |
return undef; |
192 | 169 |
}; |
193 | 170 |
|
194 |
foreach my $entry ( @{ $collection } ) { |
|
195 |
my $value; |
|
196 |
my $title; |
|
171 |
my $list_to_code = sub { |
|
172 |
my ($sub_collection) = @_; |
|
197 | 173 |
|
198 |
if ( $value_title_sub ) { |
|
199 |
($value, $title) = @{ $value_title_sub->($entry) }; |
|
200 |
} else { |
|
174 |
my @options; |
|
175 |
foreach my $entry ( @{ $sub_collection } ) { |
|
176 |
my $value; |
|
177 |
my $title; |
|
201 | 178 |
|
202 |
$value = $normalize_entry->('value', $entry, $value_sub, $value_key); |
|
203 |
$title = $normalize_entry->('title', $entry, $title_sub, $title_key); |
|
204 |
} |
|
179 |
if ( $value_title_sub ) { |
|
180 |
($value, $title) = @{ $value_title_sub->($entry) }; |
|
181 |
} else { |
|
182 |
|
|
183 |
$value = $normalize_entry->('value', $entry, $value_sub, $value_key); |
|
184 |
$title = $normalize_entry->('title', $entry, $title_sub, $title_key); |
|
185 |
} |
|
205 | 186 |
|
206 |
my $default = $normalize_entry->('default', $entry, $default_sub, $default_key); |
|
187 |
my $default = $normalize_entry->('default', $entry, $default_sub, $default_key);
|
|
207 | 188 |
|
208 |
push(@options, [$value, $title, $default]); |
|
209 |
} |
|
189 |
push(@options, [$value, $title, $default]);
|
|
190 |
}
|
|
210 | 191 |
|
211 |
foreach my $entry (@options) { |
|
212 |
if ( exists($selected{$entry->[0]}) ) { |
|
213 |
$entry->[2] = 1; |
|
192 |
foreach my $entry (@options) { |
|
193 |
$entry->[2] = 1 if $selected{$entry->[0]}; |
|
214 | 194 |
} |
215 |
} |
|
216 | 195 |
|
217 |
my $code = ''; |
|
196 |
return join '', map { $self->html_tag('option', _H($_->[1]), value => $_->[0], selected => $_->[2]) } @options; |
|
197 |
}; |
|
218 | 198 |
|
219 |
foreach my $entry (@options) { |
|
220 |
my %args = (value => $entry->[0]); |
|
199 |
my $code; |
|
221 | 200 |
|
222 |
$args{selected} = $entry->[2]; |
|
201 |
if (!$with_optgroups) { |
|
202 |
$code = $list_to_code->($collection); |
|
223 | 203 |
|
224 |
$code .= $self->html_tag('option', _H($entry->[1]), %args); |
|
204 |
} else { |
|
205 |
$code = join '', map { |
|
206 |
my ($optgroup_title, $sub_collection) = @{ $_ }; |
|
207 |
$self->html_tag('optgroup', $list_to_code->($sub_collection), label => $optgroup_title) |
|
208 |
} @{ $collection }; |
|
225 | 209 |
} |
226 | 210 |
|
227 |
$code = $self->html_tag('select', $code, %attributes, name => $name); |
|
228 |
|
|
229 |
return $code; |
|
211 |
return $self->html_tag('select', $code, %attributes, name => $name); |
|
230 | 212 |
} |
231 | 213 |
|
232 | 214 |
sub textarea_tag { |
... | ... | |
771 | 753 |
|
772 | 754 |
The tag's C<id> defaults to C<name_to_id($name)>. |
773 | 755 |
|
756 |
If the option C<with_optgroups> is set then this function expects |
|
757 |
C<\@collection> to be one level deeper. The upper-most level is |
|
758 |
translated into a HTML C<optgroup> tag. So the structure becomes: |
|
759 |
|
|
760 |
=over 4 |
|
761 |
|
|
762 |
=item 1. Array of array references. Each element in the |
|
763 |
C<\@collection> is converted into an optgroup. |
|
764 |
|
|
765 |
=item 2. The optgroup's C<label> attribute will be set to the the |
|
766 |
first element in the array element. The second array element is then |
|
767 |
converted to a list of C<option> tags like it is described above. |
|
768 |
|
|
769 |
=back |
|
770 |
|
|
771 |
Example for use of optgroups: |
|
772 |
|
|
773 |
# First in a controller: |
|
774 |
my @collection = ( |
|
775 |
[ t8("First optgroup with two items"), |
|
776 |
[ { id => 42, name => "item one" }, |
|
777 |
{ id => 54, name => "second item" }, |
|
778 |
{ id => 23, name => "and the third one" }, |
|
779 |
] ], |
|
780 |
[ t8("Another optgroup, with a lot of items from Rose"), |
|
781 |
SL::DB::Manager::Customer->get_all_sorted ], |
|
782 |
); |
|
783 |
|
|
784 |
# Later in the template: |
|
785 |
[% L.select_tag('the_selection', COLLECTION, with_optgroups=1, title_key='name') %] |
|
786 |
|
|
774 | 787 |
=item C<yes_no_tag $name, $value, %attributes> |
775 | 788 |
|
776 | 789 |
Creates a HTML 'select' tag with the two entries C<yes> and C<no> by |
Auch abrufbar als: Unified diff
L.select_tag: Unterstützung für Nutzung von <optgroup>s