JQuery UI Autocomplete - поиск с начала строки

Сегодня мне захотелось написать маленький, но очень полезный пост о плагине автодополнения текстовых полей 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);
    });
};
                    

После переопределения метода в списке предложений для автокомплита будут только варианты, начинающиеся с введённых в поле символов.