AutoComplete - расширяемый плагин автозаполнения на jQuery

Хотя и с большим опозданием (я обещала написать об этом плагине ещё 3 месяца назад), но я всё-таки пишу о простом, но довольно интересном плагине автозаполнения на jQuery.
Интересен он своей расширяемостью и тем, что при наличии прямых рук и небольшого знания jQuery и php из него можно сделать практически что угодно.

Примеры

Сначала посмотрим несколько примеров работы плагина.

Простой выбор

Начните вводить слово, и вы увидите список подходящих слов.


Множественный выбор

Слова нужно вводить через запятую. Этот вариант хорошо подходит для работы с тегами.


Выбор города

Следующие три поля для ввода связаны между собой - в первом вы выбираете страну, во втором - регион, и в третьем - город.
Варианты подбираются с учетом того, что было введено в предыдущих полях.
Страна

Регион или область

Город
Кроме того, с плагином можно взаимодействовать через клавиши вверх-вниз, Enter и Esc.

Параметры

Теперь обратим внимание на параметры, которые принимает плагин. Их совсем немного.

url – адрес, к которому будет обращаться скрипт.

onClose — функция, которая позволяет изменить параметры исчезания блока.

Например:

Исчезание с функцией fadeOut

Исчезание с функцией hide

Исчезание без анимации


dataSend — функция возвращает параметры для отправки на сервер.

wordClick — функция, которая, как видно по её названию, срабатывает при нажатии на выбранное слово.


Код

Теперь посмотрим на код плагина:
jQuery.fn.ac = function(o) { // объявление функции
	var o = $.extend({     // параметры по умолчанию
		url:'/upload/ac/ajax.php',  // URL для поиска слов
		onClose:function(suggest) {  // функция, которая срабатывает при закрытии окна с подсказками
			setTimeout(function(){
				suggest.slideUp('fast'); // плавно закрывает окно
			}, 100); // через 100 мс
		},
		dataSend:function(input) {  // функция, возвращающая данные для отправки на сервер
			return 'suggest_name=' + input.attr('name') + '&query=ac&word=' + word;
		},
		wordClick:function(input,link) { // функция, которая срабатывает при добавлении слова в input
			input.val(link.attr('href')).focus();
		}
	}, o);

	return $(this).each(function(){ // каждое поле для ввода
		var onClose = o.onClose;
		var input = $(this); // присваиваем переменной input
		input.after('<div class="auto-suggest"></div>'); // после него вставляем блок для подсказок
		var suggest = input.next(); // присваиваем его переменной
		suggest.width(input.width() + 6); // выставляем для него ширину
		input.blur(function(){ // когда input не в фокусе
			if (suggest.is(':visible'))  {  // если подсказки не скрыты
				input.focus(); // фокусируемся на input'e
				onClose(suggest); // и скрываем подсказки
			}
		}).keydown(function(e) {  // при нажатии клавиши
			if (e.keyCode == 38 || e.keyCode == 40) { // если эта клавиша вверх или вниз
	   			var tag = suggest.children('a.selected'),  // находим выделенный пункт
	   			new_tag = suggest.children('a:first'); // и первый в списке
	   			if (tag.length) { // если выделение существует
	   			   	if (e.keyCode == 38) { // нажата клавиша вверх
	   			   		if (suggest.children('a:first.selected').length) {  // и выделен первый пункт
		                	                new_tag = suggest.children('a:last'); // выделяем последний
		   			        } else {  // иначе
		   				        new_tag = tag.prev('a');  // выделяем предыдущий
		   			        }
		   		        } else { // иначе
		   			        if (!suggest.children('a:last.selected').length) new_tag = tag.next('a'); // выделяем следующий
		   		        }
		   		        tag.removeClass('selected'); // снимаем выделение со старого пункта
		    	        }
		    	        new_tag.addClass('selected');   // добавляем класс выделения
	                        input.val(new_tag.attr('href')); // заменяем слово в поле ввода
		    	        return;
		        }
		        if (e.keyCode == 13 || e.keyCode == 27) {   // если нажата клавиша Enter или Esc
	   		        onClose(suggest); // закрываем окно
		    	        return;
		        }
	        }).keyup(function(e) {
	       	        if (e.keyCode == 38 || e.keyCode == 40 || e.keyCode == 13 || e.keyCode == 27) return; // если нажата одна из вышеперечисленных клавиш, выходим
			        word = input.val(); // добавляем переменную со значением поля ввода
			        if (word) { // если переменная не пуста
				        $.post(o.url, o.dataSend(input), function(data){  // отправляем запрос
					        if (data.length > 0) { // если есть список подходящих слов
						        suggest.html(data).show().children('a').click(function(){ // функция, срабатывающая при нажатии на слово
							        o.wordClick(input,$(this)); // пользовательская функция, объявленная выше
							        return false;
						        });
					        } else {  // если нет
						        onClose(suggest); // закрываем окно
					        }
				        });
			        } else { // если переменная пуста
	    		                onClose(suggest); // закрываем окно
			        }
		       });
	});
}

