Реализация динамической формы

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

Аватар пользователя Tazik@drupal.org Tazik@drupal.org 19 января 2010 в 1:54

Добрый день.
В ходе изучения друпал возник такой вопрос.
Как реализовать такую форму:
есть несколько зависимых выпадающих списков, а также зависимые от них радиобаттоны, чекбоксы, кнопка "поиск", по нажатию которой значения полей передаются обработчику, который полученные значения ищет в базе, находит их, выводит на экран.

Пробывал для решения данной задачи следующие модули:
conditional fields, но он полезен лишь в создании типов публикации;
web form - не дает зависимости между полями;
есть еще вариант использовать таксономию + views, но тоже немного не то...

Искал решение задачи на форумах... есть похожие темы, но даже на эти похожие темы толком никто ответить не может. Уверен у многих возникает такая задача. Помогите кто чем может Smile

Комментарии

Аватар пользователя gorr gorr 19 января 2010 в 3:34

Думаю придется самостоятельно писать, hierarchical_select справляется только с многоуровневыми словарями.., а у Вас задача, как понимаю посложнее..

Аватар пользователя retuam retuam 19 января 2010 в 9:40

К сожалению, данный функционал в 6-ке отсутствует, самый подходящий модуль, это Hierarchical_Select. С данной проблемой сталкиваюсь часто, пока решаю связкой PHP+Ajax, а выводить можно на страницу формируемую на лету модулем Views, отправляя в url в качестве аргументов значение формы. Форму можно создать с помощью WebForms.
Все это относится к прямой связи, когда "А" связано с "Б", "Б" с "В", "В" с "Г" и т.д., вообщем такого же вида, как для Hierarchical_Select (т.е. древовидная структура). Очевидно, что наличие более сложных связей требует более сложного решения.
Есть путь через API Drupal, здесь я еще не пробился, нет достаточных знаний :(.

Аватар пользователя Dan Dan 19 января 2010 в 10:59

Есть примеры на этом сайте. Даже HOW TO кто-то выкладывал.
Вот мой вариант:

/**
 * Implementation of hook_menu().
 */

function ahahtest_menu(){
  // Создаём обработчик для AHAH-запросов
  // код обработчика - ниже
  $items['ahahtest/autocomplete'] = array(
    'title' => 'Ahahtest autocomplete',
    'page callback' => 'ahahtest_autocomplete',
    'access arguments' => array('access content'),
    'type' => MENU_CALLBACK,
   );
  return $items;
}

// Создаём форму. Здесь, как самый частый случай, форма выбора региона-города
function ahahtest_my_form($form_state){

  // получаем список регионов
  $regions = /* код пропущен */;

  $form['region'] = array(
    '#type' => 'select',
    '#title' => 'Регион',
    '#options' => array('0' => '-- Выберите регион -- ') + $regions,
    '#default_value' => 0,
    // Задаём AHAH-обработчик
    '#ahah' => array(
      'path'    => 'ahahtest/autocomplete',
      'wrapper' => 'ahahtest-town-select',
      'method'  => 'replace',
      'event'   => 'change',
      'effect'  => 'fade',
    ),
  );
  $form['town'] = array(
    '#type' => 'select',
    '#title' => 'Город',
    '#options'       => array( 0 => '-- Не выбран регион -- '),
    '#default_value' => 0,
    '#disabled'      => true,
    '#prefix' => '<div id="ahahtest-town-select">',
    '#suffix' => '</div>',
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Search'),
  );
  return $form;
}

// Код обработчика
function ahahtest_autocomplete(){
 
  // Строим новую форму
  $form_state = array('submitted' => FALSE);
  $form_build_id = $_POST['form_build_id'];

  // Получаем текущую форму из кэша
  $form = form_get_cache($form_build_id, $form_state);

  // Из пост берём нужные переменные, в данном случае - $_POST['region']
  // и на их основании делаем выборку из БД
  $options = /* код пропущен */;

  // Обновляем элемент формы...
  $form['town']['#disabled']      = false;
  $form['town']['#default_value'] = 0;
  $form['town']['#options']       = $options;

  // и сохраняем в кэше
  form_set_cache($form_build_id, $form, $form_state);
           
  $form += array(
    '#post' => $_POST,
    '#programmed' => FALSE,
  );

  // Перестраиваем форму
  $form = form_builder('ahahtest_my_form', $form, $form_state);

  // Рендер элемента формы и отправка клиенту
  $output = drupal_render($form['town']);
  drupal_json(array('status' => TRUE, 'data' => $output));
}

Аватар пользователя retuam retuam 15 февраля 2010 в 20:21

Да, действительно. Пригодилось, применил решение. Спасибо. А как решить вопрос того, чтобы в результате обработки формы информация выводилась в определенный слой или блок без перезагрузки страницы?

Аватар пользователя sadmin sadmin 15 февраля 2010 в 21:46

Рассматривал пример из Вандюка, [user=penexe] дал дельный совет. Сохранил решение - по запросу изменяется текст в диве. Вместе с решением от [user=Dan], приведенным выше, реализуется вывод отработанной формы.