DigitalKitty has asked for the wisdom of the Perl Monks concerning the following question:

Hi all.

I am working on a perl based form validator ( very nearly completed ) but I am unable to eradicate some minor errors. In the drop-down box, if the user doesn't select a state, an error is not flagged. The other being the zip code field. I am trying to limit it to 5 digits ( no less / no more ) but it doesn't seem to work. Any suggestions would be most appreciated. Thanks,

-Caitlin.

#!/usr/bin/perl -wT use strict; use CGI; use CGI::Carp qw( fatalsToBrowser ); my $q = new CGI; my $colon = ":"; my $f_name = ""; my $f_name_error = ""; my $f_email_error = ""; my $f_mail_address = ""; my $f_mail = ""; my $f_mail_error= ""; my $f_city = ""; my $f_city_error = ""; my $f_state = ""; my $f_state_error = ""; my $f_zip = ""; my $f_zip_error = ""; my $f_share = ""; my $f_shareword = ""; my $f_email = ""; my $p_Terrors = 0; my $f_contact = ""; print "Content-type: text/html\n\n"; # If the first time the form is shown, then ... if ($q->param == 0) { &S_Show_Form(); exit(); } else { # If this is not the first time the form is shown. #1. Get the value for the control named f_name. $_ = $q->param("f_name"); s/^[\s]*//; #Remove leading blanks. s/[\s]*$//; #Remove trailng blanks. $f_name = $_; $p_Terrors = 0; #3. Check each form field for errors. if ($f_name eq "") { $f_name_error = "<font color=\"red\">Name may not be blank.</f +ont><br>\n"; $p_Terrors = $p_Terrors + 1; } $_ = $q->param("f_email"); s/^[\s]*//; #Remove leading blanks. s/[\s]*$//; #Remove trailng blanks. $f_email = $_; if ($f_email eq "") { $f_email_error = "<font color=\"red\">Email may not be bla +nk.</font><br>\n"; $p_Terrors = $p_Terrors + 1; + } + $_ = $q->param("f_mail_address"); s/^[\s]*//; #Remove leading blanks. s/[\s]*$//; #Remove trailng blanks. $f_mail_address = $_; if ($f_mail_address eq "") { $f_mail_error = "<font color=\"red\">Address may not be bl +ank.</font><br>\n"; $p_Terrors = $p_Terrors + 1; + } + $_ = $q->param("f_city"); s/^[\s]*//; #Remove leading blanks. s/[\s]*$//; #Remove trailng blanks. $f_city = $_; if ($f_city eq "") { $f_city_error = "<font color=\"red\">City may not be blank.</fo +nt><br>\n"; $p_Terrors = $p_Terrors + 1; + } $_ = $q->param("f_state"); s/^[\s]*//; #Remove leading blanks. s/[\s]*$//; #Remove trailng blanks. $f_state = $_; if ($f_state eq "") { $f_state_error = "<font color=\"red\">State may not be blank.</ +font><BR>\n"; $p_Terrors = $p_Terrors + 1; + } $_ = $q->param("f_zip"); s/^[\s]*//; #Remove leading blanks. s/[\s]*$//; #Remove trailng blanks. $f_zip = $_; unless ( $f_zip =~ /\d{5}/ ) { $f_zip_error = "<font color=\"red\">Zip code cannot be blan +k and must be 5 digits in length.</font><BR>\n"; $p_Terrors = $p_Terrors + 1; } #4. When all done checking individual form fields for errors, s +ee if the count of errors = zero. if ($p_Terrors == 0) { #No errors. Call subroutine "S_Process_Form" &S_Process_Form(); } else { #We had one or more errors, Show the form again. &S_Show_Form(); } } #End if $q == 0 exit(); #--------------- sub S_Show_Form { #--------------- print "<HTML>\n"; print "<TITLE>WEB SITE REGISTRATION</title>\n"; print "</head>\n"; print "<BODY BGCOLOR=\"cornsilk\">\n"; print "<FONT COLOR=\"cornflowerblue\"><B>\n"; print "<CENTER>\n"; print "<H1><b><FONT COLOR=\"crimson\">REGISTER WEB SITE</font></b> +</h1>\n"; print "<BR>\n"; print $q->start_form(-action => "customer.cgi", method => "get"); #The next print statment will print "" (nothing) if # there was no error in registering person's name. # Otherwise it will print the error message. print $f_name_error; print "Name: ", $q->textfield(-name=>"f_name", -size=>30), "<BR>\n +"; print $f_email_error; print "E-mail address: ", $q->textfield(-name=>"f_email", -siz +e=>30), "<BR>\n"; print "$f_mail_error"; print "Mailing address: ", $q->textfield(-name=>"f_mail_addres +s", -size=>30), "<BR>\n"; print "$f_city_error"; print "City: " . $q->textfield(-name=>"f_city", -size=>30), "<br>\ +n"; print "$f_state_error"; print "State: " . $q->popup_menu(-name=>"f_state", -value=>['P +lease select your state', 'Az', 'Ca', 'Hi'], -labels=>{'Az'=>'Arizona +', 'Ca'=>'California', 'Hi'=>'Hawaii'}), "<BR>\n"; print "$f_zip_error"; print "Zip: ", $q->textfield(-name=>"f_zip", -size => 15), "<B +R>\n"; print "Contact: ", $q->radio_group(-name=>"f_contact", -value= +>['Email', 'Postal mail'], -default=>'Email'), "<BR>\n"; print "Share with others?", $q->checkbox(-name=>'f_share', -va +lue=>'', -label=>''), "<BR>\n"; #The next two lines are sample for print the email address error ( +if any) #and the text field for the email address. print $q->submit(-value =>"Submit Information"); print "</b></font>\n"; print $q->end_form(); } #end-sub S_Show_Form #----------------- sub S_Process_Form { #----------------- #The test immediately below checks the value #of the "share/don't share" checkbox and sets #a variable named $Vshareword = "Y" or "N" --- #so that value can be written to the customer.txt file. if ($f_share eq "on") { $f_shareword = "Y"; } else { $f_shareword = "N"; } open(CUSTFILE, ">>customer.txt"); print CUSTFILE "$f_name" . "$colon" . "\n"; close(CUSTFILE); print "$f_name thank you for registering at our site.<BR>\n"; if ($f_share eq "on") { print "We appreciate you allowing us to share your information wit +h our sponsoring companies.<BR>\n"; } else { print "We acknowledge your request that your information NOT be sh +ared with others.<BR>\n"; } } #end sub ProcessForm

