В разрабатываемом проекте (под Drupal v.5) понадобилось создать много разных иерархических списков: пользователь выбирает значение первого уровня, далее ему показываются данные, относящиеся к выбранной категории, и т.д. для реализации выбора Страна-Город-Университет/Школа, Производитель-Марка-модель машины и т.п.
Есть замечательный модуль http://drupal.org/project/hierarchical_select (далее HS), который:
1. Сохраняет всю цепочку выбора пользователя
2. Позволяет конфигурировать до какого уровня пользователь должен/может выбирать данные, на каких уровнях пользователь может создавать свои данные/уровни.
3. Позволяет конфигурировать количество выбранных пользователем элементов
4. Предоставляет возможности конфигурации dropbox (участка, где выводится выбранная цепочка)
Кроме того, есть модуль http://drupal.org/project/content_taxonomy, который позволяет добавлять выбранные в hierarhical_select данные в поле CCK. Но. Для версии Друпал 5 на момент написания данного сообщения модуль находится в dev-версии, и не позволяет (как показали тесты в домашних условиях) сохранять несколько значений из HS для нода.
После изучения API Hierarchical Select сделала модуль с формой выбора университета (в моем случае) используя словарь Таксономии и сохранение и отображение всех выбранных пользователем элементов. Дальнейшие действия по удалению уже выбранного, отображению формы в виде вкладки/пункта меню, вывод "себе подобных" рассмотрю в отдельной записи, тут же хочу остановиться на создании формы с Hierarchical Select и получении значений из нее по Submit.
Итак, последовательность действий:
1. Скачать с http://drupal.org/project/hierarchical_select модуль.
2. Скачать и установить согласно инструкциям jQuery Update 2.x с http://drupal.org/project/jquery_update
3. Через admin/content/taxonomy создать новый Vocabulary, Заполнить обязательные к заполнению поля и пометить в пункте Hierarchy: как Single. Остальными настройками можно пренебречь, все равно далее данные будут выводиться через форму.
4. Создать форму (в комментариях к строкам я указываю, какие поля и для чего нужны)
function university_select_nameform() {
$form['select_some_term'] = array(
//указываем тип данного как hierarchical_select, а не как select
'#type' => 'hierarchical_select',
//заголовок для поля
'#title' => t('Select your university, please, or create own'),
//размер отображаемых в поле select строчек
'#size' => 1,
'#config' => array(
'module' => 'hs_taxonomy', //обязательное поле.
'params' => array(
'vid' => 5, //ссылка на id созданного ранее Vocabulary
'exclude_tid' => 0, //этого и следующего параметра нет в описании API, но без их указания не работает форма
'root_term' => 0, // поэтому значения тут стоят 0. Если у кого-то есть идеи, что сюда подставить - отпишитесь в комментариях, пожалуйста
),
'save_lineage' => 1, //Сохранять или нет всю цепочку выбора в формате "страна-город-университет" или просто последнее выбранное значение
'enforce_deepest' => 0, //Заставлять или нет выбирать самый глубокий (в приведенном примере: университет) пункт или принимать значение на любом уровне
'entity_count' => 0, //выводить или нет количество выбранных пунктов
'resizable' => 0, //разрешать или нет изменение размера списка (по вертикали)
'level_labels' => array( //управление labels для списков
'status' => 0, //разрешить отображение или нет
'labels' => array( //сами названия для списков (приведено просто для примера, все равно в моем случае они не будут отображаться)
0 => t('Main category'),
1 => t('Subcategory'),
2 => t('Third level category'),
),
),
'dropbox' => array( //управление отдельным блоком, куда выводятся выбранные пункты
'status' => 1, //отображать или нет
'title' => t('All selections'), //заголовок
'limit' => 0, //количество выбранных пунктов (0-без ограничений)
'reset_hs' => 1, //сбрасывать или нет выбранные пункты, после нажатия на кнопку "Add"
),
'editability' => array( //управление редактированием списков иерархии
'status' => 1, //разрешить или нет редактировать
'item_types' => array(),
'allowed_levels' => array( //на каких уровнях разрешить создание новых пунктов: 0 - не разрешать, 1 - разрешить
0 => 1,
1 => 1,
2 => 1,
),
'allow_new_levels' => 1, //разрешить или нет создание новых уровней в иерархии
'max_levels' => 3, //максимальное количество уровней
),
// These settings cannot be configured through the UI: they can only be
// overridden through code.
'animation_delay' => 400, //задержка в перерисовке выпадающих списков
'exclusive_lineages' => array(),
'render_flat_select' => 0,
),
'#default_value' => '0',
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit')
);
$form ['#tree'] = TRUE;
return $form;
}
?>
Много времени ушло на выяснение, через какое поле в Submit формы получить выбранные пользователем значения.
Оказалось, что значения передаются массивом через значение select_some_term.
Что интересно, передаются все выбранные пункты цепочки, а совпадающие значения пропускаются.
Например, если выбрать Страна1-город1-Университет1 и Страна1-город1-Университет2, то передадутся значения Страна1, город1, университет1, университет2.
Поэтому в обработчике submit пробегаемся по списку полученных значений, находим самые нижние пункты (листья), сохраняем их отдельно и используем их в зависимости от наших интересов.
Как вариант, при включенном usernode, можно сохранить связь в таблице term_node между пользователем и полученным term, для дальнейших манипуляций по поиску "своих" единомышленников, удалению/редактированию выбранных ранее пунктов и т.д.
Комментарии
Спасибо, а где надо создавать форму?
В своем модуле, куда потом уйдет дополнительная логика по работе с данными формы.
Спасибо за статью. Теперь данный подход использую в разных модулях, например, переписал для своих нужд модуль Profile (чтобы можно было выбрать район области и школу из списка).
Извиняюсь за глупый вопрос, но c Drupal’ом я познакомился недавно и сейчас на стадии альфа обучения и не понимаю, куда нужно вставить код?
- усе модули распаковал согласно выше написанным инструкциям.
- создал словарь, наполнил его терминами с единичной иерархией.
- создал CCK материал «список чего-то там очень архи важного»
- в нем нужно добавить поле типа Taxonomy Field и выбрать 1 из 4 на выбор?
А куда тогда php код? Распечатать и в письме послать на хостинг?
Понимаю что я тут не один такой, так что этим вы поможете многим будущим повелителям ядра друпала.
Будущим повелителям ядра друпала до этого топика ещё далеко
Путь в 1000 ле начинается с одного шага.
Но все равно спасибо тебе ХиЙ за то что хотя бы нашел время просмотреть мой комментарий.
Ну а какой ответ вы ожидали получить? У вас вопрос мало касается данного топика, в остальном:
- в нем нужно добавить поле типа Taxonomy Field и выбрать 1 из 4 на выбор?
Вам нужен список? Значит список и выбирать
-А куда тогда php код? Распечатать и в письме послать на хостинг?
Внимательный читать топик