add support from select-multiple
[HTML-Widgets-SelectLayers.git] / SelectLayers.pm
index f37c90a..5444071 100644 (file)
@@ -3,7 +3,7 @@ package HTML::Widgets::SelectLayers;
 use strict;
 use vars qw($VERSION);
 
-$VERSION = '0.05';
+$VERSION = '0.07';
 
 =head1 NAME
 
@@ -23,10 +23,17 @@ HTML::Widgets::SelectLayers - Perl extension for selectable HTML layers
     'options'       => \%options,
     'form_name'     => 'dummy',
     'form_action'   => 'process.cgi',
-    'form_text'     => [ qw( textfield1 textfield2 ) ],
-    'form_checkbox' => [ qw( checkbox1 ) ],
-    'form_radio'    => [ qw( radio1 ) ],
-    'form_select'   => [ qw( select1 ) ],
+
+    #new code auto-detects form types (radio not yet supported)
+    #'form_elements' => [ qw( textfield1 textfield2 checkbox1 radio1 select1 ) ],
+    'form_elements' => [ qw( textfield1 textfield2 checkbox1 radio1 select1 ) ],
+    
+    #deprecated style still works for now
+    #'form_text'     => [ qw( textfield1 textfield2 ) ],
+    #'form_checkbox' => [ qw( checkbox1 ) ],
+    #'form_radio'    => [ qw( radio1 ) ],
+    #'form_select'   => [ qw( select1 ) ],
+
     'layer_callback' => sub {
       my $layer = shift;
       my $html = qq!<INPUT TYPE="hidden" NAME="layer" VALUE="$layer">!;
@@ -50,7 +57,8 @@ example see http://www.420.am/selectlayers/
 This HTML generated by this module uses JavaScript, but nevertheless attempts
 to be as cross-browser as possible.  The 0.05 release drops Navigator 4
 compatibility and has been tested under Mozilla Firefox 1.0.6, MSIE 6.0, 
-Konqueror 3.3.2, and Opera 8.0.2.
+Konqueror 3.3.2, and Opera 8.0.2 (2006 note: still working under newer
+browsers such as IE7, Firefox 2.0, etc.).
 
 =head1 FORMS
 
@@ -83,6 +91,11 @@ form_name - (optional) Form name to copy values from.  If not supplied, no
 
 form_action - Form action
 
+form_elements - (optional) Array reference of form fields to copy from the
+                B<form_name> form.  Field type is autodetected; currently
+                text, hidden, checkbox, and select fields are
+                supported.  Radio fields are not yet supported.
+
 form_text - (optional) Array reference of text (or hidden) form fields to copy
             from the B<form_name> form.
 
@@ -92,8 +105,8 @@ form_checkbox - (optional) Array reference of checkbox form fields to copy from
 form_radio - (optional) Array reference of radio form fields to copy from the
              B<form_name> form.
 
-form_select - (optional) Array reference of select (not select multiple) form
-              fields to copy from the B<form_name> form.
+form_select - (optional) Array reference of select form fields to copy from
+             the B<form_name> form.
 
 fixup_callback - (optional) subroutine reference, returns supplimentary
                  JavaScript for the function described above under FORMS.
@@ -130,6 +143,9 @@ sub html {
   my $between = exists($self->{html_between}) ? $self->{html_between} : '';
   my $options = $self->{options};
   my $form_action = exists($self->{form_action}) ? $self->{form_action} : '';
+
+  my $form_elements =
+    exists($self->{form_elements}) ? $self->{form_elements} : [];
   my $form_text =
     exists($self->{form_text}) ? $self->{form_text} : [];
   my $form_checkbox =
@@ -167,9 +183,9 @@ END
 
     #form fields
     $html .= <<END;
-      <FORM NAME="${key}$layer" ACTION="$form_action" METHOD=POST onSubmit="${key}fixup(this)" STYLE="margin-top: 0; margin-bottom: 0">
+      <FORM NAME="${key}$layer" ACTION="$form_action" METHOD=POST onsubmit="${key}fixup(this)" STYLE="margin-top: 0; margin-bottom: 0">
 END
-    foreach my $f ( @$form_text, @$form_checkbox, @$form_radio, @$form_select )
+    foreach my $f ( @$form_elements, @$form_text, @$form_checkbox, @$form_radio, @$form_select )
     {
       $html .= <<END;
         <INPUT TYPE="hidden" NAME="$f" VALUE="">
@@ -207,6 +223,9 @@ sub _fixup {
   my $self = shift;
   my $key = exists($self->{unique_key}) ? $self->{unique_key} : '';
   my $form_name = $self->{form_name} or return '';
+
+  my $form_elements =
+    exists($self->{form_elements}) ? $self->{form_elements} : [];
   my $form_text =
     exists($self->{form_text}) ? $self->{form_text} : [];
   my $form_checkbox =
@@ -215,13 +234,64 @@ sub _fixup {
     exists($self->{form_radio}) ? $self->{form_radio} : [];
   my $form_select =
     exists($self->{form_select}) ? $self->{form_select} : [];
-  my $html = "
+  my $html = <<END;
     <SCRIPT>
-    function ${key}fchanged(what) {
-      ${key}fixup(what.form);
+
+function copyelement(from, to) {
+  if ( from.type == undefined ) {
+    to.value = '';
+  } else if ( from.type == 'select-one' ) {
+    to.value = from.options[from.selectedIndex].value;
+    //alert(from + " (" + from.type + "): " + to.name + " => (" + from.selectedIndex + ") " + to.value);
+  } else if ( from.type == 'select-multiple' ) {
+    var i = 0;
+    var count = 0;
+    var values = new Array();
+    for (i=0;i<from.length;i++) {
+      if (from.options[i].selected){
+        values[count++] = from.options[i].value;
+      }
+    }
+    for (i=0;i<values.length-1;i++) {
+      var clone = to.cloneNode(true);
+      clone.value = values[i];
+      to.form.appendChild(clone);
     }
+    if (count > 0) {
+      to.value = values[values.length-1];
+    }else{
+      to.value = '';
+    }
+  } else if ( from.type == 'checkbox' ) {
+    if ( from.checked ) {
+      to.value = from.value;
+    } else {
+      to.value = '';
+    }
+//  } else if ( from.type == 'radio' ) {
+  } else {
+    if ( from.value == undefined ) {
+      to.value = '';
+    } else {
+      to.value = from.value;
+    }
+  }
+  //alert(from + " (" + from.type + "): " + to.name + " => " + to.value);
+}
+END
+
+  $html .= "
+    //function ${key}fchanged(what) {
+    //  ${key}fixup(what.form);
+    //}
     function ${key}fixup(what) {\n";
 
+  foreach my $f ( @$form_elements ) {
+    $html .= "copyelement( document.$form_name.elements['$f'],
+                           what.elements['$f']
+                         )\n";
+  }
+
   foreach my $f ( @$form_text ) {
     $html .= "what.$f.value = document.$form_name.$f.value;\n";
   }