Сегодня мне захотелось написать маленький, но очень полезный пост о плагине автодополнения текстовых полей jquery ui autocomplete, который сейчас используется повсеместно, как и сама библиотека jquery ui. Суть работы плагина, думаю, рассказывать никому не надо - пользователь вводит кусочек фразы в текстовый инпут, а плагин предлагает её завершение в виде выпадающего списка. Существует 2 режима - когда поиск совпадений осуществляется на сервере или же когда список возможных вариантов автозаполнения указывается в js массиве при инициализации плагина. В первом случае всё понятно - вы сами определяете в своём серверном скрипте принципы поиска. А вот во втором случае может возникнуть проблемка, ведь данный плагин по умолчанию настроен на поиск любого вхождения поискового запроса, и в нём нет опции для поиска, к примеру, от начала строки.
Когда это может потребоваться?
Собственно говоря, именно тогда, когда необходим поиск точной фразы от начала строки, то есть, когда поиск любого вхождения неэффективен. Представьте себе, что имеете дело с полем ввода города, а в вариантах автокомплита помимо города у каждого айтема в скобочках указана область, и вот при вводе областного центра в предложениях получается лажа. Введём "Яросл":
- Ярославль (Ярославская)
- Ростов (Ярославская)
- Рыбинск (Ярославская)
- Тутаев (Ярославская)
- Переславль-Залесский (Ярославская)
- ... итд, в общем, в предложениях окажутся все города этой области :(
Как сделать, чтобы поиск шёл от начала строки?
Находил в сети решение, в котором при инициализации плагина определялся атрибут source, и в нём прописывалась логика поиска. Поскольку мне зачастую приходится использовать виджет CJuiAutoComplete из Yii Framework, а в нём очень удобно source передавать как php массив, предлагаю, на мой вкус, более элегантное решение:
/*
* Переопределяем метод "filter" плагина
* По сути, он отличается только регулярным выражением, точнее, символом "^",
* "приклеивающим" поиск к началу строки :)
*/
$.ui.autocomplete.filter = function (array, term) {
var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(term), "i");
return $.grep(array, function (value) {
return matcher.test(value.label || value.value || value);
});
};
После переопределения метода в списке предложений для автокомплита будут только варианты, начинающиеся с введённых в поле символов.