Drupal-8 Modal 不处理登录错误

问题描述 投票:0回答:2

我使用“use-ajax”类在模式中呈现登录表单。我想在同一模式上处理验证错误而不关闭它。成功登录后,它会正确重定向,但是当发生错误时,它会关闭模式并重定向到登录页面,即用户/登录并在该页面上显示错误。我尝试使用 ajax 回调通过更改正在工作的表单来显示模式本身的错误。但是,它给了我 drupal ajax 错误。这是我的代码:

 $form['#prefix'] = '<div id="modal-form">';
     $form['#suffix'] = '</div>';
     $form['status_messages'] = [ 
           '#type' => 'status_messages',
                 '#weight' => -10,

     ];

     $form['actions']['submit']['#ajax'] = array(
         'callback' => 'setMessage',
         'wrapper' => 'modal-form',
     );

====================================================== ========================

function setMessage(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
$response = new AjaxResponse();

 if ($form_state->hasAnyErrors()) {
     $response->addCommand(new ReplaceCommand('#modal-form', $form));

 }
 else {
     $command = new CloseModalDialogCommand('#modal-form', FALSE);
     $response->addCommand($command);

 }
 return $response;
}

上面的代码也给了我会话 ID,但由于 drupal ajax 错误,它不会通过关闭模式成功重定向。

如果我使用非ajax ie。如果我删除 ajax 回调函数,它会成功,但错误不会显示在模式上。

modal-dialog drupal-8 drupal-ajax
2个回答
3
投票

首先,检查您是否在模块文件中使用 hook_login 添加了与重定向相关的更改。您可以删除与重定向相关的更改并在回调函数中处理重定向。

function setMessage(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {

     $response = new AjaxResponse();
     $current= \Drupal::currentUser();
     if ($form_state->hasAnyErrors()) {
         $response->addCommand(new ReplaceCommand('#modal-form', $form));

     }
     else if (!$current->id()) {
         $response->addCommand(new ReplaceCommand('#modal-form', $form));
     }
     else {
         $command = new RedirectCommand(' ');

         return $response->addCommand($command);
     }
     return $response;
} 

成功后,它将关闭模式并正确重定向。如果您发现任何错误或者您尚未登录,它将保留在模式表单中。


0
投票

这里是在弹出窗口中显示错误消息的代码片段:(核心:登录表单)

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Ajax\CloseModalDialogCommand;
use Drupal\Core\Ajax\RedirectCommand;


function login_popup_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'user_login_form') {
    // Check if the current request is for an Ajax modal/dialog.
    if (login_popup_is_dialog() == TRUE) {
      // Add a wrapper around the form so that we can replace it.
      $form['#prefix'] = '<div id="modal_user_login_form">';
      $form['#suffix'] = '</div>';
      // The status messages that will contain any form errors.
      $form['status_messages'] = [
        '#type' => 'status_messages',
        '#weight' => -10,
      ];
      // Add form validation to the submit btn & make it Ajax.
      $form['actions']['submit']['#validate'] = $form['#validate'];
      $form['actions']['submit']['#attributes']['class'][] = 'use-ajax';
      $form['actions']['submit']['#ajax'] = [
        'callback' => 'login_popup_submit_modal_form_ajax',
        'event' => 'click',
      ];
    }
  }
}

/**
 * AJAX callback that displays the form errors or redirects to page.
 */
function login_popup_submit_modal_form_ajax(array $form, FormStateInterface $form_state) {
  $response = new AjaxResponse();
  // If there are any form errors, re-display the form.
  if ($form_state->hasAnyErrors()) {
    $response->addCommand(new ReplaceCommand('#modal_user_login_form', $form));
  }
  else {
    // On successfully form submission close dialog & redirect to the user page.
    $response->addCommand(new CloseModalDialogCommand());
    $uid = \Drupal::currentUser()->id();
    $redircet_path = Url::fromRoute('entity.user.canonical', ['user' => $uid])->toString();
    $response->addCommand(new RedirectCommand($redircet_path));
  }

  return $response;
}


* Is the current request for an Ajax modal/dialog.
 *
 * @return bool
 *   TRUE if the current request is for an Ajax modal/dialog.
 */
function login_popup_is_dialog() {
  $wrapper_format = \Drupal::request()->query
    ->get(MainContentViewSubscriber::WRAPPER_FORMAT);
  return (in_array($wrapper_format, [
    'drupal_ajax',
    'drupal_modal',
    'drupal_dialog',
    'drupal_dialog.off_canvas',
  ])) ? TRUE : FALSE;
}

注:

#1 下面的代码是必需的,以便核心(登录)表单验证在弹出窗口中触发,否则核心(登录)表单的内置验证将不会在弹出窗口中触发/显示。

$form['actions']['submit']['#validate'] = $form['#validate'];

说明: 我们只想在弹出窗口中显示的任何核心/贡献(内置)表单,但面临验证错误未在弹出窗口中显示的问题:

要重用表单验证而不是编写重复的代码,这个问题背后的解决方案:

在 hook_form_alter 中获取 core/contrib(login) 表单的验证定义 > 在弹出表单的提交处理程序中的“#validate”变量中设置验证定义。

#2 login_popup 是模块名称,可以根据您的模块名称更新“login_popup”。

#3 login_popup_is_dialog : 自定义函数,用于判断表单是否以模态方式打开,如果表单未打开则为模态 那么就没有必要添加这段代码了。

© www.soinside.com 2019 - 2024. All rights reserved.