25 April 2005
This post may be outdated due to it was written on 2005. The links may be broken. The code may be not working anymore. Leave comments if needed.

Problem

先讲讲不用 HTML::FillInForm 我们得怎么做。

举一个例子:编辑 Config ,配置文件。
比如配置文件中有一个OS选择,每次进入配置文件编辑时,为了显示原来选中的项,一般我们得用如下代码:


my $tempoutput = qq~<select name="OS">\n<option value="Win32">Win32\n<option value="FreeBSD">FreeBSD\n<option value="MacX">Mac X\n</select>\n~;
$tempoutput =~ s/value=\"$Cfg{'OS'}\"/value=\"$Cfg{'OS'}\" selected/;
print qq~请选择您使用的操作系统:$tempoutput~;
这种带 select radio checkbox 的选项都要使用正则来配置您所选中的。挺麻烦的。而且代码和HTML混在一起,看起来都不舒服。
所谓前人种树,后人乘凉。 HTML::FillInForm 能很好的解决这些问题。

Solution

已编辑个人资料为例,下面讲的只是 HTML::FillInForm 的一部分。详细的查阅 perldoc HTML::FillInForm
代码如下:

#!/usr/bin/perl
use strict;
use warnings;
use CGI qw/:cgi/;
use CGI::Carp qw(fatalsToBrowser);
use HTML::FillInForm;

my $q = new CGI;
print $q->header;

my $fif = new HTML::FillInForm;

if ($q->param('rm') eq 'edit') {
    # Validate the form data, recommend Data::FormValidator
    ##########################
    # my $Validate_Failed = 1; # for test
    ##########################
    if ($Validate_Failed) {
        my $html = &html_form('edit');
        print $fif->fill(scalarref => \$html, fobject => $q);
    } else {
        # store the profile, YAML or Config::* is a good choice
    }
} else {
    # Load the profile && convert data as
    # it can be YAML::Load
    ##########################
    # for test
    #my %profile = (
    #    'user' => 'fayland',
    #    'password' => 'unkown',
    #    'gender' => 'm',
    #    'interest' => 'Sleep',
    #    'location' => 'EU',
    #);
    ##########################
    my $html = &html_form('edit');
    print $fif->fill(scalarref => \$html,  fdat => \%profile);
}

sub html_form {
    my $rm = shift;
    return <<HTML;
<form action='http://localhost/cgi-bin/register.pl' method='post'>
<input type='hidden' name='rm' value='$rm'>
UserName: <input type='text' name='user'><br>
Password: <input type='password' name='pwd'><br>
Gender: <input type="radio" name='gender' value='m'>Male <input type="radio" name='gender' value='f'>Female <br>
Interest: <input type='checkbox' name='interest' value='Computer'>Computer <input type='checkbox' name='interest' value='Reading'>Reading <input type='checkbox' name='interest' value='Sleep'>Sleep <br>
Location:<select name='location'>
<option value='China'>China
<option value='US'>US
<option value='EU'>EU
</select><br>
<input type='submit'></form>
HTML
}
详细说明:
最主要需要说明的是 fill 参数选项:
  1. scalarref => \$html, $html 为 HTML 表单标量
  2. fobject => $q, or fobject => [$q1, $q2] 这里的 $q* 都是 CGI.pm 的一个实例。如果你不用 CGI.pm, 那 $q 必须有 param 方法。
  3. fdat => \%fdat, %fdat 是一个 Hash, 可以由 YAML 或 Config::* 等获取过来。
  4. file => 'form.tmpl', file 为一 HTML::Template 模版文件。
  5. target => 'form1', 如果 $html 或 file 里多个 form ,这个用于指定是哪个 form
  6. fill_password => 0|1, 用于指定显示不显示 type='password' 的内容
  7. ignore_fields => ['prev','next'], 指定忽略的表单项
Enjoy!


blog comments powered by Disqus