Adicionar um manipulador de envio personalizado a um formulário

19

Como posso adicionar um manipulador de envio de formulário personalizado?

Eu tentei adicionar $form['#submit'][] = 'mymodule_form_submit';ou $form['actions']['submit']['#submit'][] = 'mymodule_form_submit';para 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?");
}

Parece que drupal_set_message()não é chamado. Eu também tentei reconstruir o cache, mas a função ainda não é chamada.

Estou usando o Drupal 8.2.3.

Yusef
fonte
Você deve mostrar a implementação completa hook_form_alter()ou é um pouco mais difícil dizer o que está fazendo de errado. Além disso, você deve dizer qual formulário você está tentando alterar.
kiamlaluno
@kiamlaluno eu adiciono meu hook_form_alter.
Yusef
qual é o seu código ainda $ form ['actions'] ['submit'] ['# submit']? Tente substituir ['submit'] por [$ action].
MrD

Respostas:

25

Se você usar, hook_form_node_form_alter()pode usar o código de exemplo :

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

e enviar função

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
fonte
1
$form['actions'][$action]['#submit'][]qual documentação você está visualizando? ou você fez um erro de digitação? Neste documento hook_form_alter, ele diz $form['actions']['submit']['#submit'][].
No Sssweat
1
Interessante, sim, talvez ele precise percorrer as ações. Embora, neste outro Q, como você implementa um manipulador de envio personalizado em hook_form_alter ()? é suposto funcionar da maneira que ele está fazendo.
Não Sssweat
3
Cada formulário possui estruturas diferentes. Portanto, não há resposta específica.
MrD
5
Veja drupal.org/node/1901216 e drupal.org/node/2068063 para obter mais contexto sobre por que esse loop é necessário.
Berdir
18

Criando um plug-in de manipulador de formulário da web personalizado para o drupal 8.

Este documento pressupõe que você já instalou e ativou o webform e o webform-ui

1) Crie seu formulário da web. - Vá para estrutura -> formulários da web e pressione o botão "+ Adicionar formulário da web". - Você pode usar a interface do usuário ou yaml, isso é com você. exemplo yaml para um formulário de um campo que usa um endereço de email:

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

O recuo é importante para o yaml, portanto, certifique-se de acertar. recuos são espaços.

Agora salve seu formulário.

2) Criando um plug-in de manipulador de formulários da web

Em seguida, podemos criar um novo plug-in que será exibido na seção "Emails / Manipuladores" ao editar o formulário da web. Vou chamá-lo de myhandler, você pode chamar o que quiser, desde que substitua todas as menções de myhandler pelo nome que escolher.

a) Crie uma nova pasta para o seu plug-in, faça isso na sua raiz drupal (referida aqui como / var / www / html /) na seguinte subpasta: / var / www / html / modules / Custom / myhandler

b) Crie um novo arquivo no diretório acima chamado myhandler.info.yml neste arquivo, conforme segue:

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

3) Crie um diretório src no diretório do módulo, por exemplo: / var / www / html / modules / Custom / myhandler / src no src create Plugin in Plugin create WebformHandler

(isso pode ser obtido de uma só vez usando

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

que fará a estrutura inteira de uma só vez usando o sinalizador -p no mkdir.)

4) Crie um novo arquivo /var/www/html/modules/Custom/myhandler/src/Plugin/WebformHandler/MyFormHandler.php

nesse arquivo vai o seguinte código php, deixei a configuração do formulário de configuração para que você possa ver como configurar seu plugin, se necessário.

<?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) Habilite o módulo MyHandler (usando o menu drush ou estender) e depois reconstrua o cache do drupal ("drush cr" de qualquer lugar abaixo da raiz do drupal (/ var / www / html aqui) faria isso se você usar o drush)

6) edite seu formulário da web, vá para "Email / Manipuladores" e clique no botão "+ Adicionar manipulador" Você deve ver seu plug-in listado, clique em Adicionar manipulador, agora você verá uma caixa solicitando o URL de envio. clique no botão Salvar. Se algo não parece certo ou não está funcionando, verifique o log de erros do apache, você pode encontrar algo útil lá.

7) Teste seu formulário - faça um envio para o formulário e verifique o registro do watchdog (drush ws); você deve ver os valores enviados a ele. Eles podem estar truncados na saída que você vê, não entre em pânico, está tudo lá. O que você faz com isso agora é com você.

Espero que isso ajude alguém. Juntei-o com as coisas que encontrei pelo local e o escrevi em um único documento. Obrigado aos outros que me trouxeram aqui.

CptnObvious
fonte
1
Se eu acertar, a menor coisa que está faltando no código acima para o manipulador funcionar corretamente é o método submitConfigurationForm (), consistindo em parent::submitConfigurationForm($form, $form_state);e parent::applyFormStateToConfiguration($form_state);.
21718 Hendrik
1
@ Hendrik Não, você não precisa disso. Eu criei um novo manipulador com apenas uma submitForm()função e ele funciona. Todas as outras funções estão situadas na classe base e não preciso substituí-las. A propósito: uma solução bastante agradável um simples uma vez que você descobrir isso ;-)
RWAM
5

se usando hook_form_BASE_FORM_ID_alter no Drupal 8 core 8.4.3, encontrei maneiras de adicionar o manipulador de envio personalizado não funcionou. Isso funcionou para adicionar o nome da função do manipulador de envio:

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

Em outra situação, usando hook_form_FORM_ID_alter no Drupal 8.4.5, descobri que o acima não funcionava para adicionar o manipulador de envio personalizado. Em vez disso, isso funcionou:

$form['actions']['submit']['#submit'][]  = 'mymodule_submit_handler';
Anthony Fournier
fonte
1

A resposta aceita não funcionou para mim usando o Drupal 8.7.7, tentando adicionar um manipulador de envio a um formulário do search_apimódulo.

Eu recebi este erro:

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

Para fazê-lo funcionar, alterei minha assinatura de função para o espaço de nome completo da interface:

function _my_module_search_api_form_submit(array $form, Drupal\Core\Form\FormStateInterface $form_state) { ...
user1359
fonte