Проблема с элементом radios на форме при попытке обновить через ajax

Главные вкладки

Аватар пользователя reMaster reMaster 18 декабря 2013 в 20:23

Столкнулся с проблемой обновления radios при использовании ajax callback

Пример кода:

function module_form($form, &$form_state){
    $form['radios_1'] = array(
        '#type' => 'radios',
        '#default_value' => (int)$form_state['values']['radios_2'],
        '#options' => array(1 => '1', 2 => '2', 3 => '3'),
        '#prefix' => '<div id="radios_change">',
        '#suffix' => '</div>',
    );

    $form['radios_2'] = array(
        '#type' => 'radios',
        '#default_value' => 1,
        '#options' => array(1 => '1', 2 => '2', 3 => '3'),
        '#ajax' => array(
            'callback' => 'example_callback',
            'wrapper' => 'radios_change',
        ),
    );
return $form;
}

function example_callback($form, &$form_state) {
    $form_state['rebuild'] = true;
    $form_state['values']['radios_1'] = $form_state['values']['radios_2'];
    return $form['radios_1'];
}

нашёл эту же проблему без ответа https://drupal.org/node/1446510
Значение меняется только при первом выполнении ajax

В чём подвох?
Спасибо откликнувшимся.

Комментарии

Аватар пользователя zestagio zestagio 19 декабря 2013 в 10:47

Рабочий вариант #1:

function demo_example_form($form, &$form_state) {
  $form['#tree'] = TRUE;

  // Unique hash required for updating form values in browser on ajax callback.
  $unique_hash = md5(rand());

  $form['radios_1'][$unique_hash]['radio'] = array(
    '#type' => 'radios',
    '#default_value' => isset($form_state['values']['radios_2']) ? $form_state['values']['radios_2'] : 1,
    '#options' => array(1 => '1', 2 => '2', 3 => '3'),
    '#prefix' => '<div id="radios-change">',
    '#suffix' => '</div>',
  );

  $form['radios_2'] = array(
    '#type' => 'radios',
    '#default_value' => 1,
    '#options' => array(1 => '1', 2 => '2', 3 => '3'),
    '#ajax' => array(
      'callback' => 'demo_example_ajax_callback',
      'wrapper' => 'radios-change',
    ),
  );
  return $form;
}

function demo_example_ajax_callback($form, &$form_state) {
  return $form['radios_1'];
}

Рабочий вариант #2:

function demo_example_form($form, &$form_state) {
  unset($form_state['input']);
  $form['radios_1'] = array(
    '#type' => 'radios',
    '#default_value' => isset($form_state['values']['radios_2']) ? $form_state['values']['radios_2'] : 1,
    '#options' => array(1 => '1', 2 => '2', 3 => '3'),
    '#prefix' => '<div id="radios-change">',
    '#suffix' => '</div>',
  );

  $form['radios_2'] = array(
    '#type' => 'radios',
    '#default_value' => 1,
    '#options' => array(1 => '1', 2 => '2', 3 => '3'),
    '#ajax' => array(
      'callback' => 'demo_example_ajax_callback',
      'wrapper' => 'radios-change',
    ),
  );
  return $form;
}

function demo_example_ajax_callback($form, &$form_state) {
  return $form['radios_1'];
}

Плохо искал решение, в сети куча вопросов подобного рода, вот тема на d.org https://drupal.org/node/1100170

Аватар пользователя zestagio zestagio 19 декабря 2013 в 11:27

Эта проблема не только с радиос, а почти со всеми элементами формами, для которых необходимо поменять #default_value на ajax callback, можете првоерить сами для теста. Извращения в первом случае нужны для того, что бы при каждом рендере элемента, менялся родитель и тем самым очищался так сказать ввод, во втором случае мы его и очищаем с помощью unset($form_state['input']);

Первый вариант я написал, потому что видел такое решение в нескольких контриб модулях.