Como posso implementar o envio de formulários AJAX?

14

Minha tarefa é enviar o formulário de contato via AJAX e depois mostrar "Obrigado pela apresentação!" mensagem, carregada no local onde estava o formulário. Então, eu preciso ajaxificar o formulário de contato existente.

Encontrei alguns exemplos de como validar campos de formulário usando AJAX no D8, mas não consigo encontrar nenhum exemplo de como implementar o envio de formulários ajax e carregar algum conteúdo via AJAX.

Como posso implementar minha tarefa? Como devo alterar o formulário de contato para adicionar a funcionalidade necessária?

Sergey Kravchenko
fonte
Para aqueles que chegam aqui com uma pergunta genérica de formulário: O módulo Webform permite criar um formulário da maneira que você deseja e permitir que os resultados sejam enviados via ajax.
Florian Müller

Respostas:

26

Ao trabalhar com ajax em formulários, você deve ter em mente o seguinte:

  • saiba se você está reconstruindo o formulário inteiro ou apenas parte dele e agrupe o formulário de acordo com o elemento div que possui o atributo ID que você usará na definição #ajax no elemento acionador como 'wrapper'. Use os atributos #prefix e #suffix para isso ( $form['#prefix'] = '<div id="myform-ajax-wrapper">'; $form['#suffix'] = '</div>';). Lembre-se também de que, se você tiver um modelo personalizado para o seu formulário NÃO renderizar o prefixo e o sufixo nesse caso ( {{ form|without('#prefix', '#suffix') }}), eles serão renderizados duas vezes - pelo seu modelo e também pelo wrapper do tema do formulário. Você não pode impedir isso definindo #theme_wrappers como matriz vazia, pois o modelo de formulário contém o elemento html real do formulário.

  • no manipulador de envio do ajax, retorne todo o formulário ou parte dele que você agrupou e deseja reconstruir ( return $formou return $form['myelement']). Além disso, você pode usar comandos ajax em vez de apenas retornar a estrutura do formulário, mas isso é algo mais avançado.

  • armazene todos os valores no armazenamento do estado do formulário até você enviar o formulário. Faça isso no manipulador de envio ( $form_state->set('somevalue', $form_state->getValue('somevalue'))) e sempre ligue $form_state->setRebuild()se você não estiver fazendo o envio final do formulário. Prefiro ter manipuladores de envio personalizados, mas ter mais lógica no manipulador de envio primário também é totalmente aceitável.

  • sempre use o #nameatributo no botão que está enviando e, se você tiver apenas um único manipulador de envio de formulário, use $for_state->getTriggeringElement()['#name']para detectar qual elemento enviou o formulário.

  • se você estiver usando 'trigger_as' na definição de #ajax, caso deseje enviar o formulário com o elemento select, por exemplo, sempre use a mesma definição de #ajax usada no botão. Na minha experiência, é necessário - embora não esteja indicado na documentação.

  • #limit_validation_errorsÀs vezes, usar pode ser muito complicado e descobrir por que o formulário não está funcionando pode demorar um pouco, portanto, use-o com cuidado (isso é bom para isolar erros de formulário apenas no (s) elemento (s) que você está realmente reconstruindo para que seu código não influencia outras partes do formulário).

  • sempre use botões para enviar o formulário e, se quiser ter algo sofisticado, como selecionar ser o elemento acionador, use a opção 'trigger_as' da configuração #ajax e oculte o botão real com a classe 'js-hide' para obter uma boa interface do usuário.

  • na definição do formulário, obtenha os valores padrão do armazenamento do estado do formulário, se existirem, ou atribua-os ao armazenamento, se não existirem. Caso contrário, o formulário não funcionará corretamente.

  • não use $ this ou qualquer outra coisa à qual você não tenha acesso externamente; caso contrário, isso quebrará o ajax. sempre use manipuladores estáticos de ajax.

  • quando finalmente enviar o formulário, dependendo do fato de você (não) ter um manipulador de envio de formulário personalizado para o ajax, desative a reconstrução do formulário chamando $form_state->setRebuild(FALSE).

  • você pode usar as chamadas de taquigrafia :: no elemento de envio do ajax ( $element['#ajax']['callback'] = '::ajaxFormRebuild';e $element['#submit'] = [['::ajaxFormSubmitHandler'];).

  • o retorno de chamada do ajax serve apenas para retornar o formulário reconstruído ou os comandos do ajax. Nunca retorne formulário alterado (ou seja, não altere a matriz do formulário nesse retorno de chamada).


fonte
Ótima lista de verificação, se você tiver problemas com o ajax no drupal 8! (Eu não entendo o primeiro ponto, por que não tornar a div envoltório ajax?)
4k4
Não me lembro exatamente, mas acho que pode ter algo a ver com #theme, #theme_wrappers e manipulação dos atributos #prefix e #suffix no renderizador. Eu acho que você acabaria com o wrapper dentro do elemento <form>. É claro que isso se aplica apenas se você estiver reconstruindo todo o formulário, não apenas algum elemento.
Obrigado, mas onde posso encontrar um exemplo simples para o envio de AJAX?
Sergey Kravchenko
@IvanJaros, thx pela resposta. Você sabe como limpar os valores do formulário após o envio do ajax?
milkovsky
1

Para adicionar a esta lista de verificação, se você estiver exibindo um formulário em uma janela modal, é possível que as mensagens de erro não sejam exibidas. Como Ivan Jaros disse, você deve garantir que o formulário tenha um wrapper:

$form['#prefix'] = '<div id="my-form-wrapper-id">';
$form['#suffix'] = '</div>';

Você também precisará adicionar o seguinte ao elemento que está enviando o formulário. Na maioria dos casos, seria o botão de envio:

$form['submit'] = [
    '#type' => 'submit',
    '#value' => $this->t('Save Changes'),
    '#attributes' => [
        'class' => [
            'btn',
            'btn-md',
            'btn-primary',
            'use-ajax-submit'
        ]
    ],
    '#ajax' => [
        'wrapper' => 'my-form-wrapper-id',
    ]
];
IslandDev
fonte
1

Eu uso o módulo de contato ajax . Mais alguns detalhes sobre ele (na página do projeto):

O contato Ajax implementa o envio do ajax para o formulário de contato no Drupal 8.

Como funciona

Após ativar o módulo, cada formulário de contato mostrará uma caixa de seleção "Usar ajax". Quando esta caixa de seleção está ativada, o formulário de contato mostra outra opção "Tipo de confirmação" com estas opções:

  • Carregar o formulário: enviará o formulário sem recarregar a página.
  • Carregar da mensagem personalizada: carrega um texto personalizado.
  • Carregar do nó: carrega um nó após o envio do formulário.

Este módulo pode ajudá-lo se:

  • você precisa personalizar a mensagem de confirmação
  • você precisa enviar um formulário de contato sem recarregar a página.
  • você deseja carregar um texto personalizado ou outro nó após o envio do formulário.
masdzen
fonte