跳转到主要内容

主页内容

Drupal页面重定向

由 webadmin 发布于 阅读 22 次

一、以Ajax的方式提交表单后重定向:

要实现重定向到一个指定的url,需要用到RedirectCommand类。首先引入RedirectCommand类的命名空间:

use Drupal\Core\Ajax\RedirectCommand;

1、如果需要在提交成功后立即跳转,可以使用RedirectCommand()构造方法。

$redirect_command = new RedirectCommand('/custom/path');
$response->addCommand($redirect_command);

这样在表单提交成功后,将跳转到/custom/path页面。

2、如果需要在请求完成后延迟几秒钟再进行重定向,则需要结合 JavaScript 来实现,需要在模块中定义一个新的 AJAX 命令。这个命令需要继承 Drupal\Core\Ajax\CommandInterface 接口,并实现 render() 方法。在 render()方法中,需要返回一个数组,其中包含你想要在客户端执行的 JavaScript 代码。

(1)、新建一个module_name/src/AjaxCommand/DelayedRedirectCommand.php

DelayedRedirectCommand.php文件内容如下:

<?php
namespace Drupal\demo_form\AjaxCommand;
use Drupal\Core\Ajax\CommandInterface;
class DelayedRedirectCommand implements CommandInterface
{
  /**
   * 重定向的url
   * @var
   */
  protected $url;
  /**
   * 延迟的时间
   * @var
   */
  protected $delay;
  public function __construct($url, $delay) {
    $this->url = $url;
    $this->delay = $delay;
  }
  /**
   * @return array
   */
  public function render() {
    return [
      'command' => 'delayedRedirect',
      'url' => $this->url,
      'delay' => $this->delay,
    ];
  }
}

(2)、在JS中实现跳转

(function ($,Drupal,drupalSettings) {
  'use strict';
  Drupal.AjaxCommands.prototype.delayedRedirect = function(ajax, response, status) {
    setTimeout(function() {
      window.location.href = response.url;
    }, response.delay);
  };
})(jQuery, Drupal, drupalSettings)

(3)、调用

引入命名空间:

use Drupal\demo_form\AjaxCommand\DelayedRedirectCommand;

调用:

$redirect_command = new DelayedRedirectCommand('/custom/path', 5000);
$response->addCommand($redirect_command);

完整示例:表单提交成功后延迟跳转到指定url

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\Component\Utility\EmailValidator;
use Drupal\Core\Database\Database;
use Drupal\demo_form\AjaxCommand\DelayedRedirectCommand;
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' => [
        'mr' => $this->t('先生'),
        'ms' => $this->t('女士'),
        'dr' => $this->t('博士')
      ],
      '#default_value' => 'mr'
    ];
    $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' => 'textfield',
      '#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>'
    ];
    $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','年龄填写不符合规范'));
    }
    $email_validator = new EmailValidator();
    if (!$email_validator->isValid($formData['email'])){
      $ajax_response->addCommand(new HtmlCommand('#email_message','请填写有效的邮箱地址'));
    }
    if (!empty($ajax_response->getCommands())) {
      $ajax_response->addCommand(new InvokeCommand('.message', 'addClass', ['failure']));
      $ajax_response->addCommand(new HtmlCommand('.message','表单有误'));
    }else{
      try {
        $res = $connection->insert('employee')->fields($formData)->execute();
        $ajax_response->addCommand(new InvokeCommand('.message', 'addClass', ['success']));
        $ajax_response->addCommand(new HtmlCommand('.message','提交成功'));
        
        //提交成功后延迟5秒跳转到指定url中
        $redirect_command = new DelayedRedirectCommand('/custom/path', 5000);
        $ajax_response->addCommand($redirect_command);
      }catch (\Exception $e){
        $ajax_response->addCommand(new InvokeCommand('.message', 'addClass', ['failure']));
        \Drupal::logger('demo_form')->error($e->getMessage());
        $ajax_response->addCommand(new HtmlCommand('.message','提交过程中产生了异常,请查看错误日志'));
      }
    }
    return $ajax_response;
  }
}