• статья
  • pantey

Создаем ajax автодополнение для текстового поля формы

13.01.2016

Сегодня мы займемся реализацией Ajax автодополнением для текстового поля формы в Drupal 7. Скорее всего, вы не раз уже такое встречали на различных сайтах. Например, нечто подобное используется во всех популярных поисковых системах, при вводе какого-либо запроса в поисковую строку, что значительно увеличивает взаимодействие пользователя с сайтом.

Использование автодополнения в поисковых системах

Для начала, давайте определимся с задачей. Нам необходима форма, с текстовым полем, которая при вводе текста будет предлагать нам соответствующие данному запросу заголовки нод.

Приступим, создадим форму и выведем ее в блок. Как это сделать уже не раз писалось на этом сайте, поэтому я выложу уже готовый код модуля. Кстати, мой модуль будет называться ajax_autocomplete

Файл ajax_autocomplete.info
  1. name = Ajax Autocomplete
  2. description = Формирует автодополнения для формы
  3. package = Other
  4. core = 7.x
  5. version = 7.x-1.0
Файл ajax_autocomplete.module
  1. <?php
  2.  
  3. /**
  4.  * Implements hook_block_info()
  5.  */
  6.  
  7. function ajax_autocomplete_block_info(){
  8. $blocks = array();
  9. $blocks['ajax_autocomplete'] = array(
  10. 'info' => t('Form Ajax Autocomplete'),
  11. 'cache' => DRUPAL_CACHE_PER_ROLE,
  12. );
  13. return $blocks;
  14. }
  15.  
  16. /**
  17.  * Implements hook_block_view()
  18.  */
  19. function ajax_autocomplete_block_view($delta='') {
  20. $block = array();
  21. if($delta == 'ajax_autocomplete' ){
  22. $output = drupal_get_form('ajax_autocomplete_form');
  23. $block['subject'] = t('Form Ajax Autocomplete');
  24. $block['content'] = $output;
  25. }
  26. return $block;
  27. }
  28.  
  29. /**
  30.  * Implements hook_form()
  31.  */
  32. function ajax_autocomplete_form(){
  33.  
  34. $form['text'] = array(
  35. '#type' => 'textfield',
  36. '#title' => 'Заголовок ноды'
  37. );
  38.  
  39. $form['submit'] = array(
  40. '#type' => 'submit',
  41. '#value' => 'Поиск'
  42. );
  43.  
  44. return $form;
  45.  
  46. }

Включаем модуль, выводим блок в необходимый нам регион и смотрим результат.

Создали форму

Как мы видим форма у нас появилось, по сабмиту у нас естественно ничего не происходит, ибо это нам и не нужно в нашем примере. Теперь приступаем к реализации автодополнения.

Саму реализацию, можно разделить на несколько этапов:

  • Подключить библиотеку drupal.ajax, ибо автодополнение будет работать через Ajax
  • Зарегистрировать страницу, к которой будет отправляться запрос при вводе текста
  • Написать ajax callback, которая будет принимать входящие данные пользователя и на основе это формировать список с подходящими по запросу заголовками нод
  • «Сказать» текстовому полю, что необходимо использовать автодополнение
Подключаем библиотеку drupal.ajax
  1. /**
  2.  * Implements hook_init
  3.  */
  4. function ajax_autocomplete_init() {
  5. drupal_add_library('system', 'drupal.ajax');
  6. }
Регистрируем страницу
  1. /**
  2.  * Implements hook_menu
  3.  */
  4. function ajax_autocomplete_menu(){
  5.  
  6. $items['ajax-autocomplete'] = array(
  7. 'page callback' => 'ajax_autocomplete_search',
  8. 'access arguments' => array('access content'),
  9. 'type' => MENU_CALLBACK,
  10. );
  11.  
  12. return $items;
  13.  
  14. }
