Задача:
Есть три поля CCK (типа select list)
страна, регион, город;
В БД есть соответствующие таблицы.
Я заполняю поле "Страна" из бд, к примеру так
<?php$con = db_result(db_query("SELECT COUNT(*) FROM {country}")); // выборка количества записей
$id1 = db_query("SELECT name FROM {country}"); // получаем данные
for ($i = 0; $i < $con; $i++)
{
$result=db_result($id1,$i); // в масив их
$items[$i] = $result;
}
return $items; // возвращаем массив?>
После выбора страны, select list "Город" Должен заполниться городами, этой страны, из таблицы БД - city.
Собственно вопрос, как это реализовать?
Комментарии
Hierarchical select
не вариант. с cck не работает. для 6 ки тока dev версия.
Я так предполагаю, нужно что то ajax вское делать... но вот только как...
предполагается что при выборе, каково то значения, в селект листе, должна отправлятся какая либо переменная на сервер...
вот, как реализовать отправку переменой на сервер по выбору, значения из select box
Hierarchical select хорошая вещь. Жалко что не работает с последней версией jquery. Для CCK пока такое не делал, но только что реализовал именно такой функционал в форме своего модуля. Если надо выложу код. Он не идеален, но со своей задачей справляется.
да, было бы неплохо. Код, можно и доработать, если будут изменения с моей стороны, доработки итд, все вышлю вам. А возможно создам свой модуль на основе вашего, результатом так же поделюсь.
выслать можно на nnc1701e(символ собачки)mail.ru
Можно и под CCK заточить
Допустим у нас есть 2 селекта. При выборе значения в первом должны загружаться значения во второй. Следующий вариант конечно не идеален, т.к. используется массив $_POST и сначала во 2-й селект загружаются все его возможные значения. Но со своей задачей справляется.
Код формы:
'#type' => 'select',
'#title' => t('Country'),
'#options' => array(
'1' => t('Россия'),
'2' => t('Кипр'),
'3' => t('Украина'),
),
'#ahah' => array(
'path' => 'path/to/callback',
'wrapper' => 'edit-city-container',
'method' => 'replace',
),
'#weight' => 0,
);
$form['location']['city'] = array(
'#type' => 'select',
'#title' => t('City'),
'#options' => my_get_cities(), //Загрузка всех элементов, которые могут быть выбраны в элементе
'#prefix' => '<div id="edit-city-container">',
'#suffix' => '</div>',
'#weight' => 5,
);
Хук меню:
$items['path/to/callback'] = array(
'page callback' => 'my_print_city_options',
'type' => MENU_CALLBACK,
'access callback' => TRUE,
);
return $items;
}
Коллбек:
$element = array(
'#name' => 'city',
'#id' => 'edit-city',
'#title' => t('City'),
'#parents' => array('location'),
'#options' => my_get_cities($_POST['country']),
);
print drupal_json(theme('select', $element));
exit;
}
Функция my_get_cities:
$sql = ($cid)?"SELECT id, name FROM {table_name} WHERE id = %d":'SELECT id, name FROM {table_name}';
$res = db_query($sql, $cid);
while ($row = db_fetch_object($res)){
$options[$row->id] = $row->name;
}
return $options;
}
Весь модуль выкладывать не стал, т.к. этот текст по счастливому случаю у меня уже был готов, а кода в нем на несколько сотен строк поболее будет. Если с этим у вас не получится отправлю.
спасибо. буду побывать)
вышел релиз http://drupal.org/project/hierarchical_select[/module] для шестерки обошолся средствами предлагаемыми этим модулем.
С jquery 1.3 работает?
Работает. Чему очень рад.
Наконец-то вкурил как решить эту проблему в CCK силами своего модуля. Способ нашел здесь http://drupal.org/node/390452. Если кому интересно подготовлю и выложу код.
Однозначно интересно.
Предположим у нас 2 селекта - марки и модели автомобилей. Соответственно при выборе марки загружаются модели.
field_model - модели
field_marka - марки
В hook_form_alter:
$form['field_model']['#suffix'] = '< /div>';
$form['field_marka']['#ahah']['path'] = 'path/to/callback';
$form['field_marka']['#ahah']['event'] = 'click';
$ahah_binding = array(
"button" => false,
"keypress" => null,
'url' => url('path/to/callback'),
'event' => 'change',
'wrapper' => 'edit-model-container',
'selector' => '#edit-field-marka-value',
'effect' => 'fade',
'method' => 'replace',
'progress' => array('type' => 'throbber'),
);
drupal_add_js('misc/jquery.form.js');
drupal_add_js('misc/ahah.js');
drupal_add_js(array('ahah' => array('edit-field-marka-value' => $ahah_binding)), 'setting');
А вот коллбек:
<?php
//если элемент вложен в какой-либо контейнер заполняем массив parents
function callback(){
$element = array(
'#name' => 'field_model[value]',
'#id' => 'edit-field-model-value',
'#title' => t('Model'),
//'#parents' => array(),
//берем из базы массив типа id => 'value'
'#options' => my_get_models($_POST['field_marka']['value']),);
print drupal_json(theme('select', $element));
exit;
}
?>
Вот как-то так. Опять таки не идеально но работает. Если что пишите.
подписался
Очень актуальная тема! Спасибо, g00dvin!!! Ждем продолжения! Можете показать Ваш сайт?
Да пожалуйста! Какой сайт вы имеете в виду? Блог или что?
Вот разобрал еще один метод.
У нас 2 CCK селекта - field_main и field_sub.
id формы - my_type_node_form
В первый в варианты значений занесем такой php-массив
<?phpreturn array('one', 'two', 'three');?>
Во второй
<?phpreturn array('one-one', 'two-one', 'two-two', 'three-one', 'three-two', 'three-three');?>
В модуле
* Implementation of hook_menu().
*/
function mymod_menu() {
$items['path/to/callback'] = array(
'page callback' => 'mymod_simple_callback',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Implementation of hook_form_alter().
*/
function mymod_form_alter(&$form, $form_state, $form_id) {
switch ($form_id) {
case 'my_type_node_form':
$form['field_main']['#pre_render'][] = 'my_cck_main_field_pre_render';
$form['#pre_render'][] = 'my_form_pre_render';
break;
}
}
function my_cck_main_field_pre_render($element) {
$element['value']['#ahah'] = array(
'event' => 'change',
'path' => 'path/to/callback',
'wrapper' => 'edit-field-sub-value-wrapper',
'method' => 'replace',
);
form_expand_ahah($element['value']);
return $element;
}
function my_form_pre_render($form) {
$form['field_sub']['value']['#options'] = my_return_value($form['field_main']['value']['#default_value']);
return $form;
}
function mymod_simple_callback(){
$element = array(
'#name' => 'field_sub[value]',
'#id' => 'edit-field-sub-value',
'#title' => t('New element'),
'#parents' => array('field_sub'),
'#options' => my_return_value($_POST['field_main']['value']),
);
drupal_json(theme('select', $element));
}
function my_return_value($param){
$items = array(
0 => array('' => '- None -', 0 => 'one-one'),
1 => array('' => '- None -', 1 => 'two-one', 2 => 'two-two'),
2 => array('' => '- None -', 3 => 'three-one', 4 => 'three-two', 5 => 'three-three'),
);
return ($items[$param])?$items[$param]:array('' => '- None -');
}
Тоже работает. А вообще делать надо конечно по-другому. В коллбеке надо извлекать форму из кеша, перестраивать её, потом заносить в кеш и возвращать элемент. В своих формах так делать можно и нужно. Тот первый блок кода который я здесь выложил нужно переписать чем сегодня и займусь. Но с CCK пока так не научился.
Очень хотелось бы знать о результатах Вашей работы! Давно ищу простое решения динамических select-полей для своего сайта. К сожалению, навыками для написания скриптов не обладаю :(.
Недавно создал модуль облегчающий эту задачу http://95.143.220.95:85/projects/ahah-helper/repository (модуль сырой, но рабочий)
На базе этого модуля уже создал иерархию подобно Страна -> Город -> Улица -> Дом
Причем получить обработку можно на любом шаге. Все вызовы подписаны ключем, благодаря ему несложно определить какой контрол произвел вызов и передачу данных.
Тогда из готового к употреблению только HierarchicalSelect.
Было бы всё хорошо, но у меня простые cck-поля, а не таксономия.
Спасибо огромное! Знать бы теперь, как это прикручивается к Друпалу)
Там 2 модуля. Один из них Demo.
А с content_taxonomy не работает?