Replies are listed 'Best First'.
Re: Perl Form Validator problems.
by vladb (Vicar) on Apr 27, 2002 at 04:11 UTC
    I suggest you look at a readily available module that would allow you to do what you want and probably even more. The module is HTML::FormValidator.

    I remember using it once or twice in a few of my projects and as far as I can tell it's the right answer to these kind of problems.

    You simply built form validation rules (or constraints) like this:
    my $validation_rules = { customer_infos => { optional => [ qw( company fax country ) ], required => [ qw( fullname phone email address city state zipcode ) ], constraints => { email => "email", fax => "american_phone", phone => "american_phone", zipcode => '/^\s*\d{5}(?:[-]\d{4})?\s*$/', state => "state", }, defaults => { country => "USA", }, } };
    I believe hash keys are form names (top keys) and form element names. So, the zip code match is already there for you ;-). I suggest you read the docs for better info.

    "There is no system but GNU, and Linux is one of its kernels." -- Confession of Faith
Re: Perl Form Validator problems.
by DaWolf (Curate) on Apr 27, 2002 at 06:18 UTC
    Hey there.

    You could do it like this.

    If your check is just about noticing that the zip code is 5 chars, use length:
    unless ( length $f_zip == 5 ) { $f_zip_error = "<font color=\"red\">Zip code cannot be blan +k and must be 5 digits in length.</font><BR>\n"; $p_Terrors = $p_Terrors + 1; }
    For the state part, in drop-down cases I always do it like this:

    - The first option is null like:
    <option value="null">Select the state</option> - So your code change into this:
    if ($f_state eq "null") { $f_state_error = "<font color=\"red\">State may not be blank.</ +font><BR>\n"; $p_Terrors = $p_Terrors + 1; + } ...
    Hint: Since it's a drop-down box, it will always return a value, so you can't use something like:
    if (! defined $f_state) { ...
    or
    if ($f_state eq "") { ...
    Hope it helps.

    my ($author_nickname, $author_email) = ("DaWolf","erabbott\@terra.com.br") if ($author_name eq "Er Galvão Abbott");
      Hint: Since it's a drop-down box, it will always return a value,...
      Not necessarily. Nothing prevents a malicious or a lousy client from submitting bad data. Nothing prevents your program from accepting it except your paranoia.
      Hi.

      I tried ( in vain ) to check for a null value in the popup box. It still didn't flag it as an empty field ( and therefore display the message ). Sorry if my question seems naive but this is my first program that uses Dr. Stein's CGI.pm module. Do you ( or anyone else ) have another suggestion?
      Thanks for all the help by the way.

      -Cait.
        Please post the code that checks the drop-down box and the html code of the box.

        I'll help you from there.

        Best regards,

        my ($author_nickname, $author_email) = ("DaWolf","erabbott\@terra.com.br") if ($author_name eq "Er Galvão Abbott");
A reply falls below the community's threshold of quality. You may see it by logging in.