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 ;-) |