Chinaunix首页 | 论坛 | 博客
  • 博客访问: 395633
  • 博文数量: 69
  • 博客积分: 1984
  • 博客等级: 上尉
  • 技术积分: 953
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-28 00:43
个人简介

学无所长,一事无成

文章分类

全部博文(69)

文章存档

2015年(19)

2014年(14)

2013年(9)

2012年(17)

2010年(10)

我的朋友

分类:

2010-08-28 11:30:29

Catalyst::Manual::Tutorial::09_AdvancedCRUD
学习笔记 (2010-8-28 星期六) -- 高阶 CRUD
 
文章来源:
 
 
......

可用的高阶 CRUD 


Catalyst::Manual::Tutorial::09_AdvancedCRUD::09_FormFu 学习

本节内容来自:

概述 

本节探索 ,用于管理表单,输入校验,通过数据库保存及回复数据。本章基于 HTML::FormFu 版本 0.05001。

HTML::FormFu 表单创建

Catalyst::Controller::HTML::FormFu 继承

首先, 修改文件 lib/MyApp/Controller/Books.pm ,改变继承关系,将如下:

BEGIN {extends 'Catalyst::Controller'; }

修改为: 

BEGIN {extends 'Catalyst::Controller::HTML::FormFu'; }

记得修改 Makefile.PL :

requires 'Catalyst::Controller::HTML::FormFu';

添加 Action 用于显示和保存表单

编辑文件 lib/MyApp/Controller/Books.pm

sub formfu_create :Chained('base') :PathPart('formfu_create') :Args(0) :FormConfig {
    my ($self, $c) = @_;
    my $form = $c->stash->{form};
    if ($form->submitted_and_valid) {
        # 创建一本书
        my $book = $c->model('DB::Book')->new_result({});
        # 保存表单中该书信息
        $form->model->update($book);
        # 为用户设置一条状态信息
        $c->flash->{status_msg} = 'Book created';
        # 返回书目列表页面
        $c->response->redirect($c->uri_for($self->action_for('list')));
        $c->detach;
    } else {
        # 从数据库获取作者信息
        my @author_objs = $c->model("DB::Author")->all();
        # 创建一个数组或数组引用,每个元素指向一个作者
        my @authors;
        foreach (sort {$a->last_name cmp $b->last_name} @author_objs) {
            push(@authors, [$_->id, $_->last_name]);
        }
        # 从配置文件获取需要添加选择项的元素
        my $select = $form->get_element({type => 'Select'});
        # 将作者添加进去
        $select->options(\@authors);
    }    
    # 设置模板
    $c->stash(template => 'books/formfu_create.tt2');
}

编写一个表单配置文件(Config File)

尽管 HTML::FormFu 支持  能识别的任意格式,但大多数人倾向于 YAML 格式。首先创建一个目录用于保存你的表单配置文件:

mkdir -p root/forms/books

创建文件 root/forms/books/formfu_create.yml : 

---
# indicator is the field that is used to test for form submission
indicator: submit
# Start listing the form elements
elements:
    # The first element will be a text field for the title
    - type: Text
      name: title
      label: Title
      # This is an optional 'mouse over' title pop-up
      attributes:
        title: Enter a book title here
    # Another text field for the numeric rating
    - type: Text
      name: rating
      label: Rating
      attributes:
        title: Enter a rating between 1 and 5 here

    # Add a drop-down list for the author selection. Note that we will
    # dynamically fill in all the authors from the controller but we
    # could manually set items in the drop-list by adding this YAML code:
    # options:
    # - [ '1', 'Bastien' ]
    # - [ '2', 'Nasseh' ]
    - type: Select
      name: authors
      label: Author
    # The submit button
    - type: Submit
      name: submit
      value: Submit

注意: 从 perl 文档格式复制粘贴 YAML 文件比较麻烦。参考本章  这一小节,介绍了一个绝不会出错的配置文件格式。

更新 CSS 文件

编辑 root/static/css/main.css ,文件末尾添加:

...
input {
    display: block;
}
select {
    display: block;
}
.submit {
    padding-top: .5em;
    display: block;
}

这些设置用于垂直排列显示表单元素。注意现存的 .error 类的定义关联到色彩方案设置,这个设置是由 TTSite helper 生成的 root/lib/config/col 文件定义的。这样就有一个切入点可以控制 CSS 色彩设定。

创建一个模板页面用于显示表单:

编辑文件 root/src/books/formfu_create.tt2  :

[% META title = 'Create/Update Book' %]
[%# Render the HTML::FormFu Form %]
[% form %]
<p><a href="[% c.uri_for(c.controller.action_for('list'))
    %]"
