让我们使用 fuelphp 的 fieldset 来快速、优雅且广泛地批量生成输入表单。

大家好,
我是开发团队的Mandai,来自Wild Team。
我们公司经常使用
FuelPHP在本文中,我想分享一下Fieldset的精髓。
我们测试的FuelPHP版本是1.7.2。

 

什么是字段集?

我认为 fieldset 是 FuelPHP 中快速开发的典范,但令人惊讶的是,深入探讨它的日文文章却寥寥无几。
很多文章只是简单地说“我试用了一下”。fieldset
是一种机制,它基于模型中定义的信息,通过一个方法创建一个表单。
如果你使用的是基于标准 Twitter Bootstrap 的 Web 应用程序,
那么在忽略一些细节的情况下,你无需编写任何 HTML 代码即可输出表单。

一旦你仔细编写好模型,就可以让 fieldset 接管并一次性创建所有内容,所以如果你
有很多输入屏幕,并且可能要错过末班车一段时间,请考虑一下,并抽出一些时间陪伴家人。

 

那么,让我们来编写一个模型吧。

使用字段集时,生成表单所需的所有信息都存储在 `$_pr​​operties` 中。
您可以在此处编写输入类型和验证规则,从而集中管理表单信息。
例如,我们创建一个 `Model_Book` 类,该类使用一个假定为图书注册页面的模型。

书桌的样子是这样的:

