Хочу сделать форму для сайта по заправки картриджей.
Необходимо чтобы посетитель заполнил зависимые поля Принтер>Серия>модель>картридж и на основе этих данных ниже через ajax при нажатии кнопки вывелось ему стоимость заправки выбранного картриджа.
Каждое последующее поле списка, должно содержать данные относительно выбранного предыдущего.
Не понимаю как это реализовать. Какие способы и методы выбрать. Направьте пожалуйста.
Комментарии
Смотри примеры ajax форм https://www.drupal.org/project/examples
Огромное спасибо за примеры! Многое теперь стало доступно. Но к сожалению моего случая там нет((
Вам поможет параметр #ajax в элементе формы, например кнопке. Иногда, если форма большая, бывает полезно просто создать ajax-команду.
Спасибо. Ajax в моей форме уж точно будет. Да и без него реализовать обновление второго селлекта никак.
http://xandeadx.ru/blog/drupal/893
По ссылке совсем не то. Там последовательно показывающиеся элементы формы. А мне нужно чтобы от выбранного первого селекта (Родительский термин таксономии) менялся второй селект (с дочерними терминами таксономии выбранного родительского термина). Потом после выбора во втором селекте, в третьем уже подгружались соответствующие заголовки нод. И потом при нажатии сабмита, это все дело подсчитывалось и аджаксом выводилось значение (или значение полей ноды).
Ну ровно то, что вам нужно никто не разжуёт и не положит в рот. По ссылке концепт работы формы через ajax. Какую логику туда засунуть - дело ваше.
да, дело в том, что мне не нужно разжовывать. Я просто уперся в стену и не могу продвинутся. Не могу получить значение. Пробую брать переменную $form_state['values']['field_select']. А она пустая постоянно(
Уфф... Парни. Не делал еще ниразу модули и с form API тоже. Решил все это изучить. Вроде получается но появилась загвоздка. Первый селект кое как вывел. А вот после введенного значения получить id таксономии для второго и подставить варианты его дочерних, что то не могу догнать.
Оочень нужна ваша помощь. Вот мой код:
<?php
/**
* Создаю страницу формы
*/
function Mymodule_menu() {
$items = array();
$items['Mymodule'] = array(
'title' => 'Form API',
'page callback' => 'drupal_get_form',
'page arguments' => array('Mymodule_form'),
'access callback' => TRUE
);
return $items;
}
/**
* Реализация hook_form() Создаем форму
*/
function Mymodule_form() {
$vid = 2; // id словаря таксономии
$parent = taxonomy_get_tree($vid, 0, 1);
$form['field_select'] = array(
'#prefix' => '<div id="wrappp">',
'#suffix' => '</div>',
'#type' => 'select',
'#title' => t('Селект'),
'#ajax' => array(
'callback' => 'reload_selekt_ajax_callback',
'wrapper' => 'wrappp',
),
);
foreach ($parent as $key => $val) {
$form['field_select']['#options'][] = $val->name;
}
// Описал кнопку отправки форму
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('отправить форму'),
'#ajax' => array(
'callback' => 'Mymodule_ajax_callback',
'wrapper' => 'Mymodule-form',
'event' => 'click',
),
);
return $form;
}
/**
* Реализация hook_ajax_callback()
*/
function Mymodule_ajax_callback($form, &$form_state) {
return $form;
}
function reload_selekt_ajax_callback($form, &$form_state) {
return $form['field_select'];
}
?>
Получите, распишитесь.
<?php
// id словаря таксономии;
$form['select_wrapper'] = array(
$tree = taxonomy_get_tree($vid, 0, 1);
$tree = array_map('get_object_vars', $tree);
$form['actions']['submit'] = array(
/**
* Создаю страницу формы
*/
function mymodule_menu() {
$items = array();
$items['mymodule'] = array(
'title' => 'Form API',
'page callback' => 'drupal_get_form',
'page arguments' => array('mymodule_form'),
'access callback' => TRUE,
);
return $items;
} /**
* Form builder for mymodule.
*/
function mymodule_form($form, &$form_state) {
$form['#wrapper_id'] = drupal_clean_css_identifier(__FUNCTION__) . '-wrapper';
$form['#prefix'] = "<div id='{$form['#wrapper_id']}'>";
$form['#suffix'] = "</div>";
$vid = 15;
'#type' => 'fieldset',
'#title' => t('Select wrapper'),
'#description' => t('Select wrapper'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#tree' => TRUE
);
$tids = array_column($tree, 'tid');
$term_names = array_column($tree, 'name');
$form['select_wrapper'][0] = array(
'#type' => 'select',
'#title' => 'Селект для термина 0',
'#options' => array_combine($tids, $term_names),
'#weight' => 0,
'#ajax' => array(
'callback' => 'mymodule_form_ajax_callback',
'wrapper' => $form['#wrapper_id'],
),
);
if(!empty(
$form_state['storage']['selected_terms'])){$form['select_wrapper']['result'] = array(
'#type' => 'markup',
'#markup' => implode(', ', $form_state['storage']['selected_terms'])
);
}
'#type' => 'actions'
);
$form['actions']['submit'] = array(
'#type' => 'submit',
// В функцию t() передавать строку только на английском
'#value' => t('Submit'),
'#ajax' => array(
'callback' => 'mymodule_form_ajax_callback',
'wrapper' => $form['#wrapper_id'],
'event' => 'click',
),
);
return $form;
} /**
* Form validate for mymodule_form().
*/
function mymodule_form_validate($form, &$form_state) {
// Логика валидации.
// Для запуска сабмит функции когда форму сабмитит селект.
$form_state['submitted'] = true;} /**
* Form submit for mymodule_form().
*/
function mymodule_form_submit($form, &$form_state) {
form_state_values_clean($form_state);
$vals = &$form_state['values'];
$form_state['storage']['selected_terms'] = $vals['select_wrapper'];
$form_state['rebuild'] = TRUE;
} /**
* Реализация hook_ajax_callback()
*/
function mymodule_form_ajax_callback($form, &$form_state) {
return $form;
}
?>
О, супер. Работает, и выдает нужный айди. Сейчас буду разбираться как реализовано. Много новых функций. Вижу что и через валидацию нужно прогонять.
Теперь дальше буду выводить подкатегорию и зависимую ноду. Потом результат ниже формы.
mbaev, спасибо огромное за подсказку. И спасибо за свой способ реализации формы на данном этапе. Филдсет сворачивающийся мне не нужен, поэтому его убрал.
@mbaev - прекрасный пример! Спасибо! Будет мне левел-ап....
Нюанс: [man=array-column]array_column()[/man] - только с 5.5 работает, для версий ниже - рекомендуют самим реализовать.
Ну, а если все поддерживается - можно трохи упростить:
<?php
// Вместо:
$tids = array_column($tree, 'tid');
$term_names = array_column($tree, 'name');
// и потом:
$form['select_wrapper'][0] = array(
'#options' => array_combine($tids, $term_names),
); // Просто:
$terms = array_column($tree, 'name', 'tid');
// и в:
$form['select_wrapper'][0] = array(
'#options' => $terms,
); // Или, даже сразу:
$form['select_wrapper'][0] = array(
'#options' => array_column($tree, 'name', 'tid'),
);
?>
Спасибо, хорошая находка!
Сначала была одна такая функция, потом я добавил еще одну для $tids в другом месте, а потом они оказались рядом. Ну короче не стал оптимизировать до идеала.
Там по ссылке "своя реализация" слишком сложная. Достаточно так
<?php
$tids = array_map(function ($item) {return $item->tid:}, $tree);
$term_names = array_map(function ($item) {return $item->name;}, $tree);
?>
только тогда не нужно конвертировать объекты в массивы, перед этим
<?php
$tree = array_map('get_object_vars', $tree);
?>
Эт не я )) официальный ман рекомендует.
Я так полагаю через функцию нужно получать значение? А какая функция должна быть?
Ребят, можете скинуть ссылку со всеми функциями для form API? А то в Form API на друпале.орг одни атрибуты.
Да, и не поймите меня не правильно. Перед тем как вопрос задать. Два дня мучаюсь над ним.
Зачем так усложнять жизнь посетителям?
Всмысле усложнять? Наоборот облегчаю. Вместо того чтобы в огромном списке всех картреджей посетитель выбирал нужный ему и узнавал цену. Я ему делаю форму, где он выберит нужный принтер, нужную модель и нужный картридж, получит цену на заправку. Все просто. ))) хотя на деле реализации этой формы, все очень слооожно)
Я Вам удивляюсь ребята. - примеров ajax форм и в коробке достаточно.
sas@drupal.org, где эти примеры? в exemples нет такой реализации. Там есть только вывод ноды. А зависимых селектов нет! А ajax мне нужен только для того чтобы он обновил информацию в последующих селектах. (Категория таксаномии>подкатегория таксаномии>Заголовок ноды>Вывод нескольких полей ноды ниже формы)
Там есть примеры зависимых селетов на ajax е и не один.
Вангую, что добавите обратно, потому что в сабмит функции очень удобно получать:
<?php
$selected_terms = $form_state['values']['select_wrapper'];
?>
вместо
<?php
$selected_terms[] = $form_state['values'][1];
$selected_terms[] = $form_state['values'][2];
$selected_terms[] = $form_state['values'][3];
?>