A Mason component to fill-in error messages
How often have you seen those sites with a form, and after you miss a field, it pops up a little message in red under the text box indicating what went wrong? I’m guessing a lot, and when writing web applications this can be a pain to code in.
Typically in Perl/PHP, you’d add this by going through your form, adding little bits of code under each and every form element to display the error on invalid input. I quickly got tired of this, and decided to simplify the process.
% if ($form_status eq 'errors') {
<&| /lib/error_fill.mas, errors => $errors_hash_ref &>
<p style="color: red; font-weight:bold;">Errors Found: Please correct the fields indicated.
<& /forms/myform.mas, %ARGS &>
</&>
% } else {
<& /forms/myform.mas, %ARGS &>
% }
$errors_hash_ref is a hash ref that is keyed by the form field name, with the value set to the error message you want displayed. Right now, error_fill.mas does not have custom pre/post-fix variables for you to tweak how the error message is inserted. It currently puts a <br> followed by a red span element containing your message.
myform.mas is the form I want to display, I prefer to split sections out in Mason to keep my web application modular and the sections of my pages more reusable.
Here’s error_fill.mas:
<%args>
$errors
</%args>
<%init>
# $errors is a hash reference keyed as:
# 'field name' > 'Error message'
use HTML::Parser;
my $form = $m->content;
my $p = HTML::Parser->new(api_version > 3);
$p->handler(default => sub { print @_ }, "text");
$p->handler(end => sub {
my ($tagname, $text, $attr) = @_;
if (($tagname eq 'select') && (exists $errors->{$attr->{name}})) {
print $text;
print '<span style="color:red;">';
foreach my $err (@{$errors->{$attr->{name}}}) {
print '<br />'.$err;
}
print '</span>';
} else {
print $text;
}
},
"tagname, text, attr");
$p->handler(start => sub {
my ($tagname, $text, $attr) = @_;
if (($tagname eq 'input') && (exists $errors->{$attr->{name}})) {
print $text;
print '<span style="color:red;">';
foreach my $err (@{$errors->{$attr->{name}}}) {
print '<br />'.$err;
}
print '</span>';
} else {
print $text;
}
},
"tagname, text, attr");
$p->parse($form);
</%init>
Hopefully this will help some people out.