Server-side

Для правильной работы плагина ответ от сервера должен поступать в следующем виде:
<a href="это вставляется в поле ввода">это показывается пользователю</a>
<a href="это вставляется в поле ввода">...
Пример:
<a href="пиала"><b>пи</b>ала</a>
<a href="пианизм"><b>пи</b>анизм</a>
<a href="пианино"><b>пи</b>анино</a>
<a href="пианист"><b>пи</b>анист</a>
<a href="пианола"><b>пи</b>анола</a>
<a href="пиастр"><b>пи</b>астр</a>
<a href="пивко"><b>пи</b>вко</a>
<a href="пивная"><b>пи</b>вная</a>
<a href="пивник"><b>пи</b>вник</a>
<a href="пивница"><b>пи</b>вница</a>
Ещё один пример:
<a href="пробег, контекст"><b>конт</b>екст</a>
<a href="пробег, контора"><b>конт</b>ора</a>
<a href="пробег, контра"><b>конт</b>ра</a>
<a href="пробег, контракт"><b>конт</b>ракт</a>
<a href="пробег, контраст"><b>конт</b>раст</a>
<a href="пробег, контроль"><b>конт</b>роль</a>
<a href="пробег, контрпар"><b>конт</b>рпар</a>
<a href="пробег, контузия"><b>конт</b>узия</a>
<a href="пробег, контур"><b>конт</b>ур</a>

Поддержка плагина браузерами

  • IE 6+ (в седьмом IE проблемы с позиционированием)
  • Opera
  • Firefox
  • Safari
  • Chrome


По всем вопросам, связанным с работой плагина, обращайтесь в комментарии.
Удачи.



Комментарии

10 ноября 2010, 11:15 (Ответить)
Как осуществить множественный выбор для работы с тегами? Все перерыл, ничего не нашел. Вот только тут пример увидел. Подскажите, плпз!
10 ноября 2010, 16:08 (Ответить)
petrik86, множественный выбор осуществляется на стороне сервера.
В моём примере PHP код для выборки подходящих слов выглядит примерно так:
$search = $_POST['название_поля_автозаполнения'];
$search_arr = explode(',',$search);
$search = trim(array_pop($search_arr));
$search_before = ($search_arr? implode(',',$search_arr).', ' : '');
if (!$search) exit;
$result = mysql_query('запрос_к_базе');  
$len = strlen($search);
while ($row = mysql_fetch_assoc($result)) {
	$word = $row['название_столбца_с_тегами'];
	echo '<a href="'.$search_before.$word.'"><b>'.substr($word,0,$len).'</b>'.substr($word,$len).'</a>';  
	// если вам не нужно выделение жирным набранной части
	// оставьте просто echo '<a href="'.$search_before.$word.'">'.$word.'</a>';
}

