Alterar $ form_state no retorno de chamada AJAX

16

Estou criando um formulário que usa o '#ajax'atributo API do formulário e preciso fazer alterações $form_statequando o botão ativado para AJAX for pressionado. Aqui está o que eu tenho:

Dentro da minha função de construtor de formulários:

...
$form['some_fieldset']['add_more'] = array(
      '#type' => 'button',
      '#value' => t('Add more rows'),
      '#ajax' => array(
        'wrapper' => 'some-fieldset',
        'callback' => 'my_module_settings_ajax',
        'method' => 'replace',
        'effect' => 'fade',
      ),
    );

...

E aqui está a função de retorno de chamada:

function my_module_settings_ajax($form, $form_state) { 
  // Make a change to $form_state
  if ($form_state['some_fieldset']['add_more']) {
    $form_state['values']['some_fieldset']['table'][] = array('first_field' => '',
                                                                'second_field' => '');
  }

  return $form['some_fieldset'];
}

A alteração que fiz $form_stateparece perdida quando o retorno de chamada termina. Existe alguma maneira de fazer uma alteração $form_statenessa função ou alguma outra função que eu deva usar para isso?

EDITAR

Como se vê, o retorno de chamada é o lugar errado para fazer essa lógica. Em vez disso, na parte superior da função do construtor de formulários, adicionei isso:

// Respond to AJAX-triggger:
// Add new row
if ($form_state['triggering_element']['#name'] == 'add_more') {
  $form_state['values']['some_fieldset']['table'][] = array('first_field' => '',
                                                                'second_field' => '');
}

Claro, tive que dar o nome ao botão:

$form['some_fieldset']['add_more'] = array(
  '#type' => 'button',
  '#name' => 'add_more', // <-- Right here
  '#value' => t('Add more rows'),
  '#ajax' => array(
    'wrapper' => 'some-fieldset',
    'callback' => 'my_module_settings_ajax',
    'method' => 'replace',
    'effect' => 'fade',
  ),
);

E agora funciona!

MW.
fonte

Respostas:

3

Você precisa passar $form_statecomo referência; a função AJAX precisa ser definida como no exemplo a seguir:

function mymodule_settings_ajax($form, &$form_state) { /* … */ } 
nourcy
fonte
Para esclarecer, você precisa que o & passe por referência e não por valor. Sem ele, você está apenas modificando uma cópia do $ form_state.
Malks
Sim, se você não fizer isso, apenas modificará uma variável local.
Nourcy
1
Claro, não pensei nisso. Infelizmente, isso não teve nenhum efeito - qualquer alteração feita em $ form_state é ignorada no construtor de formulários e, da próxima vez que a chamada AJAX for feita, $ form_state será revertido. Será que o formulário já foi gerado no momento em que o retorno de chamada é executado? Existe uma maneira de executar um manipulador de envio personalizado para esse botão?
MW.
Tente alterar o tipo de botão para enviar
nourcy
0

Não tenho certeza de que seja uma resposta direta à sua pergunta, mas pode funcionar para o seu caso de uso: Em vez de alterar o $ form_state, adicione valores ao seu $ form. Se você não quer que eles mostrem apenas use #hidden.

Malks
fonte