http://qs1969.pair.com?node_id=363793

Diff for my enhancement to Data::FormValidator (v1.7), which adds the ability to define required alternates. In other words, it makes sure that at least one of a list of alternate fields has a value.
23c23 < package Data::FormValidator; --- > package Data::FormValidator::Enhanced; 463a464,472 > #!################################################################## +## > my %alternates; > # get list of alternates > while ( my ( $field, $deps) = each %{$profile->{alternates}} ) { > foreach my $dep (_arrayify($deps)){ > $alternates{$dep} = 1; > } > } > #################################################################### +## 519a529 > #!################################################################## +## 522c532 < grep { not (exists $optional{$_} or exists $required{$_} ) } k +eys %valid; --- > grep { not (exists $optional{$_} or exists $required{$_} or ex +ists $alternates{$_} ) } keys %valid; 526a537 > #################################################################### +## 536a548,558 > > #!################################################################## +## > # Check for the absence of alternate fields > while ( my ( $field, $deps) = each %{$profile->{alternates}} ) { > my $valid_alternate = 0; > foreach my $dep (_arrayify($deps)){ > $valid_alternate = 1 if exists $valid{$dep}; > } > push @missings, $field unless $valid_alternate; > } > #################################################################### +##
Usage:
#!/usr/bin/perl -w use strict; use Data::FormValidator::Enhanced; my $validator_profile = { 'contact' => { required => [], optional => [], alternates => { zip_or_postal => [ qw( zip postal ) ], }, constraints => { zip => "zip", postal => "post_code", }, filters => [ "trim" ], }, }; my $validator = Data::FormValidator::Enhanced->new($validator_profile) +; my %param = ( zip => '', postal => '',); my %error; ($error{valid}, $error{missing}, $error{invalid}, $error{unknown}) = $validator->validate(\%param, 'contact'); my $errortext = ''; $errortext .= "The following required fields were not completed: \n" . join("\n", @{$error{missing}}) . "\n"; $errortext .= "The following fields were not completed correctly: \n" +. join("\n", @{$error{invalid}}) . "\n"; print $errortext;

Template-Toolkit version(s) of jeffa's HTML::Template code from this node.
The first version uses TT2's more verbose way of referencing variables; the second uses the shorthand way (more like jeffa's code).
use strict; use CGI qw(header); use Template; my $data = do {local $/; <DATA>}; my $template = Template->new(); my $params = { questions => [ { question => 'What is your favorite number?', radio => [ { regular => 'question01', value => 'a', label => 5, }, { regular => 'question01', value => 'b', label => 7, }, { regular => 'question01', value => 'c', label => 13, }, { special => 'question01', value => 'd', label => 'Other', text => 'other', }, ], }, { question => 'Where did you hear about this product?', radio => [ { regular => 'question02', value => 'a', label => 'Friend', }, { special => 'question02', value => 'b', label => 'Magazine', text => 'magname', }, { regular => 'question02', value => 'c', label => 'Brochure', }, { special => 'question02', value => 'd', label => 'Other', text => 'other', }, ], }, ], }; print header; $template->process(\$data, $params) or die $!; __DATA__ <form> [% FOR q = questions %] <p> [% q.question %]<br> [% FOR r = q.radio %] [% UNLESS r.special %] <input type="radio" name="[% r.regular %]" value="[% r.value % +]">[% r.label %]<br> [% ELSE %] <input type="radio" name="[% r.special %]" value="[% r.value%] +"/>[% r.label%] (please specify:) <input type="text" name="[% r.text %]"/><br/> [% END %] [% END %] [% END %] <input type="submit"> </form>

use strict; use CGI qw(header); use Template; my $data = do {local $/; <DATA>}; my $template = Template->new(); my $params = { questions => [ { question => 'What is your favorite number?', radio => [ { regular => 'question01', value => 'a', label => 5, }, { regular => 'question01', value => 'b', label => 7, }, { regular => 'question01', value => 'c', label => 13, }, { special => 'question01', value => 'd', label => 'Other', text => 'other', }, ], }, { question => 'Where did you hear about this product?', radio => [ { regular => 'question02', value => 'a', label => 'Friend', }, { special => 'question02', value => 'b', label => 'Magazine', text => 'magname', }, { regular => 'question02', value => 'c', label => 'Brochure', }, { special => 'question02', value => 'd', label => 'Other', text => 'other', }, ], }, ], }; print header; $template->process(\$data, $params) or die $!; __DATA__ <form> [% FOR questions %] <p> [% question %]<br> [% FOR radio %] [% UNLESS special %] <input type="radio" name="[% regular %]" value="[% value %]">[ +% label %]<br> [% ELSE %] <input type="radio" name="[% special %]" value="[% value%]"/>[ +% label%] (please specify:) <input type="text" name="[% text %]"/><br/> [% END %] [% END %] [% END %] <input type="submit"> </form>

My extended Personal Nodelet :-)

Re: comparing two hashes
The SSSCA considered harmful
Re: How to flatten an x-dimensional array?
Idiomatic Array Index Search?
Re: OO - problem with inheritance
Re: Preventing autovivification of object attributes
Re: need nextline() sub
Re: Closing and re-opening the DATA Filehandle
Re: How to use PPM (WIN32)...
Re: ?PPD?
Re: How to Calculate Memory Needs?
Web Application Frameworks and their Templating Engines with a Comparative Study of Template and HTML::Template
RE: Making Apache Sessions
How do I find the index of a specific array value?
Re: How to 'peek' at next line while parsing with <>
Re: OOP: Plugin Style Development
Re: Comparing Arrays -> storing results in a third Array
Perl IDEs and Editors update
Tie::Array::Iterable
Update HTML Doc
Re: SQL Server freeTDS walkthrough?
Re: Re: Re: When to use Java?
Re: escaping anallowed chars for browser
Persistency issues with tied hashes
Re: stopping my spamming
Framework.pm 0.02
'our' is not 'my'
Iterate over HoH without Recursion
DBI recipes