CREATE TABLE `books` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `title` varchar(512) NOT NULL, `author` varchar(256) NOT NULL, `price` int(10) unsigned NOT NULL, `isbn` varchar(13) DEFAULT '', `released_at` date DEFAULT '0000-00-00', `type` tinyint(2) DEFAULT NULL, `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 
请按如下方式定义此书籍表的模型:

<?php // fuel/app/classes/model/book.php class Model_Book extends \Model\Orm { protected static $_connection = 'default'; protected static $_table_name = 'books'; protected static $_properties = [ 'id', 'title' => [ 'data_type' => 'varchar', 'label' => 'title', 'validation' => [ 'required', 'max_length' => [512], ], 'form' => [ 'type' => 'text', 'class' => 'form-control', ], ], 'author' => [ 'data_type' => 'varchar', 'label' => 'author', 'validation' => [ 'required', 'max_length' => [512], ], 'form' => [ 'type' => 'text', 'class' => 'form-control', ], ], 'price' => [ 'data_type' => 'int', 'label' => 'price', 'validation' => [ 'required', 'numeric_min' => [0], ], 'form' => [ 'type' => 'number', 'class' => 'form-control', 'min' => 0, ], ], 'isbn' => [ 'data_type' => 'varchar', 'label' => 'ISBN', 'validation' => [ 'match_pattern' => ['/^[0-9]{10}([0-9]{3})?$/'], ], 'form' => [ 'type' => 'text', 'class' => 'form-control', ], ], 'released_at' => [ 'data_type' => 'date', 'label' => 'issue date', 'validation' => [ 'valid_date' => [], ], 'form' => [ 'type' => 'text', 'class' => 'form-control datepicker', ], ], 'type' => [ 'date_type' => 'tinyint', 'label' => 'format', 'validation' => [ 'numeric_min' => [0], ], 'form' => [ 'type' => 'select', 'class' => 'form-control', 'options' => [ 0 => '未知', 1 => 'A4 尺寸', 2 => 'A5 尺寸', 3 => 'A6 尺寸', 4 => 'B4 尺寸', 5 => 'B5 尺寸', 6 => 'B6 尺寸', 7 => '小 B6 尺寸', 8 => '菊本尺寸', 9 => '国际尺寸', 10 => 'AB 尺寸', 11 => '重箱版', 12 => '菊尺寸', 13 => '四目尺寸', 14 => 'B40 尺寸', 15 => '袖珍书version', 16 => 'Sango size', 17 => 'Ochiori size', 18 => 'HL size', ], ], ], 'created_at' => [ 'form' => ['type' => false], ], 'updated_at' => [ 'form' => ['type' => false], ], ]; protected static $_observers = [ 'Orm\Observer_CreatedAt' => [ 'events' => ['before_insert'], 'mysql_timestamp' => true, ], 'Orm\Observer_UpdatedAt' => [ 'events' => ['before_update'], 'mysql_timestamp' => true, ], ]; }


 这样就包含了大部分必要信息。
这些信息非常简洁,可以写成结构化数组,这样既能减少错误,也
便于后续修正。
标准的验证规则FuelPHP 文档的“验证 - 类 - FuelPHP”部分,请务必遵循这些规则。

表单创建信息写在每个字段的“form”键下。
“Type”对应于输入标签的type属性,其用法与常用的text、select、hidden、checkbox、radio等标签(包括textarea标签)相同。
对于type="select"、type="checkbox"和type="radio",您可以通过在“options”下编写数组来定义固定值。

此外,如果该值不是固定的,您可以按如下方式在控制器的选项中设置数据。

$form = \Fieldset::forge('default', [ 'form_attributes' => ['class' => 'form-horizo​​ntal'] ])->add_model('Model_Book'); $newspaper_types = [ 19 => 'Broadsheet', 20 => 'Nordic', 21 => 'Rhenish', 22 => 'Swiss (NZZ)', 23 => 'Berliner', 24 => 'Tabloid Extra', 25 => 'Half Swiss', 26 => 'Half Berliner', 27 => 'Half Rhenish', 28 => 'Half Broadsheet', 29 => 'Tabloid', ]; // 添加字段 $form->field('type')->set_options($newspaper_types); // 要替换字段 $form->field('type')->set_options($newspaper_types, null, true);


 如果将 `set_options` 方法的第三个参数设置为 `true`,则数组将被覆盖而不会合并。
目前,您只需在模型端输入未选择的值,如有其他可能的值,再进行添加。

你可以使用 `$form->field('type')` 直接操作表单元素,只要记住这个格式,
即使你只想在特定情况下稍微修改表达式,也可以在控制器中进行控制。
可以与 `$form->field('type')` 关联并以各种方式操作的方法位于 `fuel/core/classes/fieldset/field.php` 文件中。
查看这些方法,你应该能够找到适合你需求的方法。

 

创建一个包含单个方法的表单

模型定义完成后,剩下的就是在控制器中进行一些微调并生成 HTML。
我所说的“微调”是指,如果不做任何操作,表单将默认创建,但不会包含提交按钮。
你可能会想,“既然是表单,提交按钮当然必不可少”,但我认为这是
FuelPHP 特有的,它与 CakePHP 的设计理念不同,不会进行不必要的干预。

$form->add('submit', ' ', ['type'=>'submit', 'class'=>'btn btn-primary submit', 'value' => 'registration']);

 
不过,既然内容就这些,你基本上可以直接复制粘贴。

最后,将表单的 HTML 代码传递给视图。
如果你的控制器继承自 Controller_Template,只需按照以下步骤创建视图,并将构建表单的方法的输出传递给它即可。

$this->template->content = View::forge('manager/master/form.php', $this->contents); $this->template->content->set_safe('form', $form->build());


 FuelPHP 会自动转义传递给视图的字符串。
然而,`set_safe` 方法用于将第二个参数中的信息直接传递给视图,而不进行转义。
出于安全考虑,这样做可能不太好,但目前似乎没有其他更好的方法,所以我只能这样使用。

 

我想创建一个能够完美应用 Bootstrap 的表单。

我之前写过,如果忽略一些细节,你可以创建一个更好的表单,
但人总是希望它看起来美观,这是人之常情,对吧?
默认情况下,表单会显示一个表格,其中包含标签和输入元素,但你可以
通过修改模板来控制这种显示方式。

默认模板是 fuel/core/config/form.php,所以将此文件复制到 app/config/ 并进行修改。

例如,以下是一个修改后的模板配置文件示例,用于应用水平表单

<?php // fuel/app/config/form.php return [ 'form_template' =>"\n\t\t{打开}\n{字段}\n\t\t{关闭}\n", 'field_template' => "\t\t<div class=\"form-group\"> \n\t\t\t{标签}\n\t\t\t<div class=\"col-xs-3 {error_class}\"> {字段} <span>{描述}</span> {错误消息}</div> \n\t\t</div> \n", 'multi_field_template' => "\t\t<div class=\"form-group\"> \n\t\t\t <label class=\"col-xs-2 control-label\">{group_label}{必填}</label> \n\t\t\t<div class=\"col-xs-3 {error_class}\"> {字段}\n\t\t\t\t<div> {字段} {标签}</div> {字段} <span>{描述}</span> \t\t\t{错误信息}\n\t\t\t</div> \n\t\t</div> \n", 'label_class' => 'col-xs-2 control-label', 'group_label' => '{label}', ];


 这种格式比较难懂,混用了 \t 和 \n,但它与屏幕显示无关,所以省略它也没问题。只是会让 HTML 源代码稍微难读一些。
另外,默认的 core/config/form.php 文件中有一些 app/config/form.php 文件中没有的条目,但这些条目会被合并,并且会使用默认设置,所以不会有问题。

您也可以毫无问题地使用基于 Twitter bootstrap 的AdminLTE

 

实际可以减少多少劳动力成本?

首先,作为前提条件,数据库设计必须(在一定程度上)完成,这一点从模型信息集中化的角度来看显而易见。
使用字段集创建屏幕时,无法在进行数据库设计的同时推进实现,因此应首先专注于完成数据库设计。

此外,如果你在研究字段集机制和最佳实践的同时继续学习,虽然一开始会花费一些钱,但因为你经过了深思熟虑,所以在后半段你上手的速度会快得惊人,几乎令人难以置信。
事实上,我最终放弃了很多原计划的工时,现在正在利用空闲时间(很快就会有)撰写这篇博客。

如果你还没试过,何不试一试,体验一下它的便捷之处呢?

 
就这样。

如果您觉得这篇文章有用,请点击【点赞】!
1
加载中...
1票,平均分:1.00/11
3,149
X Facebook Hatena书签 口袋

这篇文章的作者

关于作者

万代洋一

我的主要工作是开发社交游戏的Web API,但我也很荣幸能够从事其他各种工作,包括市场营销。
我在Beyond中的肖像权采用CC0协议。