line
stmt
bran
cond
sub
pod
time
code
1
package HTML::Widgets::SelectLayers;
2
3
1
1
6137
use strict;
1
2
1
52
4
1
1
8
use vars qw($VERSION);
1
1
1
1521
5
6
$VERSION = '0.07';
7
8
=head1 NAME
9
10
HTML::Widgets::SelectLayers - Perl extension for selectable HTML layers
11
12
=head1 SYNOPSIS
13
14
use HTML::Widgets::SelectLayers;
15
16
use Tie::IxHash;
17
tie my %options, 'Tie::IxHash',
18
'value' => 'Select One',
19
'value2' => 'Select Two',
20
;
21
22
$widget = new HTML::Widgets::SelectLayers(
23
'options' => \%options,
24
'form_name' => 'dummy',
25
'form_action' => 'process.cgi',
26
27
#new code auto-detects form types (radio not yet supported)
28
#'form_elements' => [ qw( textfield1 textfield2 checkbox1 radio1 select1 ) ],
29
'form_elements' => [ qw( textfield1 textfield2 checkbox1 radio1 select1 ) ],
30
31
#deprecated style still works for now
32
#'form_text' => [ qw( textfield1 textfield2 ) ],
33
#'form_checkbox' => [ qw( checkbox1 ) ],
34
#'form_radio' => [ qw( radio1 ) ],
35
#'form_select' => [ qw( select1 ) ],
36
37
'layer_callback' => sub {
38
my $layer = shift;
39
my $html = qq! !;
40
$html .= $other_stuff;
41
$html;
42
},
43
);
44
45
print '
46
' '.
47
' '.
48
' '.
49
$widget->html;
50
51
=head1 DESCRIPTION
52
53
This module implements an HTML widget with multiple layers. Only one layer
54
is visible at any given time, controlled by a ESELECTE box. For an
55
example see http://www.420.am/selectlayers/
56
57
This HTML generated by this module uses JavaScript, but nevertheless attempts
58
to be as cross-browser as possible. The 0.05 release drops Navigator 4
59
compatibility and has been tested under Mozilla Firefox 1.0.6, MSIE 6.0,
60
Konqueror 3.3.2, and Opera 8.0.2 (2006 note: still working under newer
61
browsers such as IE7, Firefox 2.0, etc.).
62
63
=head1 FORMS
64
65
My understanding is that forms cannot span EDIVEs elements. The
66
generated HTML will have a E/FORME tag before the layers and will
67
generate EFORME and E/FORME tags for each layer. To facilitate
68
ESUBMITE buttons located within the layers, you can pass a form name
69
and element names, and the relevant values will be copied to the layer's form.
70
See the B options below.
71
72
=head1 METHODS
73
74
=over 4
75
76
=item new KEY, VALUE, KEY, VALUE...
77
78
Options are passed as name/value pairs:
79
80
options - Hash reference of layers and labels for the ESELECTE. See
81
L to control ordering.
82
In HTML: EOPTION VALUE="$layer"E$labelE/OPTIONE
83
84
layer_callback - subroutine reference to create each layer. The layer name
85
is passed as an option in I<@_>
86
87
selected_layer - (optional) initially selected layer
88
89
form_name - (optional) Form name to copy values from. If not supplied, no
90
values will be copied.
91
92
form_action - Form action
93
94
form_elements - (optional) Array reference of form fields to copy from the
95
B form. Field type is autodetected; currently
96
text, hidden, checkbox, and select fields are
97
supported. Radio fields are not yet supported.
98
99
form_text - (optional) Array reference of text (or hidden) form fields to copy
100
from the B form.
101
102
form_checkbox - (optional) Array reference of checkbox form fields to copy from
103
the B form.
104
105
form_radio - (optional) Array reference of radio form fields to copy from the
106
B form.
107
108
form_select - (optional) Array reference of select form fields to copy from
109
the B form.
110
111
fixup_callback - (optional) subroutine reference, returns supplimentary
112
JavaScript for the function described above under FORMS.
113
114
size - (optional) size of the ESELECTE, default 1.
115
116
unique_key - (optional) prepended to all JavaScript function/variable/object
117
names to avoid namespace collisions.
118
119
html_beween - (optional) HTML between the ESELECTE and the layers.
120
121
under_position - (optional) specifies the positioning of any HTML appearing after the widget. I, the default, positions subsequent HTML underneath the current layer (or immediately under the select box if no layer has yet been selected), reflowing when layers are changed. I calculates the size of the largest layer and keeps the subsequent HTML in a single position underneath it. Note that I works by positioning subsequent HTML in a EDIVE, so you should probably close it yourself with a E/DIVE before your E/HTMLE end tag. I is a bit experimental and might have some quirks with truncating the end of the page under IE; you might have better results by just making all your layers the exact same size at the moment.
122
123
=cut
124
125
sub new {
126
0
0
1
my($proto, %options) = @_;
127
0
0
my $class = ref($proto) || $proto;
128
0
my $self = \%options;
129
0
bless($self, $class);
130
}
131
132
=cut
133
134
=item html
135
136
Returns HTML for the widget.
137
138
=cut
139
140
sub html {
141
0
0
1
my $self = shift;
142
0
0
my $key = exists($self->{unique_key}) ? $self->{unique_key} : '';
143
0
0
my $between = exists($self->{html_between}) ? $self->{html_between} : '';
144
0
my $options = $self->{options};
145
0
0
my $form_action = exists($self->{form_action}) ? $self->{form_action} : '';
146
147
0
0
my $form_elements =
148
exists($self->{form_elements}) ? $self->{form_elements} : [];
149
0
0
my $form_text =
150
exists($self->{form_text}) ? $self->{form_text} : [];
151
0
0
my $form_checkbox =
152
exists($self->{form_checkbox}) ? $self->{form_checkbox} : [];
153
0
0
my $form_radio =
154
exists($self->{form_radio}) ? $self->{form_radio} : [];
155
0
0
my $form_select =
156
exists($self->{form_select}) ? $self->{form_select} : [];
157
158
0
0
my $under_position =
159
exists($self->{under_position}) ? $self->{under_position} : 'static';
160
0
0
my $hidden = lc($under_position) eq 'absolute'
161
? 'visibility: hidden; position: absolute; z-index: 0'
162
: 'display: none; z-index: 0';
163
#my $show = lc($under_position) eq 'absolute'
164
# ? 'visibility: visible'
165
# : 'display: "" ';
166
167
0
my $html = $self->_safeonload.
168
$self->_visualize.
169
"".
170
$self->_changed.
171
$self->_fixup.
172
$self->_select. $between. ''.
173
"";
174
175
#foreach my $layer ( 'konq_kludge', keys %$options ) {
176
0
foreach my $layer ( keys %$options ) {
177
178
#start layer
179
180
0
$html .= <
181
182
END
183
184
#form fields
185
0
$html .= <
186
187
END
188
0
foreach my $f ( @$form_elements, @$form_text, @$form_checkbox, @$form_radio, @$form_select )
189
{
190
0
$html .= <
191
192
END
193
}
194
195
#layer
196
0
$html .= &{$self->{layer_callback}}($layer);
0
197
198
#end form & layer
199
0
$html .= <
200
201
202
206
END
207
208
}
209
210
0
0
if ( $under_position eq 'absolute' ) {
211
0
$html .= <
212
216
END
217
}
218
219
0
$html;
220
}
221
222
sub _fixup {
223
0
0
my $self = shift;
224
0
0
my $key = exists($self->{unique_key}) ? $self->{unique_key} : '';
225
0
0
my $form_name = $self->{form_name} or return '';
226
227
0
0
my $form_elements =
228
exists($self->{form_elements}) ? $self->{form_elements} : [];
229
0
0
my $form_text =
230
exists($self->{form_text}) ? $self->{form_text} : [];
231
0
0
my $form_checkbox =
232
exists($self->{form_checkbox}) ? $self->{form_checkbox} : [];
233
0
0
my $form_radio =
234
exists($self->{form_radio}) ? $self->{form_radio} : [];
235
0
0
my $form_select =
236
exists($self->{form_select}) ? $self->{form_select} : [];
237
0
my $html = <
238
";
320
321
0
$html;
322
323
}
324
325
sub _select {
326
0
0
my $self = shift;
327
0
0
my $key = exists($self->{unique_key}) ? $self->{unique_key} : '';
328
0
my $options = $self->{options};
329
0
0
my $selected = exists($self->{selected_layer}) ? $self->{selected_layer} : '';
330
0
0
my $size = exists($self->{size}) ? $self->{size} : 1;
331
0
my $html = "
332
333
";
334
0
foreach my $option ( keys %$options ) {
335
0
$html .= qq(
336
0
0
$html .= ' SELECTED' if $option eq $selected;
337
0
$html .= '>'. $options->{$option}. '';
338
}
339
0
$html .= '';
340
}
341
342
sub _changed {
343
0
0
my $self = shift;
344
0
0
my $key = exists($self->{unique_key}) ? $self->{unique_key} : '';
345
0
my $options = $self->{options};
346
0
0
my $under_position =
347
exists($self->{under_position}) ? $self->{under_position} : 'static';
348
349
0
my $html = "
350
";
375
0
$html;
376
}
377
378
sub _visualize {
379
0
0
my $self = shift;
380
0
0
my $key = exists($self->{unique_key}) ? $self->{unique_key} : '';
381
0
0
return '' unless exists($self->{selected_layer});
382
0
my $selected = $self->{selected_layer};
383
0
0
my $under_position =
384
exists($self->{under_position}) ? $self->{under_position} : 'static';
385
0
0
my $display = ( $under_position eq 'absolute' )
386
? 'visibility = "visible"'
387
: 'display = ""';
388
0
<
389
395
END
396
}
397
398
sub _safeonload {
399
0
0
<
400
419
END
420
}
421
422
=back
423
424
=head1 AUTHOR
425
426
Ivan Kohler Eivan-selectlayers@420.amE
427
428
=head1 COPYRIGHT
429
430
Copyright (c) 2002-2005 Ivan Kohler
431
All rights reserved.
432
This program is free software; you can redistribute it and/or modify it under
433
the same terms as Perl itself.
434
435
=head1 BUGS
436
437
JavaScript
438
439
All the different form_* options are unnecessary, could use .type to auto-sense
440
441
Could give you a function or something for copying variables out of the
442
layered forms.
443
444
=head1 SEE ALSO
445
446
L. L, http://www.xs4all.nl/~ppk/js/dom.html,
447
http://javascript.about.com/library/scripts/blsafeonload.htm
448
449
=cut