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
| [reply] [d/l] |
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 ;-) | [reply] [d/l] |