Добавление элементов в форму с помощью AJAX

Для примера создадим выпадающий список с цифрами от 1 до 4, при выборе значения в котором, ниже будет появляться выбранное количество чекбоксов. Ссылка не демо.

Код, комментарии ниже:
function mymodule_dynamic_form($form, &$form_state) {
  // При сабмите формы или вызове ajax, в $form_state['values'] будут значения всех полей.
  $checkboxes_count = isset($form_state['values']) ? $form_state['values']['checkboxes_count'] : 1;
 
  $form['checkboxes_count'] = array(
    '#type' => 'select', 
    '#title' => 'Число чекбоксов', 
    '#options' => array(1 => 1, 2 => 2, 3 => 3, 4 => 4), 
    '#default_value' => $checkboxes_count,
    '#ajax' => array(
      // Функция, которая сработает при выборе значения в списке,
      // и которая должна вернуть новую часть формы
      'callback' => 'mymodule_dynamic_form_ajax_callback',
      // Id html элемента, в который будет выведена часть формы
      'wrapper' => 'checkboxes-div',
    ),
  );
 
  // Элемент, в который будет выводится новая часть формы
  $form['checkboxes'] = array(
    '#prefix' => '<div id="checkboxes-div">', 
    '#suffix' => '</div>', 
  );
 
  // Генерация элементов на основе данных из $form_state['values']
  for ($i = 1; $i <= $checkboxes_count; $i++) {
    $form['checkboxes']['checkbox' . $i] = array(
      '#type' => 'checkbox', 
      '#title' => 'Checkbox ' . $i,
    );
  }
 
  $form['submit'] = array(
    '#type' => 'submit', 
    '#value' => 'Отправить',
  );
 
  return $form;
}
 
function mymodule_dynamic_form_ajax_callback($form, $form_state) {
  return $form['checkboxes'];
}
 
function mymodule_dynamic_form_submit($form, $form_state) {
  debug($form_state['values']);
}

Основной момент — логика, по которой элементы добавляются в форму, должна быть размещена в конструкторе формы. Т.е. цикл, генерирующий чекбоксы, должен быть размещён в функции mymodule_dynamic_form(), а не в ajax калбэке mymodule_dynamic_form_ajax_callback().

По началу это взрывает мозг, но объясню почему надо делать именно так.

Конструктор формы вызывается на всех этапах работы с формой — при создании, при валидации, при отправке, при ajax запросах. Ajax калбэки же вызываются только при событии, на которое они навешены. И если бы логика создания новых элементов была в них, то к этим элементам невозможно было бы получить доступ на любом другом из перечисленных этапов, плюс к таким элементам нельзя бы было подцепиться из hook_form_alter(). Единственная задача ajax калбэка — это вернуть либо часть формы, подготовленной в конструкторе, либо набор команд для ajax фреймворка.

Понять, на каком этапе вызывается конструктор формы можно по наличию данных в $form_state['values'].

Написанное актуально для
Drupal 7.x
Теги:
ajax, работа с формами
Добавлено: 29 Июля 2018 20:44:51 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...