Thêm một trình xử lý đệ trình tùy chỉnh vào một biểu mẫu


19

Làm thế nào tôi có thể thêm một trình xử lý biểu mẫu tùy chỉnh?

Tôi đã thử thêm $form['#submit'][] = 'mymodule_form_submit';hoặc $form['actions']['submit']['#submit'][] = 'mymodule_form_submit';đến hook_form_alter().

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

function MYMODULE_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'node_trends_form' || $form_id == 'node_trends_edit_form') {
    foreach (array_keys($form['actions']) as $action) {
      if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
        $form['actions']['submit']['#submit'][] = 'mymodule_form_submit';
      }
    }
  }
}
function mymodule_form_submit(array $form, FormStateInterface $form_state){
    //die("why won't this execute? :(");
    drupal_set_message("Why won't this message show?");
}

Có vẻ như drupal_set_message()không được gọi. Tôi cũng đã thử xây dựng lại bộ đệm, nhưng chức năng vẫn không được gọi.

Tôi đang sử dụng Drupal 8.2.3.


Bạn nên thể hiện việc thực hiện đầy đủ hook_form_alter(), hoặc khó hơn một chút để cho bạn biết bạn đang làm gì sai. Ngoài ra, bạn nên nói hình thức nào bạn đang cố gắng thay đổi.
kiamlaluno

@kiamlaluno Tôi thêm hook_form_alter của tôi.
Yusef

Mã của bạn vẫn là $ form ['hành động'] ['submit'] ['# submit']? Hãy thử thay thế ['submit'] bằng [$ action].
MrD

Câu trả lời:


25

Nếu bạn sử dụng hook_form_node_form_alter()có thể sử dụng mã ví dụ :

function mymodule_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  foreach (array_keys($form['actions']) as $action) {
    if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
      $form['actions'][$action]['#submit'][] = 'mymodule_form_submit';
    }
  }
}

và gửi chức năng

function mymodule_form_submit(array $form, FormStateInterface $form_state){
    //die("I'm not getting run, why :(");
    drupal_set_message("Why won't this message show?");

}

1
$form['actions'][$action]['#submit'][]tài liệu nào bạn đang xem? hoặc bạn đã làm một lỗi đánh máy? Trong tài liệu hook_form_alter này, nó nói $form['actions']['submit']['#submit'][].
Không có Sssweat

1

1
Thật thú vị, vâng, có lẽ anh ta cần phải lặp lại các hành động. Mặc dù, trong phần khác này Q Làm thế nào để bạn triển khai trình xử lý gửi tùy chỉnh trong hook_form_alter ()? Nó giả sử làm việc theo cách anh ấy đang làm.
Không có Sssweat

3
Mỗi hình thức có cấu trúc khác nhau. Vì vậy, không có câu trả lời cụ thể.
MrD

5
Xem drupal.org/node/1901216drupal.org/node/2068063 để biết thêm bối cảnh về lý do tại sao vòng lặp đó là cần thiết
Berdir

18

Tạo một plugin xử lý biểu mẫu web tùy chỉnh cho drupal 8.

Tài liệu này giả định rằng bạn đã cài đặt và kích hoạt biểu mẫu web và webform-ui

1) Tạo biểu mẫu web của bạn. - Chuyển đến cấu trúc -> biểu mẫu web và nhấn nút "+ Thêm biểu mẫu web". - Bạn có thể sử dụng ui hoặc sử dụng yaml, tùy bạn. ví dụ yaml cho một hình thức một trường có địa chỉ email:

email:
  '#type': email
  '#title': email
  '#title_display': invisible
  '#placeholder': 'ENTER YOUR EMAIL'
  '#attributes':
    class:
      - my-ip

Việc thụt lề rất quan trọng đối với yaml vì vậy hãy chắc chắn rằng bạn đã hiểu đúng. thụt lề là không gian.

Bây giờ lưu mẫu của bạn.

2) Tạo plugin xử lý biểu mẫu web

Tiếp theo, chúng ta có thể tạo một plugin mới sẽ hiển thị trong phần "Email / Trình xử lý" khi chỉnh sửa biểu mẫu web. Tôi sẽ gọi nó là myhandler, bạn có thể gọi nó là những gì bạn muốn, miễn là bạn thay thế tất cả các đề cập của myhandler bằng tên bạn chọn.

a) Tạo thư mục mới cho plugin của bạn, thực hiện việc này trong root drupal của bạn (được gọi ở đây là / var / www / html /) trong thư mục con sau: / var / www / html / module / Custom / myhandler

b) Tạo một tệp mới trong thư mục trên có tên myhandler.info.yml trong tệp này như sau:

name: My Form Handler
description: handles form submits, does something with them. 
package: Custom
type: module
version: 1.0
core: 8.x

3) Tạo thư mục src trong thư mục mô-đun của bạn, ví dụ: / var / www / html / module / Custom / myhandler / src trong src tạo Plugin trong Plugin tạo WebformHandler

(điều này có thể đạt được trong một lần sử dụng

mkdir -p /var/www/html/modules/Custom/myhandler/src/Plugin/WebformHandler/ 

sẽ làm cho toàn bộ cấu trúc trong một lần sử dụng cờ -p thành mkdir.)

4) Tạo một tập tin mới /var/www/html/modules/Custom/myhandler/src/Plugin/WebformHandler/MyFormHandler.php