Если будут вопросы, задавайте.
10 ноября 2010, 16:45 (Ответить)
Спс, попробую.
10 ноября 2010, 17:30 (Ответить)
Странно, но скрипт обработки на сервере не получает POST запрос? url в самом плагине поменял, имя поля выставил.
Вот если на скриптом выводить echo "123";
тогда работает, а вот ПОСТ переменная пустая.
Заменил на $_REQUEST['q'], не помогло.
Что может быть такое?
10 ноября 2010, 19:05 (Ответить)
petrik86, попробуйте вывести содержимое переменной $_POST:
var_dump($_POST);

И напишите, что у вас получилось.
10 ноября 2010, 19:16 (Ответить)
array(3){["suggest_name"]=>string(1)"q"["query"]=>string(2)"ac"["word"]=>syring(1)"вы"}

Во что выводит.
10 ноября 2010, 19:29 (Ответить)
Теперь работайте с переменной $_POST['word'], насколько я поняла, там и содержится часть введённого вами слова.
10 ноября 2010, 20:32 (Ответить)
Ух, все получилось. Еще были проблемы с кодировкой. Помогло $search = iconv('UTF-8','windows-1251',$search);

Огромное спасибо тебе !
10 ноября 2010, 20:53 (Ответить)
petrik86, была рада помочь :)
14 декабря 2010, 15:39 (Ответить)
Добрый день, не могли бы вы выложить исходный код реализации выбора городов, немного не понятно как и где происходит зависимость от выше выбранных значений!...
17 декабря 2010, 14:59 (Ответить)
привет
не работает выбор значений из списка с помощью стрелок на клаве.
может быть ли проблема быть связана с версткой?
брал исходники с сайта и никаких правок в них не делал.
заранее спасибо за любую помощь
17 декабря 2010, 15:09 (Ответить)
вообщем в коде поставил пробелы между

suggest.children('a:first .selected')
(!suggest.children('a:last .selected') и вроде заработало. так и не смог понять в чем глюк.
6 января 2011, 17:23 (Ответить)
к сожалению, у плагина есть огромный недостаток.
если подряд вводить слово из 10 букв - он отправит 10 запросов вместо одного. т.е. нет задержки на обработку.

а кто автор этого плагина?
6 января 2011, 17:32 (Ответить)
и еще один момент юзабилити. было бы не плохо, если после выбора подсказанного варианта на клавиатуре и нажатия ввода форма не отправлялась
27 января 2011, 18:40 (Ответить)
Егор, ок, я доработаю этот момент. Спасибо.
14 февраля 2011, 17:37 (Ответить)
Подскажите пожалуйста, как к этому скрипту реализовать задержку при наборе букв.

Как сказал Егор - "если подряд вводить слово из 10 букв - он отправит 10 запросов вместо одного. т.е. нет задержки на обработку."

Что не есть гуд. спасибо.
1 мая 2011, 19:11 (Ответить)
У меня вопрос тот же, что и у Andrey, а точнее на счёт исходников. Проблемы с реализацией выбора возникли.
6 июня 2011, 18:16 (Ответить)
Здравствуйте, recens!
Меня очень заинтересовал Ваш метод "autocomplete" "Выбор города". Вы не могли бы дать исходники подобного метода для реализации у себя на сайте?
6 июня 2011, 18:16 (Ответить)
Я был бы очень признателен Вам.
16 июня 2011, 16:33 (Ответить)
дайте пожалуйста исходники примера, интересует php
9 сентября 2011, 17:12 (Ответить)
Здравствуйте.
У меня выводится длинный список, поэтому я сделала его с прокруткой. Проблема в том, что, при клике на полосу прокрутки, список скрывается. Нормально работает только в FF.
Можно ли как-то решить эту проблему?
7 октября 2011, 16:02 (Ответить)
круто,спасибо)
4 ноября 2011, 21:03 (Ответить)
То что нужно... талант у вас... респектую
5 января, 21:58 (Ответить)
Здравствуйте, recens!
Меня очень заинтересовал Ваш метод "autocomplete" "Выбор города". Вы не могли бы дать исходники подобного метода для реализации у себя на сайте?
31 марта, 10:46 (Ответить)
базу бы с городами выложили под "выбор города"

Добавить комментарий