Thay đổi một hình thức hiện có


12

Chúng tôi chỉ mới bắt đầu với Drupal 8 và rất nhanh chúng tôi gặp vấn đề đầu tiên.

Làm thế nào tôi nên thay đổi một hình thức hiện có trong Drupal 8?

Chúng ta cần thay đổi phương thức lưu cho dạng nút để chuyển hướng đến một trang khác. Chúng tôi muốn thay đổi hình thức nút để trở thành một cái gì đó giống như một hình thức nhiều bước. Sau khi người dùng tạo nội dung mới, họ sẽ được chuyển hướng đến một hình thức mới (chúng tôi đã tạo) để có thêm một số thông tin.

Chúng tôi đã giải quyết vấn đề của chúng tôi khi thực hiện hook_entity_type_alter().

function mymodule_entity_type_alter(&$entity_info) {
  $handlers = $entity_info['node']->get('handlers');
  $handlers['form']['default'] =    'Drupal\mymodule\Form\MyExtendedNodeForm';
  $handlers['form']['edit'] = 'Drupal\mymodule\Form\MyExtendedNodeForm';
  $entity_info['node']->set('handlers', $handlers);
}

Sau đó chúng tôi đã tạo một lớp biểu mẫu mới mở rộng biểu mẫu nút và thay đổi phương thức lưu.

class MyExtendedNodeForm extends NodeForm {

    public function save(array $form, FormStateInterface $form_state) {
      parent::save($form, $form_state);
      $node = $this->entity;
      $form_state->setRedirect('entity.regions.add_form', ['nid' => $node->id()]);
  }

}

Điều này hoạt động hoàn hảo, nhưng nó là tốt? Nếu một mô-đun khác làm điều tương tự, mã của chúng tôi sẽ không được thực thi nữa.


2
Drupal 8 vẫn hỗ trợ hook_form_alter(). Nếu bạn chỉ cần chuyển hướng biểu mẫu, đủ để thêm trình xử lý gửi biểu mẫu thực hiện chuyển hướng.
kiamlaluno

@kiamlaluno Đó phải là câu trả lời tôi nghĩ :)
Berdir

@Berdir Điều đó một mình sẽ không hữu ích lắm, tôi e rằng: Kiến thức về Drupal 8 của tôi khá hạn chế. Thêm vào đó, OP nên làm rõ "thay đổi save()phương pháp" thực sự có nghĩa là gì. Có nghĩa là thay đổi cách lưu dữ liệu, hoặc chỉ thực hiện chuyển hướng? Trong trường hợp đầu tiên, câu trả lời phức tạp hơn.
kiamlaluno

@kiamlaluno Thx cho câu trả lời. Trong trường hợp này, chúng tôi chỉ cần thực hiện chuyển hướng sau khi lưu () để câu trả lời của bạn sẽ hoạt động. Nhưng tôi cũng quan tâm đến việc làm thế nào để thay đổi những thứ khác theo mẫu theo cách đúng 8 của Drupal. Ví dụ: thay đổi cách lưu nó hoặc thêm các trường vào biểu mẫu .. vv ..
Jens Steppe

Câu trả lời:


4

Tôi đã phải làm điều tương tự chính xác ngày hôm qua, và tôi vẫn đang tìm kiếm một cách 8 Drupal hơn để làm điều này, nhưng không tìm thấy nó. Tôi cuối cùng đã làm theo cách này:

<?php

/**
 * @file
 * This is my module.
 */

use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 * Implements hook_form_alter().
 */
function MODULE_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'user_form') {
    $form['actions']['submit']['#submit'][] = '_MODULE_goto';
  }
}

/**
 * Make the form go to route.id.
 */
function _MODULE_goto($form, FormStateInterface $form_state) {
  $form_state->setRedirect('route.id');
}

Tôi vẫn rất thích làm theo cách khác, mô-đun của tôi trông rất sạch sẽ mà không có tệp .module :).


3

Tôi đang sử dụng Drupal 8.1.1 và đang cố chuyển hướng người dùng sau khi họ sửa đổi tài khoản của họ, tức là nhấp vào nút Lưu trên trang / user / chỉnh sửa. Ban đầu tôi đã thử điều này:

/**
 * Implements hook_form_alter().
*/
function MODULE_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'user_form') {
    $form['#submit'][] = '_MODULE_goto';
  }
}

Trong khi điều đó làm việc cho user_login_form, nó sẽ không làm việc cho user_form. Vì user_formtôi đã phải sử dụng

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

Tôi hy vọng điều đó sẽ giúp những người khác vấp phải vấn đề tương tự!


1

Vâng, tôi muốn thay đổi site_information_settingshình thức để thêm một số lĩnh vực.

Là bạn, tôi đã có sự lựa chọn giữa

  • hook_form_alter(hoặc hook_form_FORM_ID_alter)
  • mở rộng lớp mẫu ban đầu

Muốn thực hiện một số OOP vì vậy tôi bắt đầu viết một dịch vụ thuê bao tuyến thay đổi thuộc tính system.site_information_settingscủa tuyến _form.

Sau đó, trong lớp mới của tôi mở rộng SiteInformationForm, sau khi các trường & trình xác nhận của chúng được thêm vào và chức năng gửi được mở rộng, tôi cảm thấy giống hệt như bạn ... Bây giờ nếu một mô-đun khác viết lại tuyến đường của biểu mẫu để sử dụng lớp của chính nó thì sao?