trong tệp đó có mã php sau, tôi đã để lại thiết lập biểu mẫu cấu hình để bạn có thể xem cách định cấu hình plugin nếu cần.

<?php
namespace Drupal\myhandler\Plugin\WebformHandler;

use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Serialization\Yaml;
use Drupal\Core\Form\FormStateInterface;
use Drupal\webform\Plugin\WebformHandlerBase;
use Drupal\webform\webformSubmissionInterface;


/**
 * Form submission handler.
 *
 * @WebformHandler(
 *   id = "myhandler_form_handler",
 *   label = @Translation("MyHandler form handler"),
 *   category = @Translation("Form Handler"),
 *   description = @Translation("Do something extra with form submissions"),
 *   cardinality = \Drupal\webform\Plugin\WebformHandlerInterface::CARDINALITY_SINGLE,
 *   results = \Drupal\webform\Plugin\WebformHandlerInterface::RESULTS_PROCESSED,
 * )
 */
class MyFormHandler extends WebformHandlerBase {

     /**
       * {@inheritdoc}
       */

     public function defaultConfiguration() {
        return [
            'submission_url' => 'https://api.example.org/SOME/ENDPOINT',
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
        $form['submission_url'] = [
            '#type' => 'textfield',
            '#title' => $this->t('Submission URL to api.example.org'),
            '#description' => $this->t('The URL to post the submission data to.'),
            '#default_value' => $this->configuration['submission_url'],
            '#required' => TRUE,
        ];
        return $form;
    }



  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state, WebformSubmissionInterface $webform_submission) {
    // Your code here.
        // Get an array of the values from the submission.

        $values = $webform_submission->getData();

        // Get the URL to post the data to.
        $post_url = $this->configuration['submission_url'];

        $message = "MyHandler got form data:".print_r($values,1); 
        \Drupal::logger('myformhandler')->error($message);

        return true;
 }
}   
?>

5) Kích hoạt mô-đun MyHandler của bạn (sử dụng menu drush hoặc mở rộng) và sau đó xây dựng lại bộ đệm drupal của bạn ("drush cr" từ bất cứ nơi nào dưới gốc drupal của bạn (/ var / www / html ở đây) sẽ làm điều đó nếu bạn sử dụng drush)

6) chỉnh sửa biểu mẫu web của bạn, đi đến "Email / Trình xử lý" và nhấp vào nút "+ Thêm trình xử lý" Bạn sẽ thấy plugin của mình được liệt kê, nhấp vào Thêm Trình xử lý, bây giờ bạn sẽ thấy một hộp yêu cầu url gửi. nhấp vào nút Lưu. Nếu một cái gì đó không đúng, hoặc nó không hoạt động, hãy kiểm tra nhật ký lỗi apache, bạn có thể tìm thấy một cái gì đó hữu ích ở đó.

7) Kiểm tra biểu mẫu của bạn - thực hiện gửi đến biểu mẫu, sau đó kiểm tra nhật ký theo dõi (drush ws), bạn sẽ thấy các giá trị được gửi đến nó. Chúng có thể bị cắt ngắn trong đầu ra mà bạn thấy, đừng hoảng sợ, tất cả đều ở đó. Những gì bạn làm với điều này bây giờ là tùy thuộc vào bạn.

Hy vọng điều này sẽ giúp được ai đó. Tôi đã ghép nó lại với nhau từ những thứ tôi tìm thấy xung quanh nơi đó và viết nó vào một tài liệu duy nhất. Cảm ơn những người khác đã đưa tôi đến đây.


1
Nếu tôi hiểu đúng, một điều nhỏ còn thiếu trong đoạn mã trên để trình xử lý hoạt động chính xác là phương thức submitConfigurationForm (), bao gồm parent::submitConfigurationForm($form, $form_state);parent::applyFormStateToConfiguration($form_state);.
Hendrik

1
@Hendrik Không, bạn không cần nó. Tôi đã tạo một handler mới chỉ có một submitForm()chức năng và nó hoạt động. Tất cả các hàm khác đều nằm trong lớp cơ sở và tôi không có nhu cầu ghi đè chúng. Nhân tiện: một giải pháp khá đơn giản một khi bạn tìm ra nó ;-)
RWAM

5

nếu sử dụng hook_form_BASE_FORM_ID_alter trong lõi Drupal 8 8.4.3, tôi thấy các cách thêm trình xử lý gửi tùy chỉnh không hoạt động. Điều này làm việc để thêm tên hàm xử lý trình:

$form['#submit'][] = 'mymodule_submit_handler';

Trong một tình huống khác, sử dụng hook_form_FORM_ID_alter trong Drupal 8.4.5, tôi thấy cách trên không hoạt động để thêm trình xử lý gửi tùy chỉnh. Thay vào đó, điều này đã làm việc:

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

1

Câu trả lời được chấp nhận không hoạt động đối với tôi khi sử dụng Drupal 8.7.7, cố gắng thêm trình xử lý trình vào biểu mẫu từ search_apimô-đun.

Tôi đã nhận được lỗi này:

TypeError: Argument 2 passed to _my_module_search_api_form_submit() must be an instance of FormStateInterface, instance of Drupal\Core\Form\FormState given in ...

Để làm cho nó hoạt động, tôi đã thay đổi chữ ký hàm của mình thành không gian tên đầy đủ của giao diện:

function _my_module_search_api_form_submit(array $form, Drupal\Core\Form\FormStateInterface $form_state) { ...
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.