跳转到主要内容

主页内容

Drupal Form API(第三篇:Ajax提交表单并验证表单项数据)

由 webadmin 发布于 阅读 25 次

使用Form Api创建表单,并使用使用ajax提交表单,验证表单数据,并插入数据库。实现这个表单的步骤如下:

1、引入要用到的命名空间

namespace Drupal\demo_form\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\Core\Ajax\InvokeCommand;
use Drupal\Core\Database\Database;

namespace Drupal\demo_form\Form; 是当前表单类的命名空间。

use Drupal\Core\Form\FormBase;是 Drupal 表单 API 的基础类。要创建一个新的表单,表单类应该继承这个类。

use Drupal\Core\Form\FormStateInterface;这个接口代表了表单的状态,包括表单的值、验证错误、重建状态等。当在表单构建、验证或提交函数中处理表单数据时,需要使用到这个接口。

use Drupal\Core\Ajax\AjaxResponse;这个类用于创建 AJAX 响应。可以向这个响应中添加命令,然后返回这个响应,Drupal 就会在浏览器中执行这些命令。

use Drupal\Core\Ajax\HtmlCommand;这是一个 AJAX 命令,用于在浏览器中替换或修改 HTML 内容。

use Drupal\Core\Ajax\InvokeCommand;这是一个 AJAX 命令,用于在浏览器中调用 JavaScript 函数。

use Drupal\Core\Database\Database;这个类提供了对 Drupal 数据库的访问。可以使用这个类的静态方法来获取数据库连接,然后执行查询。

2、创建当前表单类并构建表单

class DemoForm extends FormBase{
  /**
   * {@inheritdoc }
   * 设置表单id
   */
  public function getFormId()
  {
    return 'demo_form_form';
  }
  /**
   * {@inheritdoc }
   * 构建表单中的字段及属性
   */
  public function buildForm(array $form, FormStateInterface $form_state)
  {
    $form['title'] = [
      '#type' => 'select',
      '#title' => $this->t('称呼'),
      '#options' => [//设置select的下拉选项
        'mr' => $this->t('先生'),
        'ms' => $this->t('女士'),
        'dr' => $this->t('博士')
      ],
      '#default_value' => 'mr'//设置select的默认选项
    ];
    $form['name'] = [
      '#type' => 'textfield',
      '#title' => $this->t('姓名'),
      '#maxlength' => 30,
      '#suffix' => '<div class="error" id="name_message"></div>'//表单错误提示
    ];
    $form['age'] = [
      '#type' => 'textfield',
      '#title' => $this->t('年龄'),
      '#suffix' => '<div class="error" id="age_message"></div>'//表单错误提示
    ];
    $form['email'] = [
      '#type' => 'email',
      '#title' => $this->t('邮箱'),
      '#suffix' => '<div class="error" id="email_message"></div>',//表单错误提示
    ];
    $form['actions'] = [
      '#type' => 'submit',
      '#value' => $this->t('提交'),
      '#ajax' => [
        'callback' => '::submitData'//表单以ajax方式提交后处理表单数据的方法
      ]
    ];
    //在提交表单下方添加提示信息
    $form['message'] = [
      '#type' => 'markup',
      '#markup' => '<div class="message"></div>'
    ];
    //这行代码的作用是将demo_form模块的demo_form_js_css库附加到表单。
    //这意味着当表单被渲染时,demo_form_js_css库中的所有CSS和JavaScript文件都会被加载到页面上。
    $form['#attached']['library'][] = 'demo_form/demo_form_js_css';
    return $form;
  }
  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {}
  /**
   * 处理ajax提交的方法
   * @param array $form
   * @param FormStateInterface $form_state
   * @return AjaxResponse
   */
  public function submitData(array &$form, FormStateInterface $form_state){
    $ajax_response = new AjaxResponse();
    $connection    = Database::getConnection();//获取数据库链接对象
    $formFields    = $form_state->getValues();
    $formData['title'] = $formFields['title'];
    $formData['name'] = $formFields['name'];
    $formData['age'] = $formFields['age'];
    $formData['email'] = $formFields['email'];
    if (empty(trim($formData['name']))){
      $ajax_response->addCommand(new HtmlCommand('#name_message','请填写姓名'));
    }
    if (empty(trim($formData['age'])) || $formData['age'] <= 0 || $formData['age'] > 100){
      $ajax_response->addCommand(new HtmlCommand('#age_message','年龄填写不符合规范'));
    }
    if (empty(trim($formData['email']))){
      $ajax_response->addCommand(new HtmlCommand('#email_message','请填写邮箱'));
    }
    //判断前面要验证的表单项是否已经验证通过了
    //$ajax_response->getCommands()是一个数组,如果数组不为空说明前面的表单数据没有全部验证通过
    if (!empty($ajax_response->getCommands())) {
      $ajax_response->addCommand(new InvokeCommand('.message', 'addClass', ['failure']));
      $ajax_response->addCommand(new HtmlCommand('.message','表单有误'));
    }else{
      try {
        $formData['aa'] = 111;
        //将$formData数据插入到employee表中
        $res = $connection->insert('employee')->fields($formData)->execute();
        //$res:如果插入成功,如果数据库表中有自增主键则返回主键值;如果没有自增主键则返回null;如果插入操作失败,则抛出异常。
        $ajax_response->addCommand(new InvokeCommand('#edit-name','val',['']));
        $ajax_response->addCommand(new InvokeCommand('#edit-age','val',['']));
        $ajax_response->addCommand(new InvokeCommand('#edit-email','val',['']));
        //当表单提交成功后,清空表单中各表单项的值。
        $ajax_response->addCommand(new InvokeCommand('.message', 'addClass', ['success']));
        //给提交按钮下的提示信息添加success类
        $ajax_response->addCommand(new HtmlCommand('.message','提交成功'));
        //给提交按钮下的提示信息添加"提交成功"的提示信息
      }catch (\Exception $e){
        $ajax_response->addCommand(new InvokeCommand('.message', 'addClass', ['failure']));
        //给提交按钮下的提示信息添加failure类
        \Drupal::logger('demo_form')->error($e->getMessage());//将异常错误写入错误日志
        $ajax_response->addCommand(new HtmlCommand('.message','提交过程中产生了异常,请查看错误日志'));
        //给提交按钮下的提示信息添加错误提示信息
      }
    }
    return $ajax_response;
  }
}