fuelphp 高级表单编程
fuelphp 通过 fieldset 和 fieldset_field 类提供高级表单编程。 fieldset 提供了一种面向对象的方式来创建表单。它完全支持模型。它还内置了对客户端和服务器端验证的支持。要创建一个完整的表单,创建一个具有适当表单和验证设置的模型就足够了。让我们在本章中了解 fieldset 类以及如何使用它创建表单。
字段集
fieldset 是 fieldset_field 对象的集合。 fieldset_field 定义了表单的单个条目,例如名字、姓氏等以及验证。 fieldset 类具有添加/编辑/删除字段的方法。它具有识别模型中定义的字段并从给定模型创建字段的选项。 fieldset 在后台使用 form 和 validation 类来做真正的工作。让我们看看 fieldset 类的一些重要方法。
forge
forge 创建一个新的 fieldset 实例。它有以下两个参数:
- $name-字段集的标识符
- $config-配置数组。可能的选项是 validation_instance 和 form_instance。 validation_instance 可以有 validation 对象,form_instance 可以有 form 对象。
$employee_form = fieldset::forge('employee');
实例
instance 通过标识符返回之前创建的 fieldset 实例。
$employee_form = fieldset::instance('employee');
get_name
获取字段集实例的标识符。
$employee_form = fieldset::forge('employee');
$name = $employee_form->get_name();
add
add 创建一个新的 fieldset_field 实例并将其添加到当前字段集。它包含以下四个参数,
- $name-字段名称
- $label-字段标签
- $attributes-html 标签属性
- $rules-验证规则
$employee_field = $employee_form-> add (
'employee_lastname',
'lastname',
array ('class' => 'pretty_input')
);
// with validation rules
$employee_form->add (
'email', 'e-mail',
array('type' => 'email', 'class' => 'pretty_input'),
array('required', 'valid_email')
);
add_before
add_before 与 add 类似,只是它有一个额外的参数来指定新创建的字段将添加到哪个字段之前。
$employee_form->add_before (
'employee_firstname',
'firstname',
array ('class' => 'pretty_input'),
array(),
'employee_lastname'
);
delete
delete 从字段集中删除指定的字段。
$employee_form->delete('employee_firstname');
field
field 从字段集中获取所有字段或指定的字段。
$fields = $employee_form->field();
$lastname_field = $employee_form->field('employee_lastname');
build
build 是 $this->form()->build() 的别名。生成表单的 html 标记。
$employee_form->build(uri::create('employee/add'));
enable
enable 重新启用先前已禁用的字段。
$employee_form->enable('employee_firstname');
disable
disable 允许禁止构建字段集中的字段。
$employee_form->disable('employee_firstname');
form
form 返回当前字段集的 form 实例。
$form = employee_form->form();
add_model
add_model 将模型的字段添加到字段集中。它有以下三个参数,
- $class-类名
- $instance-用值填充字段的类的实例
- $method-类中方法的名称。此方法用于将字段添加到字段集中。 orm\model 具有所需的方法。默认方法名称是 set_form_fields。
$employee_form = fieldset::forge('employee');
$employee_form->add_model('model_employee');
populate
populate 使用模型实例设置字段集中字段的初始值。
$emp = new model_employee(); $emp->name = "jon"; $employee_form->populate($emp);
repopulate
repopulate 与 populate 相同,只是它重新填充字段集中的字段。
validation
validation 获取当前字段集的验证实例。
$validation = $employee_form->validation();
validated
$this->validation()->validated() 的别名。
input
$this->validation()->input() 的别名。
error
$this->validation()->error() 的别名。
show_errors
$this->validation()->show_errors() 的别名。
工作示例
让我们创建一个高级表单,使用 fieldset 类在我们的示例员工应用程序中添加新员工。
更新模型
使用必要的验证规则更新员工模型,并按如下方式添加验证观察者。
class model_employee extends orm\model {
protected static $_connection = 'production';
protected static $_table_name = 'employee';
protected static $_primary_key = array('id');
protected static $_properties = array (
'id',
'name' =--> array (
'data_type' => 'varchar',
'label' => 'employee name',
'validation' => array (
'required',
'min_length' => array(3),
'max_length' => array(80)
),
'form' => array (
'type' => 'text'
),
),
'age' => array (
'data_type' => 'int',
'label' => 'employee age',
'validation' => array (
'required',
),
'form' => array ('type' => 'text' ),
),
);
// just add the observer, and define the required event
protected static $_observers = array('orm\\observer_validation' => array (
'events' => array('before_save')));
} 这里,我们定义了 name 和 age 字段的验证规则,并添加了一个新的观察者来执行服务器端验证,然后将模型保存到数据库中。相同的验证规则也会在表单中创建必要的输入验证属性。
创建表单
在员工控制器中创建新动作 action_advancedform,如下所示。
public function action_advancedform() {
// create a new fieldset and add employee model
$fieldset = fieldset::forge('employee')->add_model('model_employee');
// get form from fieldset
$form = $fieldset->form();
// add submit button to the form
$form->add('submit', '', array('type' => 'submit', 'value' => 'submit'));
// build the form and set the current page as action
$formhtml = $fieldset->build(uri::create('employee/advancedform'));
// set form in data
$data = array();
$data['form'] = $formhtml;
return response::forge(view::forge('employee/advancedform', $data, false));
} 在这里,我们使用 fieldset 创建了表单并将表单发送到视图。接下来,为动作添加视图, fuel/app/views/employee/advancedform.php,如下所示。
<title>employee :: add page</title>
<meta charset="utf-8">
<meta name="viewport" content="width = device-width, initial-scale = 1">
echo asset::css('bootstrap.css');
<style>
table {
width: 90%;
}
table tr {
width: 90%
}
table tr td {
width: 50%
}
input[type = text], select {
width: 100%;
padding: 12px 20px;
margin: 8px 0;
display: inline-block;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
input[type = submit] {
width: 100%;
background-color: #3c3c3c;
color: white;
padding: 14px 20px;
margin: 8px 0;
border: none;
border-radius: 4px;
cursor: pointer;
}
div {
border-radius: 5px;
background-color: #f2f2f2;
padding: 20px;
}
</style>
if(isset($errors)) {
echo $errors;
}
echo $form;
现在,请求页面 http://localhost:8080/employee/add 将显示以下表单。

流程表格
更新action方法, action_advancedform来处理表单,将用户输入的员工数据添加到员工控制器的数据库中,如下所示。
public function action_advancedform() {
// create a new fieldset and add employee model
$fieldset = fieldset::forge('employee')->add_model('model_employee');
// get form from fieldset
$form = $fieldset->form();
// add submit button to the form
$form->add('submit', '', array('type' => 'submit', 'value' => 'submit'));
// build the form and set the current page as action
$formhtml = $fieldset->build(uri::create('employee/advancedform'));
if (input::param() != array()) {
try {
$article = model_employee::forge();
$article->name = input::param('name');
$article->url = input::param('age');
$article->save();
response::redirect('employee/list');
}
catch (orm\validationfailed $e) {
$view = view::forge('employee/advancedform');
$view->set('form', $formhtml, false);
$view->set('errors', $e->getmessage(), false);
}
}
return response::forge($view);
} 在这里,我们被重定向到员工列表页面,一旦用户输入的数据被验证并保存到数据库中。否则,我们将再次显示该表单。
创建表单
现在,请求 url, http://localhost:8080/employee/add 并输入一些员工数据并提交表单。如果未提供数据,则表单将提示用户输入数据,如下面的屏幕截图所示。

如果用户绕过客户端验证,则服务器将验证表单并显示错误,如下面的屏幕截图所示。

如果数据通过客户端和服务器端验证,那么员工数据将被保存到数据库中,页面被重定向到列表页面。


