Добавить пользовательский обработчик отправки в форму

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.
Юсеф
какой твой код еще $ form ['actions'] ['submit'] ['# submit']? Попробуйте заменить ['submit'] на [$ action].
MrD

Ответы:

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?");

}
MrD
источник
1
$form['actions'][$action]['#submit'][]какую документацию вы просматриваете? или ты сделал опечатку? В этом документе hook_form_alter сказано $form['actions']['submit']['#submit'][].
Нет Sssweat
1
Нет, это hook_form_BASE_FORM_ID_alter ()
MrD
1
Интересно, да, может быть, ему нужно пройти через действия. Хотя, в этом другом вопросе Как реализовать пользовательский обработчик отправки в hook_form_alter ()? Предполагается, что он работает так, как он это делает.
Нет Sssweat
3
Каждая форма имеет разные структуры. Так что конкретного ответа нет.
MrD
5
См. Drupal.org/node/1901216 и drupal.org/node/2068063 для получения дополнительной информации о том, почему этот цикл необходим
Бердир
18

Создание собственного плагина обработчика веб-формы для drupal 8.

В этом документе предполагается, что вы уже установили и включили webform и webform-ui

1) Создайте свою веб-форму. - Перейдите в структуру -> веб-формы и нажмите кнопку «+ Добавить веб-форму». - Вы можете использовать пользовательский интерфейс или yaml, это ваше дело. Пример yaml для формы с одним полем, которая принимает адрес электронной почты:

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

Отступ важен для yaml, поэтому убедитесь, что вы правильно поняли. отступы - пробелы.

Теперь сохраните вашу форму.

2) Создание плагина обработчика веб-формы

Затем мы можем создать новый плагин, который будет отображаться в разделе «Электронная почта / обработчики» при редактировании веб-формы. Я назову это myhandler, вы можете назвать это как хотите, при условии, что вы замените все упоминания myhandler на выбранное вами имя.

a) Создайте новую папку для вашего плагина, сделайте это в корне drupal (называемом здесь / var / www / html /) в следующей подпапке: / var / www / html / modules / Custom / myhandler

б) Создать новый файл в указанном выше каталоге с именем 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 в каталоге вашего модуля, например: / var / www / html / modules / Custom / myhandler / src в 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 или extends), а затем перестройте кеш drupal («drush cr» из любого места под вашим корнем drupal (/ var / www / html здесь) сделает это, если вы используете drush)

6) отредактируйте свою веб-форму, перейдите в раздел «Электронная почта / обработчики» и нажмите кнопку «+ Добавить обработчик». Вы должны увидеть свой плагин в списке, нажать «Добавить обработчик», теперь вы должны увидеть окно с просьбой ввести URL-адрес отправки. нажмите кнопку Сохранить. Если что-то выглядит неправильно или не работает, проверьте журнал ошибок apache, там вы можете найти что-то полезное.

7) Протестируйте свою форму - сделайте отправку в форму, а затем проверьте контрольный журнал (drush ws), вы должны увидеть значения, отправленные в него. Они могут быть усечены в выводе, который вы видите, не паникуйте, все это есть. Что вы делаете с этим сейчас, зависит от вас.

Надеюсь, это кому-нибудь поможет. Я собрал все это вместе с вещами, которые я нашел повсюду, и записал их в единый документ. Спасибо всем, кто меня сюда привел.

CptnObvious
источник
1
Если я правильно понял, единственной вещью, которая отсутствует в приведенном выше коде для корректной работы обработчика, является метод submitConfigurationForm (), состоящий из parent::submitConfigurationForm($form, $form_state);и parent::applyFormStateToConfiguration($form_state);.
Хендрик
1
@ Хендрик Нет, тебе это не нужно. Я создал новый обработчик только с submitForm()функцией, и он работает. Все остальные функции находятся в базовом классе, и мне не нужно их переопределять. Кстати, довольно хорошее простое решение, как только вы это
выясните
5

если использовать hook_form_BASE_FORM_ID_alter в Drupal 8 core 8.4.3, я обнаружил, что способы добавления пользовательского обработчика отправки не работают. Это сработало для добавления имени функции обработчика отправки:

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

В другой ситуации, используя hook_form_FORM_ID_alter в Drupal 8.4.5, я обнаружил, что вышеописанное не работает для добавления пользовательского обработчика отправки. Вместо этого это сработало:

$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) { ...
user1359
источник