Embperl
view release on metacpan or search on metacpan
Embperl/Form.pm view on Meta::CPAN
###################################################################################
#
# Embperl - Copyright (c) 1997-2008 Gerald Richter / ecos gmbh www.ecos.de
# Embperl - Copyright (c) 2008-2015 Gerald Richter
# Embperl - Copyright (c) 2015-2023 actevy.io
#
# You may distribute under the terms of either the GNU General Public
# License or the Artistic License, as specified in the Perl README file.
#
# THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
###################################################################################
package Embperl::Form ;
use strict ;
use lib qw{..} ;
use Embperl ;
use Embperl::Form::Control ;
use Embperl::Form::Validate ;
use Embperl::Form::Control::blank ;
use Embperl::Inline ;
use Data::Dumper ;
use Storable ;
use MIME::Base64 ;
use Scalar::Util qw{weaken} ;
our %forms ;
our $form_cnt = 1 ;
our %CLEANUP = ('forms' => 0) ;
use vars qw{$epreq} ;
# ---------------------------------------------------------------------------
#
# sub_new - create a new sub form
#
sub sub_new
{
my ($class, $controls, $options, $id, $toplevel, $parentptr) = @_ ;
$id ||= 'topdiv' ;
$options ||= {} ;
$toplevel = 1 if (!defined ($toplevel)) ;
my $self = ref $class?$class:{} ;
$self -> {controls} = $controls ;
$self -> {options} = $options ;
$self -> {id} = $id ;
$self -> {parentptr} = $parentptr ;
$self -> {formname} = $options -> {formname} || 'topform' ;
$self -> {bottom_code} = [] ;
$self -> {validate_rules} = [] ;
$self -> {toplevel} = $toplevel ;
$self -> {checkitems} = $options -> {checkitems} ;
$self -> {valign} = $options -> {valign} || 'top' ;
$self -> {jsnamespace} = $options -> {jsnamespace} || '' ;
$self -> {jsnamespace} .= '.' if ($self -> {jsnamespace}) ;
$self -> {disable} = $options -> {disable} ;
$self -> {control_packages} = $options -> {control_packages} ;
$self -> {datasrc_packages} = $options -> {datasrc_packages} ;
$self -> {formptr} = ($options -> {formptr} || "$self") . '/' . $id ;
bless $self, $class if (!ref $class);
# The following lines needs to there twice!
# some weired bug in Perl?
$Embperl::FormData::forms{$self -> {formptr}} = $self ;
weaken($Embperl::FormData::forms{$self -> {formptr}});
#$Embperl::FormData::forms{$self -> {formptr}} = $self ;
if ($toplevel)
{
$self -> {fields2empty} = [] ;
$self -> {init_data} = [] ;
$self -> {init_markup} = [] ;
$self -> {prepare_fdat} = [] ;
$self -> {code_refs} = [] ;
$self -> {constrain_attrs} = [] ;
$self -> {do_validate} = [] ;
$self -> {all_controls} = {} ;
}
else
{
$self -> {fields2empty} = $self -> parent_form -> {fields2empty} ;
$self -> {init_data} = $self -> parent_form -> {init_data} ;
$self -> {init_markup} = $self -> parent_form -> {init_markup} ;
$self -> {prepare_fdat} = $self -> parent_form -> {prepare_fdat} ;
$self -> {constrain_attrs} = $self -> parent_form -> {constrain_attrs} ;
$self -> {code_refs} = $self -> parent_form -> {code_refs} ;
$self -> {do_validate} = $self -> parent_form -> {do_validate} ;
$self -> {all_controls} = $self -> parent_form -> {all_controls} ;
}
if ($self -> has_code_refs)
{
push @{$self -> {code_refs}}, $self ;
weaken ($self -> {code_refs}[-1]) ;
}
$self -> new_controls ($controls, $options, undef, $id, $options -> {masks}, $options -> {defaults}) ;
$self -> {noframe} = 1 if ($controls && @$controls > 0 &&
$controls -> [0] -> noframe) ;
return $self ;
}
# ---------------------------------------------------------------------------
#
# new - create a new form
#
sub new
{
my $class = shift ;
return $class -> sub_new (@_) ;
}
# ---------------------------------------------------------------------------
#
# clone - clone an existing form. trivial new here, maybe more complex for kids
# This will always return a Embperl::Form, no matter what $self is
sub cloned_form
{
my $self = shift ;
return Embperl::Form -> sub_new (@_) ;
}
# ---------------------------------------------------------------------------
#
# DESTROY
#
sub DESTROY
{
my ($self) = @_ ;
delete $Embperl::FormData::forms{$self -> {formptr}} ;
}
# ---------------------------------------------------------------------------
#
# get_control_packages
#
# returns an array ref with packges where to search for control classes
#
sub get_control_packages
{
my ($self) = @_ ;
return $self -> {control_packages} || ['Embperl::Form::Control'] ;
}
# ---------------------------------------------------------------------------
#
Embperl/Form.pm view on Meta::CPAN
#
sub new_controls
{
my ($self, $controls, $options, $id, $formid, $masks, $defaults, $no_init) = @_ ;
my $n = 0 ;
my $packages = $self -> get_control_packages ;
foreach my $control (@$controls)
{
die "control definition must be a hashref or an object, is '$control' " if (!ref $control || ref $control eq 'ARRAY');
my $ctlid = $control->{name} ;
my $q = 2 ;
while (exists $self -> {controlids}{$ctlid})
{
$ctlid = $control->{name} . '_' . $q ;
$q++ ;
}
my $name = $control -> {name} ;
$control -> {type} =~ s/sf_select.+/select/ ;
$control -> {type} ||= ($control -> {name}?'input':'blank') ;
$control -> {parentid} = $id if ($id) ;
$control -> {id} ||= $ctlid ;
$control -> {basename}||= $control->{name} ;
$control -> {formid} = $formid ;
$control -> {formptr} = $self -> {formptr} ;
my $type = $control -> {type} ;
my $default = $defaults -> {$name} || $defaults -> {"*$type"} || $defaults -> {'*'};
my $mask = $masks -> {$name} || $masks -> {"*$type"} || $masks -> {'*'};
if ($mask)
{
foreach (keys %$mask)
{
$control -> {$_} = $mask -> {$_} ;
}
}
if ($default)
{
foreach (keys %$default)
{
$control -> {$_} = $default -> {$_} if (!exists $control -> {$_}) ;
}
}
if (ref $control eq 'HASH')
{
my $type = $control -> {type} ;
$control = $self -> new_object ($packages, $type, $control) ;
if (!$no_init)
{
if ($control -> can ('init_data'))
{
push @{$self -> {init_data}}, $control ;
weaken ($self -> {init_data}[-1]) ;
}
if ($control -> can ('init_markup'))
{
push @{$self -> {init_markup}}, $control ;
weaken ($self -> {init_markup}[-1]) ;
}
if ($control -> can ('prepare_fdat'))
{
push @{$self -> {prepare_fdat}}, $control ;
weaken ($self -> {prepare_fdat}[-1]) ;
}
if ($control -> has_code_refs)
{
push @{$self -> {code_refs}}, $control ;
weaken ($self -> {code_refs}[-1]) ;
}
if ($control -> has_validate_rules)
{
push @{$self -> {do_validate}}, $control ;
weaken ($self -> {do_validate}[-1]) ;
}
push @{$self -> {constrain_attrs}}, $control -> constrain_attrs ;
$self -> {all_controls}{$name} = $control ;
weaken ($self -> {all_controls}{$name}) ;
}
}
$self -> {controlids}{$control->{id}} = $control ;
next if ($control -> is_disabled ()) ;
if ($control -> {sublines})
{
my $i = 0 ;
my $name = $control -> {name} ;
foreach my $subcontrols (@{$control -> {sublines}})
{
next if (!$subcontrols) ;
$self -> new_controls ($subcontrols, $options, "$name-$i", $formid, $masks, $defaults, $no_init) ;
$i++ ;
}
}
if ($control -> {subforms})
{
my @obj ;
my @ids ;
my $i = 0 ;
foreach my $subcontrols (@{$control -> {subforms}})
{
next if (!$subcontrols) ;
my $ctlid = $control -> {values}[$i] || $control->{name} ;
my $q = 2 ;
while (exists $self -> {controlids}{$ctlid})
{
$ctlid = $control->{name} . '_' . $q ;
$q++ ;
}
my $class = ref $self ;
local $options -> {disable} = $control -> {disables}[$i] ;
my $subform = $class -> sub_new ($subcontrols, $options, $ctlid, 0, $self -> {formptr}) ;
$subform -> {text} ||= $control -> {options}[$i] if (exists ($control -> {options}) && $control -> {options}[$i]) ;
$subform -> {parent_control} = $control ;
weaken ($subform -> {parent_control}) ;
push @ids, $ctlid ;
push @obj, $subform ;
$i++ ;
}
$control -> {subobjects} = \@obj ;
$control -> {subids} = \@ids ;
}
$n++ ;
}
}
# ---------------------------------------------------------------------------
#
# parent_form - return parent form object if any
#
sub parent_form
{
my ($self) = @_ ;
return $Embperl::FormData::forms{$self -> {parentptr}} ;
}
# ---------------------------------------------------------------------------
#
# add_code_at_bottom - add js code at the bottom of the page
#
sub add_code_at_bottom
{
my ($self, $code) = @_ ;
push @{$self->{bottom_code}}, $code ;
}
# ---------------------------------------------------------------------------
#
# layout - build the layout of the form
#
sub layout
{
my ($self, $controls, $level) = @_ ;
$controls ||= $self -> {controls} ;
$level ||= 1 ;
my $hidden = $self -> {hidden} ||= [] ;
my $x = 0 ;
my $max_x = 100 ;
my $line = [] ;
my @lines ;
my $max_num = 0 ;
my $num = 0 ;
( run in 2.580 seconds using v1.01-cache-2.11-cpan-75ffa21a3d4 )