cvsuser     05/10/20 13:54:44

  Added:       App-Widget/lib/App/Widget Compound.pm
  Log:
  new
  
  Revision  Changes    Path
  1.1                  p5ee/App-Widget/lib/App/Widget/Compound.pm
  
  Index: Compound.pm
  ===================================================================
  
  ######################################################################
  ## $Id: Compound.pm,v 1.1 2005/10/20 20:54:44 spadkins Exp $
  ######################################################################
  
  package App::Widget::Compound;
  $VERSION = do { my @r=(q$Revision: 1.1 $=~/\d+/g); sprintf 
"%d."."%02d"x$#r,@r};
  
  use App::Widget;
  @ISA = ( "App::Widget" );
  
  use strict;
  
  =head1 NAME
  
  App::Widget::Compound - A non-visual compound of other (presumably) visual 
widgets
  
  =head1 SYNOPSIS
  
   $conf = {
     SessionObject => {
       begin_datetime => {
         class  => "App::Widget::Compound",
         components => [ "begin_yr", "begin_mon", "begin_day", "begin_hr", 
"begin_min", "begin_sec", ],
         parse  => "^([0-9]{4})-([0-9][0-9])-([0-9][0-9]) 
([0-9][0-9]):([0-9][0-9]):([0-9][0-9])$",
         format => "%04d-%02d-%02d %02d:%02d:%02d",
       }
       end_datetime => {
         class  => "App::Widget::Compound",
         components => [ "end_yr", "end_mon", "end_day", ],
         separator  => "-",
       }
     },
   };
  
  =cut
  
  ######################################################################
  # CONSTANTS
  ######################################################################
  
  ######################################################################
  # ATTRIBUTES
  ######################################################################
  
  # INPUTS FROM THE ENVIRONMENT
  
  =head1 DESCRIPTION
  
  This class is a non-visual compound of other (presumably) visual widgets.
  However, it must be "displayed" so that event-html is created 
  (an <input type="hidden"> tag).
  
  The role of a Compound widget is to keep the joined compound value
  in sync with the split component values.  Thus, when the form is
  submitted an event is fired to join() the component values into
  the compound value. 
  
  Processing then occurs, presumably affecting
  the value of the compound widget directly.
  
  When the compound widget is "displayed" with an html() call, its
  value is split out into the component values.  This should happen
  before the component widgets are displayed or the wrong values
  will be shown.  This may be done by placing the compound widget
  higher on the page than its components or by making an explicit
  call to split() in the code.
  
  =cut
  
  ######################################################################
  # CONSTRUCTOR
  ######################################################################
  
  sub _init {
      my $self = shift;
      $self->SUPER::_init(@_);
      my $name = $self->{name};
      my $context = $self->{context};
  
      my $component_widgets = $self->{components};
      if ($component_widgets && $#$component_widgets > -1) {
          foreach my $widget (@$component_widgets) {
              $context->widget($widget);
          }
      }
  }
  
  ######################################################################
  # EVENTS
  ######################################################################
  
  # Usage: $widget->handle_event($name, $event, @args);
  sub handle_event {
      my ($self, $name, $event, @args) = @_;
  
      if ($event eq "split") {
          $self->split(@_);
          return 1;
      }
      elsif ($event eq "join") {
          $self->join(@_);
          return 1;
      }
      elsif ($event eq "change") {   # i.e. onChange
          $self->change(@_);
          return 1;
      }
      else {
          return $self->SUPER::handle_event(@_);
      }
  }
  
  sub split {
      my $self = shift;
      my $context = $self->{context};
      my $name = $self->{name};
      my $value  = $context->so_get($name);
      return if (! defined $value || $value eq "");
  
      my (@values);
  
      my $parse = $self->{parse};
      if ($parse) {
          @values = ($value =~ /$parse/);
      }
      else {
          my $sep = $self->{separator};
          $sep = "," if (!defined $sep);
          @values = split(/$sep/, $value);
      }
  
      my $component_widgets = $self->{components};
      if ($component_widgets && $#$component_widgets > -1) {
          for (my $i = 0; $i <= $#$component_widgets; $i++) {
              $context->so_set($component_widgets->[$i], undef, $values[$i]);
          }
      }
  }
  
  sub join {
      my $self = shift;
      my $context = $self->{context};
      my $name = $self->{name};
  
      my (@values, $value);
  
      my $component_widgets = $self->{components};
      if ($component_widgets && $#$component_widgets > -1) {
          for (my $i = 0; $i <= $#$component_widgets; $i++) {
              $values[$i] = $context->so_get($component_widgets->[$i]);
          }
      }
  
      my $format = $self->{format};
      if ($format) {
          $value = sprintf($format, @values);
      }
      else {
          my $sep = $self->{separator};
          $sep = "," if (!defined $sep);
          $value = join($sep, @values);
      }
  
      $context->so_set($name, undef, $value);
  }
  
  sub change {
      my $self = shift;
      $self->join();
  }
  
  ######################################################################
  # OUTPUT METHODS
  ######################################################################
  
  sub html {
      my $self = shift;
  
      $self->split();
  
      return $self->callback_event_tag("change");
  }
  
  1;
  
  
  
  

Reply via email to