>Return to book list</a></p>

创建一个链接 for Create and Update via HTML::FormFu

编辑 root/src/books/list.tt2 ,在文件底部添加:

...
<p>
  HTML::FormFu:
  <a href="[% c.uri_for(c.controller.action_for('formfu_create')) %]">Create</a>
</p>

这样就在书目列表页面底部添加了一个新的链接,可以通过这个链接调用基于 HTML::FormFu 的表单。

测试 HTML::FormFu 添加书目的表单

使用 -r 参数启动服务:

$ script/myapp_server.pl -r

以用户 test01(密码:mypass)登录。进入书目列表页面后,点击表单底部的  HTML::FormFu "Create" 链接,输入以下内容:

Title: Internetworking with TCP/IP Vol. II
Rating: 4
Author: Comer


点击提交按钮,然后返回到书目列表页面,你会看到 "Book created" 状态信息。

以上实现方式允许你输入任何乱七八糟的数据。尽管说我们通过下拉选择列表对作者一栏的录入进行了约束(其实对于侵略性的用户,依然可以通过"hacking"手段录入任何数值,这个防护并不严密),但是对于其他栏目并没有限制,比如标题栏没有限定长度(你甚至可以录入只有一个字母的书目),投票栏也没有限定类型(你可以输入数字,也可以输入非数字字符)。接下来的章节我们进行讨论。

注意: 依赖于你所使用的数据库,以及表中所建立的字段,数据库提供了一种直观的不同水平层级的数据 "类型约束"。前面章节一再强调了一个重要观点,web 应用程序本身不能进行任何数据校验。 

HTML::FormFu 数据校验及过滤

虽说前面部分的 的示例演示了一种很好的自动创建表单的机制,但是这个模块的真正威力在于对用户输入数据的自动校验及过滤。校验约束可以保证用户输入适当的数据(比如说表单的 email 一栏就需要合法的 email 地址)。过滤机制可以滤掉输入信息中的空白字符,或者对元字符进行转义处理。

Add Constraints

编辑 root/forms/books/formfu_create.yml

---
# indicator 域是用来测试表单提交
indicator: submit
# 列出表单所有元素
elements:
    # 第一个元素是文本类型的 title 域
    - type: Text
      name: title
      label: Title
      # 此项可选,定义鼠标滑过时的 title 提示信息
      attributes:
        title: Enter a book title here
      # 添加此域的约束
      constraints:
        # 定义长度必须为 5-40 个字符
        - type: Length
          min: 5
          max: 40
          # 重新定义无效输入时的提示信息
          message: Length must be between 5 and 40 characters
    # 定义一个文本域,用于输入 rating 数字
    - type: Text
      name: rating
      label: Rating
      attributes:
        title: Enter a rating between 1 and 5 here
      # Use Filter to clean up the input data
      # Could use 'NonNumeric' below, but since Filters apply *before*
      # constraints, it would conflict with the 'Integer' constraint below.
      # So let's skip this and just use the constraint.
      #filter:
        # Remove everything except digits
        #- NonNumeric
      # Add constraints to the field
      constraints:
        # 确保输入为一个数字
        - type: Integer
          message: "Required. Digits only, please."
        # 检查最大、最小值
        - type: Range
          min: 1
          max: 5
          message: "Must be between 1 and 5."
    # 这里设定 author 选择列表,由于我们从 controller 直接获取 authors 列表添加进来
    # 因此就不用手工添加如下 YAML 代码:
    # options:
    # - [ '1', 'Bastien' ]
    # - [ '2', 'Nasseh' ]
    - type: Select
      name: authors
      label: Author

      # Convert the drop-down to a multi-select list


      multiple: 1
      # Display 3 entries (user can scroll to see others)
      size: 3
      # One could argue we don't need to do filters or constraints for
      # a select list, but it's smart to do validation and sanity
      # checks on this data in case a user "hacks" the input
      # Add constraints to the field
      constraints:
        # Make sure it's a number
        - Integer

    # The submit button
    - type: Submit
      name: submit
      value: Submit

# Global filters and constraints.
constraints:
  # The user cannot leave any fields blank
  - Required
  # If not all fields are required, move the Required constraint to the
  # fields that are
filter:
  # Remove whitespace at both ends
  - TrimEdges
  # Escape HTML characters for safety
  - HTMLEscape

 
狗日的服务器,本来这章还有   都写完了,编辑好的一大段文字都凭空消失了,不写了。
 
。。。。
阅读(1277) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~