FuelPHP - 高级表单编程
FuelPHP 通过 Fieldset 和 Fieldset_Field 类提供高级表单编程。Fieldset 提供了一种面向对象的方式来创建表单。它完全支持模型。它还内置了对客户端和服务器端验证的支持。要创建一个功能齐全的表单,只需创建一个具有适当表单和验证设置的模型即可。让我们在本章中了解 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
instance通过标识符返回之前创建的Fieldset实例。
$employee_form = Fieldset::instance('employee');
get_name
获取fieldset实例的标识符。
$employee_form = Fieldset::forge('employee'); $name = $employee_form->get_name();
add
add创建一个新的Fieldset_Field实例,并将其添加到当前fieldset中。它包含以下四个参数,
$name − 字段的名称
$label − 字段的标签
$attributes − HTML 标签属性
$rules − 验证规则
$employee_field = $employee_form-> add ( 'employee_lastname', 'Lastname', array ('class' => 'pretty_input') ); // 使用验证规则 $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 使用模型实例设置 fieldset 中字段的初始值。
$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 类创建一个高级表单,以在我们的示例员工应用程序中添加新员工。
更新模型
使用必要的验证规则更新员工模型,并按如下方式添加验证观察者。
<?php 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'))); }
在这里,我们定义了姓名和年龄字段的验证规则,并添加了一个新的观察者,在将模型保存到数据库之前执行服务器端验证。相同的验证规则也将在表单中创建必要的输入验证属性。
创建表单
在员工控制器中创建新操作 action_advancedform,如下所示。
public function action_advancedform() { // 创建新的字段集并添加员工模型 $fieldset = Fieldset::forge('employee')->add_model('Model_Employee'); // 从字段集获取表单 $form = $fieldset->form(); // 向表单添加提交按钮 $form->add('Submit', '', array('type' => 'submit', 'value' => 'Submit')); // 构建表单并将当前页面设置为操作 $formHtml = $fieldset->build(Uri::create('employee/advancedform')); // 在数据中设置表单 $data = array(); $data['form'] = $formHtml; return Response::forge(View::forge('employee/advancedform', $data, false)); }
这里,我们使用 fieldset 创建了表单,并将该表单发送到视图。接下来,为操作添加视图 fuel/app/views/employee/advancedform.php,如下所示。
<!DOCTYPE html> <html lang = "en"> <head> <title>Employee :: add page</title> <meta charset = "utf-8"> <meta name = "viewport" content = "width = device-width, initial-scale = 1"> <?php 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> </head> <body> <div class = "container"> <?php if(isset($errors)) { echo $errors; } echo $form; ?> </div> </body> </html>
现在,请求页面 http://localhost:8080/employee/add 将显示以下表单。
处理表单
更新操作方法 action_advancedform 以处理表单并将用户输入的员工数据添加到员工控制器中的数据库中,如下所示。
public function action_advancedform() { // 创建新的字段集并添加员工模型 $fieldset = Fieldset::forge('employee')->add_model('Model_Employee'); // 从字段集获取表单 $form = $fieldset->form(); // 向表单添加提交按钮 $form->add('Submit', '', array('type' => 'submit', 'value' => 'Submit')); // 构建表单并将当前页面设置为操作 $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,输入一些员工数据并提交表单。如果未提供数据,则表单将提示用户输入数据,如以下屏幕截图所示。
如果用户绕过客户端验证,则服务器将验证表单并显示错误,如以下屏幕截图所示。
如果数据通过了客户端和服务器端验证,则员工数据将保存到数据库中,页面将重定向到列表页面。