Изменить $ form_state в обратном вызове AJAX

16

Я создаю форму, которая использует '#ajax'атрибут API формы , и мне нужно внести изменения, $form_stateкогда нажата кнопка с поддержкой AJAX. Вот что у меня есть:

Внутри моей функции конструктора форм:

...
$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',
      ),
    );

...

А вот и функция обратного вызова:

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

$form_stateПохоже, что изменение, которое я сделал , потеряно после завершения обратного вызова. Есть ли способ внести изменения $form_stateв эту функцию, или есть какие-то другие функции, которые я должен использовать вместо этого?

РЕДАКТИРОВАТЬ

Как выясняется, обратный вызов - неправильное место для этой логики. Вместо этого, в верхней части функции конструктора форм, я добавил это:

// 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' => '');
}

Конечно, мне пришлось дать кнопке название:

$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',
  ),
);

И теперь это работает!

МВт.
источник

Ответы:

3

Вам нужно передать $form_stateкак ссылку; функция AJAX должна быть определена как в следующем примере:

function mymodule_settings_ajax($form, &$form_state) { /* … */ } 
nourcy
источник
Чтобы уточнить, вам нужно & передать по ссылке, а не по значению. Без этого вы только изменяете копию $ form_state.
Малкс
Да, если вы этого не сделаете, вы измените только локальную переменную.
Nourcy
1
Конечно, не думал об этом. К сожалению, это не имело никакого эффекта - любое изменение, внесенное в $ form_state, игнорируется в конструкторе форм, и при следующем вызове AJAX, $ form_state отменяется. Может ли быть так, что форма уже сгенерирована ко времени выполнения обратного вызова? Есть ли способ запустить собственный обработчик отправки для этой кнопки?
МВт.
Попробуйте изменить тип с кнопки для отправки
nourcy
0

Я не уверен, что это прямой ответ на ваш вопрос, но он может работать в вашем случае: вместо изменения $ form_state добавьте значения в вашу форму $. Если вы не хотите их показывать, просто используйте #hidden.

Malks
источник