将自定义提交处理程序添加到表单


19

如何添加自定义表单提交处理程序?

我尝试添加$form['#submit'][] = 'mymodule_form_submit';$form['actions']['submit']['#submit'][] = 'mymodule_form_submit';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?");
}

好像drupal_set_message()不叫。我也尝试过重建缓存,但是仍然没有调用该函数。

我正在使用Drupal 8.2.3。


您应该显示的完整实现hook_form_alter(),否则很难告诉您您做错了什么。另外,您应该说出您要更改的形式。
kiamlaluno

@kiamlaluno我添加了hook_form_alter。
Yusef

您的代码仍然是$ form ['actions'] ['submit'] ['#submit']?尝试用[$ action]替换['submit']。
MrD

Answers:


25

如果您使用的hook_form_node_form_alter()可能是示例代码

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';
    }
  }
}

并提交功能

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'][]您正在查看哪些文档?还是打错字了?在这个hook_form_alter文档中说$form['actions']['submit']['#submit'][]
No Sssweat


1
有趣的是,也许他需要遍历所有动作。虽然,在另一个问题中,您如何在hook_form_alter()中实现自定义提交处理程序?它应该按照他的方式工作。
没有Sssweat

3
每种形式都有不同的结构。因此,没有具体答案。
MrD

5
请参阅drupal.org/node/1901216drupal.org/node/2068063了解有关为什么需要循环的更多信息
Berdir 2016年

18

为drupal 8创建自定义的Webform处理程序插件。

本文档假定您已经安装并启用了webform和webform-ui

1)创建您的网络表单。-转到结构->网络表单,然后按“ +添加网络表单”按钮。-您可以使用ui或yaml,由您决定。包含电子邮件地址的一个字段表单的示例yaml:

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

缩进对于yaml很重要,因此请确保正确。缩进是空格。

现在保存您的表格。

2)创建一个Webform处理程序插件

接下来,我们可以创建一个新插件,该插件将在编辑网络表单时显示在“电子邮件/处理程序”部分中。我将其称为myhandler,只要您用选择的名称替换所有提及myhandler的内容,就可以随意命名。

a)为您的插件创建一个新文件夹,在以下子文件夹的drupal根目录(此处称为/ var / www / html /)中执行此操作:/ var / www / html / modules / Custom / myhandler

b)在上面的目录中创建一个名为myhandler.info.yml的新文件,该文件中包含以下内容:

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

3)在您的模块目录中创建一个src目录,例如:src中的/ var / www / html / modules / Custom / myhandler / src在插件中创建插件在插件中创建WebformHandler

(这可以使用

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

这将使用-p标志对mkdir一次完成整个结构。)

4)创建一个新文件 /var/www/html/modules/Custom/myhandler/src/Plugin/WebformHandler/MyFormHandler.php

在该文件中包含以下php代码,我将配置表单设置保留在其中,因此您可以查看如何根据需要配置插件。

<?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)启用MyHandler模​​块(使用drush或扩展菜单),然后重建您的drupal缓存(如果您使用drush,则可以在您drupal根目录下的任何地方(“ / var / www / html”处都是“ drush cr”))

6)编辑您的Web表单,转到“电子邮件/处理程序”,然后单击“ +添加处理程序”按钮。您应该看到列出的插件,单击“添加处理程序”,现在应该看到一个询问提交网址的框。单击保存按钮。如果某些东西看起来不正确或不起作用,请检查apache错误日志,您可能会在这里找到有用的信息。

7)测试您的表单-提交表单,然后检查看门狗日志(wsrush),您应该看到发送给它的值。在您看到的输出中,它们可能会被截断,不要惊慌,它就在那里。您现在该做什么取决于您。

希望这对某人有帮助。我将在该地点发现的东西拼凑在一起,并将其写到一个文档中。多亏其他把我带到这里的人。


1
如果我做对了,则上述代码中使处理程序无法正常运行的一件小事是SubmitConfigurationForm()方法,由parent::submitConfigurationForm($form, $form_state);和组成parent::applyFormStateToConfiguration($form_state);
Hendrik '18

1
@Hendrik不,您不需要它。我创建了一个仅具有submitForm()函数的新处理程序,它可以工作。所有其他函数都位于基类中,而我无需覆盖它们。顺便说一句:
找到答案后,

5

如果在Drupal 8核心8.4.3中使用hook_form_BASE_FORM_ID_alter,我发现添加自定义提交处理程序的方法无效。这有助于添加提交处理程序函数名称:

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

在另一种情况下,在Drupal 8.4.5中使用hook_form_FORM_ID_alter时,我发现上述操作不适用于添加自定义提交处理程序。相反,这可行:

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

1

使用Drupal 8.7.7试图将提交处理程序添加到search_api模块中的表单时,可接受的答案对我不起作用。

我收到此错误:

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 ...

为了使其正常工作,我将函数签名更改为接口的完整名称空间:

function _my_module_search_api_form_submit(array $form, Drupal\Core\Form\FormStateInterface $form_state) { ...
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.