#autocomplete_path в элементах textfield
Иногда возникает необходимость для удобства ввода данных создать поле с автозаполнением(autocomplete field). Примерами таких полей могут быть виджеты для cck-полей Node reference i User reference.
Рассмотрим программное создание такого рода полей. Согласно Drupal Forms API reference свойство #autocomplete_path можно добавить только для элемента texfield. Это свойство определяет путь, по которому автоматически включенный JavaScript-код Друпала пошлет HTTP-запросы, используя JQuery.
Первым делом, объявим textfield в форме:
<?php
$form['example'] = array(
'#type' => 'textfield',
'#title' => t('Example Textfield'),
'#autocomplete_path' => 'products/autocomplete',
);
?>
Теперь в hook_menu() определим callback для нашего автозаполнения:
<?php
/**
* Implementation of hook_menu
*/
function module_menu() {
$items['products/autocomplete'] = array(
'page callback' => 'module_products_autocomplete',
'type' => MENU_CALLBACK,
'access arguments' => array('administer nodes'),
);
return $items;
}
?>
И в завершение нам нужно описать саму функцию обратного вызова, которая передаст некий массив функции drupal_json():
<?php
function module_products_autocomplete($string) {
$matches = array();
$res = db_query("SELECT title, nid FROM {node} WHERE LOWER(title) LIKE LOWER('%s%%')", $string);
while ($row = db_fetch_array($res)) {
$matches[$row['nid']] = $row['title'];
}
drupal_json($matches);
}
?>
Теперь у вас есть полноценное автозаполняющееся поле.
Но очень часто бывает нужно передавать некие параметры функции автозаполнения. В моем случае нужно было передать массив идентификаторов нод, и в автокомплит подятигивать только ноды с этого массива. Для этого в hook_menu() определяем page arguments:
<?php
/**
* Implementation of hook_menu
*/
function module_menu() {
$items['products/autocomplete/%'] = array(
'page callback' => 'module_products_autocomplete',
'page arguments' => array(2),
'type' => MENU_CALLBACK,
'access arguments' => array('administer nodes'),
);
return $items;
}
?>
Вносим некоторые поправки в определение свойства #autocomplete_path для textfield'a:
<?php
//получаем массив $nids с идентификаторами нод
$string_nids = implode('|', $nids);
$form['example'] = array(
'#type' => 'textfield',
'#title' => t('Example Textfield'),
'#autocomplete_path' => "products/autocomplete/{$string_nids}",
);
?>
Параметр $string автоматически передается функции автозаполнения посредством API. Если вы хотите передать дополнительные аргументы, поместите их перед $string:
<?php
function module_products_autocomplete($arg2, $string) {
$matches = array();
$nids = explode('|', $arg2);
$res = db_query("SELECT title, nid FROM {node} WHERE LOWER(title) LIKE LOWER('%s%%') AND nid IN (" . db_placeholders($nids, 'int') . ")", array_merge(array($string), $nids));
while ($row = db_fetch_array($res)) {
$matches[$row['nid']] = $row['title'];
}
drupal_json($matches);
}
?>
Друпал визуализирует вышенаписанное примерно так:


