Lugir 2017-02-23 11:18
表单(Form)是 Drupal 开发以及 Web 开发中最常见的需求之一,用户与网站的数据交互几乎都需要通过表单来作为入口。作为 Drupal 开发工程师,掌握 Form API 的重要性不言而喻。
Drupal 8 表单基础
Drupal 中的表单,是通过 PHP 数组以特定结构进行定义(最终会转换成 HTML 代码),而不是直接编写 HTML 代码。采取这种方式的原因有以下几点:
- 使所有表单的 HTML 代码结构保持一定的一致性
- 使表单能够方便地被其它模块进行修改调整,而不必大费周章地调整表单逻辑
- 复杂的表单元素(如文件上传)可以被封装成可复用的整体,使开发更简便
Drupal 表单的基本工作流程分为:定义表单、数据验证和提交处理三个步骤。在 Drupal 8 中,开发人员通过复写 buildForm()
, validateForm()
和 submitForm()
这三个方法即可实现相应的步骤。
Drupal 8 表单的基类定义于 \Drupal\Core\Form\FormInterface 中,开发人员需根据不同的需求来选择不同的基类:
- ConfigFormBase - 创建系统配置表单,用于存放模块配置信息,如管理 > 配置 > 系统 > 站点信息(admin/config/system/site-information)页面表单
- ConfirmFormBase - 提供需要确认步骤的表单,例如删除内容时的操作
- FormBase - 最常用的普通表单
创建表单文件
以我们之前创建的 hello_world 模块为基础(详见《Drupal 8 模块开发入门教程》),创建 src/Form/HelloWorldExampleForm.php
文件,用于放置表单相关的代码
定义表单
不论打算创建哪种类型的表单,在 Drupal 8 中都需要复写 getFormId()
和 buildForm()
方法,我们以通用表单为例,在 HelloWorldExampleForm.php 中加入以下代码:
namespace Drupal\hello_world\Form;
use \Drupal\Core\Form\FormBase;
use \Drupal\Core\Form\FormStateInterface;
class HelloWorldExampleForm extends FormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'hello_world_example_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['who'] = array(
'#type' => 'textfield',
'#title' => $this->t('Who'),
'#description' => $this->t('Who do you want to say hello to?'),
);
$form['save'] = array(
'#type' => 'submit',
'#value' => $this->t('Save'),
);
return $form;
}
}
检验表单数据
当用户填写完表单并点击提交按钮后,通常需要对表单中的数据进行一些检查校验,而执行此操作是通过对 validateForm() 方法进行复写而实现。往往我们会在这个阶段对提交数据的格式、长度、安全性进行充分的检查,以便确认用户提交的数据符合格式、规则,同时也不会对系统造成安全隐患。
用户提交的数据会存放在 $form_state
对象中,可以通过 $form_state->getValue('field_id')
取得指定的值,或者使用 $form_state->getValues()
取得提交的所有值。
如果经过校验发现有些数据不符合要求,可以通过 $form_state->setErrorByName()
方法返回表单错误。
在此示例中,我们要求输入的值必须大于2个字符,相应的示例代码如下:
/**
* {@inheritdoc}
*/
p