Quay lại từ đầu, tôi đã có lựa chọn giữa hai lựa chọn ... có vẻ như tôi đã chọn sai.

hook_form_alter/ hook_form_FORM_ID_alterdường như là cách tốt nhất để thay đổi một hình thức hiện có.


0

Nó trông giống như những gì bạn muốn làm, nó không thực sự thay đổi phương thức lưu, mà là thay đổi chuyển hướng khi một nút được lưu.

Trong tình huống này, làm nhiều việc như Drupal 7, hook_form_altercùng với trình xử lý gửi tùy chỉnh (trên biểu mẫu hoặc nút, tùy thuộc vào biểu mẫu và yêu cầu) sẽ là một giải pháp tốt.

Những gì bạn mô tả trong câu hỏi cũng hoạt động, nhưng tôi sẽ tránh ghi đè lên lớp cơ sở, trừ khi tôi thực sự muốn thay đổi một cái gì đó trong lớp.

Phương thức lưu sử dụng chỉ được sử dụng như một trình xử lý trình, vì vậy không có ý nghĩa gì khi ghi đè chỉ để thêm chuyển hướng.


0

Tôi nghĩ rằng phương pháp tốt hơn là vẫn sử dụng một trong các hook từ họ form_alter, đính kèm một trình xử lý đệ trình và trong đó thiết lập chuyển hướng của bạn.

Theo ý kiến ​​của tôi, việc mở rộng các lớp cơ sở để làm điều này là rất nhiều lông. Đặc biệt là vì không có chức năng nào thay đổi, chỉ cần chuyển hướng.


0

Bạn có thể tạo một EventSubscacker mới lắng nghe sự kiện KernelEvents :: REQUEST và sau đó phản ứng khi bạn gửi biểu mẫu nút, đại loại như thế này

Dù sao cách hook_form_alter hoạt động tốt.


0

Những gì tôi tìm thấy cho đến nay: Thực hiện một trình thay đổi biểu mẫu và cố gắng thay đổi trình xử lý xác thực / gửi trình tự trong biểu mẫu thay đổi chính nó chỉ hoạt động nếu bạn thay đổi trình xử lý $ form ['# verifyate] / $ form [#submit']. (gọi các hàm form_state cho việc này sẽ không hoạt động ở dạng thay đổi chính hook)

Nhưng khi bạn thử điều này trong một trình xử lý xác nhận, nó có xu hướng hoạt động:

// Load form submit handlers.
$submit_handlers = $form_state->getSubmitHandlers();

// Drop the core entity submitForm function.
$key_core_submit = array_search('::submitForm', $submit_handlers);
if ($key_core_submit !== FALSE) {
  unset($submit_handlers[$key_core_submit]);
  // Add your own submit handler.
  array_unshift($submit_handlers, 'yourmodule_submit_handler');
}
// Update submit handlers.
$form_state->setSubmitHandlers($submit_handlers);

Điều này là do biểu mẫu hiện đã được xây dựng hoàn chỉnh, không phải là trường hợp trong biểu mẫu thay đổi móc.

Ý tưởng là: bạn có thể thêm một trình xử lý xác nhận là trình xử lý cuối cùng, đánh giá các trình xử lý khác tồn tại để gửi và thay đổi chúng ngay tại đó.

Nếu bạn cũng muốn thay đổi trình xử lý xác thực, hãy đảm bảo rằng trình xử lý của bạn chạy trước bất kỳ trình xử lý nào khác và thay đổi những gì bạn muốn trong trình xử lý xác thực.

Vẫn đang tìm kiếm một cách tốt hơn cho bản thân mình, tôi chỉ cần luôn luôn thay thế trình xử lý xác thực / gửi cho biểu mẫu đăng ký người dùng. Nhưng các mô-đun khác có thể tồn tại mà phá vỡ triển khai mô-đun của tôi. Vì vậy, mô-đun của tôi sẽ cần phải có khả năng kiểm tra những thứ này, và đó là cách có thể. Tôi tự hỏi nếu một số hình thức thực thể sau khi xây dựng chức năng tồn tại để kéo này ra. (một cái gì đó chạy khi biểu mẫu đã được hoàn thành và sắp được gửi) (đó không phải là cách phức tạp cho trường hợp đơn giản này)

Việc bỏ qua chuyển hướng của phương thức save () là không thể, nhưng bỏ đặt lưu () là thông qua cách này (+ thực hiện theo cách riêng của bạn). Đúng, một lớp đẹp hơn và cung cấp quyền truy cập dễ dàng hơn vào các đối tượng / vv, nhưng việc ghi đè một lớp lõi thực sự dẫn đến các vấn đề khi các mô-đun khác muốn sử dụng các đối tượng này. Đó không phải là trường hợp nếu bạn sử dụng mã này.


0

Sau khi kiểm tra vấn đề này, đây là những gì tôi thấy phù hợp với trường hợp của bạn:

/**
 * Implements hook_entity_type_alter().
 */
function mymodule_entity_type_alter(&$entity_info) {
 $entity_info['node']->setFormClass('edit','Drupal\mymodule\Form\CustomNodeForm');
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.