in reply to Can perl do interactive forms?

JavaScript's your best bet.

Even if you want to auto check using Perl after each input, you'd still need to use something like onBlur (which is still JavaScript) to force the call to submit form (JS again).

.02

cLive ;-)

  • Comment on (cLive ;-) Re: Can perl do interactive forms?

Replies are listed 'Best First'.
Re(3): Can perl do interactive forms?
by dmmiller2k (Chaplain) on Jan 02, 2002 at 20:29 UTC

    Bad idea: submitting a form to the server using onBlur()!

    Use JavaScript for what IMHO it appears to have been intended: as glue for holding together a web page, not for simplifying CGI coding. In other words, as little as possible within a given context.

    If you're planning to do field validation at the browser (using JS), don't presume you no longer need it on the server (using Perl). What's to prevent some saavy hacker from viewing at your HTML/JS source and dummying up a URL using HTTP GET syntax? How does your (Perl) script react to unvalidated and/or clearly bad input?

    Use Javascript or don't use it. Just make sure your forms work (however crippled it makes the UI) with JS disabled.

    dmm

    You can give a man a fish and feed him for a day ...
    Or, you can
    teach him to fish and feed him for a lifetime
      I'm not suggesting you use it for form submission in the 'traditional' sense, only as a way of checking input server side on the fly.

      yes, technically the form is submitted 'onBlur', but is only 'processed' when the submit button is hit.

      If everything's OK at that point you can just return a 204 HTTP header.

      I agree, it would be a nightmare, hence my suggestion that JavaScript was the best bet. I also agree that it can't be relied on for input verification, but if you use it to verify input of a form and still verify through CGI, it would be the most efficient as far as the user experience was concerned. Here's an example of how it could work:

      #!/usr/bin/perl -w use strict; use CGI; use CGI::Carp 'fatalsToBrowser'; my $q =new CGI; # criteria for fields my %regexp = (username => '^\w+$', table_rows => '^\d{1}$', table_cols => '^\d{1}$' ); # check an input if ($q->param('check_field')) { my $input = $q->param('check_field'); check_input_ok($input); # ok, so do nothing print "Status: 204 OK\n\n"; exit(0); } # process form elsif ($q->param()) { process_form(); } # present else { show_form(); } sub check_input_ok { my $input_name = $_[0]; my $input_value = $q->param($input_name); # check input fits criteria - simple eg here if ($input_value =~ /$regexp{$input_name}/) { # input's OK # represent form if input was table_rows or table_cols, and both v +alid if ( $q->param('check_field') && $q->param('table_rows') && $q->param('table_cols') && ( ($input_name eq 'table_rows') || ($input_name eq 'table_col +s') ) ) { show_form(); } } else { # delete and re-present $q->delete($input_name); show_form("Input $input_name is invalid - please try again"); } } sub show_form { # display form # grab error, if any my $err_message = $_[0]; # reset check_field element $q->param('check_field',''); # here's the javascript my $js = <<'_END_'; function check_input(fieldname) { document.testform.check_field.value = fieldname; document.testform.submit(); } _END_ if ($err_message) { $err_message =~ s/'/\\'/; $js .= "alert('$err_message');\n"; } print $q->header(), $q->start_html(), $q->script({-language=>'JavaScript'},$js), $q->start_form(-name=>'testform'), $q->hidden('check_field'), 'Username: ', $q->textfield(-name=>'username','-onBlur',"check_input('userna +me')"), $q->br, 'Number of Rows(1-9): ', $q->textfield(-name => 'table_rows', -size => 2, -onBlur => "check_input('table_rows')" ), 'Number of Cols(1-9): ', $q->textfield(-name => 'table_cols', -size => 2, -onBlur => "check_input('table_cols')" ), $q->p(); # do we need to show a table? if ($q->param('table_rows') && $q->param('table_cols')) { # html to create table here... print $q->start_table({-border=>1}), $q->start_Tr, $q->th(); # header row for (1..$q->param('table_cols')) { print $q->th("C$_"); } print $q->end_Tr; # content for my $row (1..$q->param('table_rows')) { print $q->start_Tr, $q->th("R$row"); for (1..$q->param('table_cols')) { print $q->td("C$_ R$row"); } print $q->end_Tr; } print $q->end_table(); } # finish off form print $q->submit(-value=>'process', -onClick=>"document.testform.check_field.value = '' +;"), $q->end_form, $q->end_html; exit(0); } sub process_form { # check all fields again for (keys %regexp) { check_input_ok($_); } # everything submitted and checked, so continue print $q->header('text/plain'), 'process form here'; exit(0); } sub err { print $q->header('text/plain'), $_[0]; exit(0); }

      This is only rough code, but you get the general idea...

      cLive ;-)