Пишем ajax callback
  1. /**
  2.  * Ajax Callback
  3.  */
  4. function ajax_autocomplete_search($title){
  5.  
  6. $matches = array();
  7. $result = db_select('node', 't')
  8. ->fields('t', array('title'))
  9. ->condition('title', '%' . db_like($title) . '%', 'LIKE')
  10. ->range(0, 10)
  11. ->execute()
  12. ->fetchAll();
  13.  
  14. foreach ($result as $row) {
  15. $matches[$row->title] = check_plain($row->title);
  16. }
  17.  
  18. drupal_json_output($matches);
  19.  
  20. }

Говорим текстовому полю, что необходимо использовать автодополнение, для этого дописываем текстовому полю свойство #autocomplete_path, где в качестве значения указываем путь до зарегистрированной нами страницы, в результате наше поле примет следующий вид

  1. $form['text'] = array(
  2. '#type' => 'textfield',
  3. '#title' => 'Заголовок ноды',
  4. '#autocomplete_path' => 'ajax-autocomplete',
  5. );

После чего чистим кеш сайта и смотрим результат

Создали автодополнение для текстового поля

Как мы видим все у нас работает.

Полный код модуля:
  1. <?php
  2.  
  3. /**
  4.  * Implements hook_block_info()
  5.  */
  6.  
  7. function ajax_autocomplete_block_info(){
  8. $blocks = array();
  9. $blocks['ajax_autocomplete'] = array(
  10. 'info' => t('Form Ajax Autocomplete'),
  11. 'cache' => DRUPAL_CACHE_PER_ROLE,
  12. );
  13. return $blocks;
  14. }
  15.  
  16. /**
  17.  * Implements hook_block_view()
  18.  */
  19. function ajax_autocomplete_block_view($delta='') {
  20. $block = array();
  21. if($delta == 'ajax_autocomplete' ){
  22. $output = drupal_get_form('ajax_autocomplete_form');
  23. $block['subject'] = t('Form Ajax Autocomplete');
  24. $block['content'] = $output;
  25. }
  26. return $block;
  27. }
  28.  
  29. /**
  30.  * Implements hook_form()
  31.  */
  32. function ajax_autocomplete_form(){
  33.  
  34. $form['text'] = array(
  35. '#type' => 'textfield',
  36. '#title' => 'Заголовок ноды',
  37. '#autocomplete_path' => 'ajax-autocomplete',
  38. );
  39.  
  40. $form['submit'] = array(
  41. '#type' => 'submit',
  42. '#value' => 'Поиск'
  43. );
  44.  
  45. return $form;
  46.  
  47. }
  48.  
  49. /**
  50.  * Implements hook_init
  51.  */
  52. function ajax_autocomplete_init() {
  53. drupal_add_library('system', 'drupal.ajax');
  54. }
  55.  
  56. /**
  57.  * Implements hook_menu
  58.  */
  59. function ajax_autocomplete_menu(){
  60.  
  61. $items['ajax-autocomplete'] = array(
  62. 'page callback' => 'ajax_autocomplete_search',
  63. 'access arguments' => array('access content'),
  64. 'type' => MENU_CALLBACK,
  65. );
  66.  
  67. return $items;
  68.  
  69. }
  70.  
  71. /**
  72.  * Ajax Callback
  73.  */
  74. function ajax_autocomplete_search($title){
  75.  
  76. $matches = array();
  77. $result = db_select('node', 't')
  78. ->fields('t', array('title'))
  79. ->condition('title', '%' . db_like($title) . '%', 'LIKE')
  80. ->range(0, 10)
  81. ->execute()
  82. ->fetchAll();
  83.  
  84. foreach ($result as $row) {
  85. $matches[$row->title] = check_plain($row->title);
  86. }
  87.  
  88. drupal_json_output($matches);
  89.  
  90. }

Скачать написанный в примере модуль можно здесь.

-->
Узнавай о новых статьях сайта - первым. Просто подпишись на рассылку.