Конфигурация поиска виджета jQuery UI Autocomplete

Я пытаюсь использовать виджет автозаполнения пользовательского интерфейса jQuery для реализации поиска пользователей по имени или фамилии. Похоже, что по умолчанию автозаполнение ищет слова по последовательности символов независимо от их вхождения в слове. Поэтому, если у вас есть такие данные, как: javascript, asp, haskell и вы javascript, asp, haskell 'as' вы получите все три. Я хотел бы, чтобы это соответствовало только началу слова. Таким образом, в приведенном выше примере вы получаете только 'asp'. Есть ли способ настроить виджет автозаполнения для этого?

В конечном итоге было бы еще лучше сопоставить по имени или фамилии, как в Gmail.

Примечание: я пытаюсь найти способ сделать это с помощью виджета jQuery UI. Поскольку в моем проекте уже используется пользовательский интерфейс jQuery, я планирую придерживаться его и не добавлять дополнительные библиотеки в свое веб-приложение.

Ответ 1

В jQuery UI v1.8rc3, виджет автозаполнения принимает source, который может быть либо строкой, либо массивом, либо функцией обратного вызова. Если это строка, автозаполнение делает GET на этом URL-адресе, чтобы получить параметры/предложения. Если массив, автозаполнение выполняет поиск, как вы указали, для наличия типизированных символов в любой позиции в терминах массива. Окончательный вариант - это то, что вы хотите - функция обратного вызова.

Из документации автозаполнения:

Третий вариант, обратный вызов, обеспечивает максимальную гибкость и может использоваться для подключения любого источника данных к автозаполнению. Обратный вызов получает два аргумента:

• Объект request с единственным свойством, называемым "term", который ссылается на значение, которое в настоящее время присутствует в текстовом вводе. Например, когда пользователь вводил "новое лет" в поле города, которое настроено на выполнение автозаполнения, request.term будет удерживать "новый год".
• Функция response, обратный вызов, который ожидает, что один аргумент будет содержать данные, предлагаемые пользователю. Эти данные должны быть отфильтрованы на основе предоставленного термина и должны быть массивом в формате, разрешенном для простых локальных данных: String-Array или Object-Array с меткой/значением/оба свойства.

Пример кода:

var wordlist= [ "about", "above", "across", "after", "against",
                "along", "among", "around", "at", "before", 
                "behind", "below", "beneath", "beside", "between", 
                "beyond", "but", "by", "despite", "down", "during", 
                "except", "for", "from", "in", "inside", "into", 
                "like", "near", "of", "off", "on", "onto", "out", 
                "outside", "over", "past", "since", "through", 
                "throughout", "till", "to", "toward", "under", 
                "underneath", "until", "up", "upon", "with", 
                "within", "without"] ; 

$("#input1").autocomplete({
    // The source option can be an array of terms.  In this case, if
    // the typed characters appear in any position in a term, then the
    // term is included in the autocomplete list.
    // The source option can also be a function that performs the search,
    // and calls a response function with the matched entries.
    source: function(req, responseFn) {
        var re = $.ui.autocomplete.escapeRegex(req.term);
        var matcher = new RegExp( "^" + re, "i" );
        var a = $.grep( wordlist, function(item,index){
            return matcher.test(item);
        });
        responseFn( a );
    }
});

Несколько ключевых моментов:

  • вызов $.ui.autocomplete.escapeRegex(req.term);, который ускоряет поиск так что любые регулярные выражения, содержащиеся в тексте, введенном пользователем, рассматриваются как простой текст. Например, точка (.) Имеет смысл для регулярного выражения. Я узнал об этой функции escapeRegex, прочитав исходный код автозаполнения.
  • строка с new Regexp(). Он задает регулярное выражение, начинающееся с ^ (Circumflex), что подразумевает, что оно будет соответствовать только тогда, когда типизированные символы появятся в начале члена в массиве, чего вы хотели. Он также использует опцию "i", которая подразумевает нечувствительность к регистру.
  • утилита $.grep() просто вызывает предоставленную функцию для каждого термина в предоставленном массиве. Функция в этом случае просто использует regexp, чтобы увидеть, соответствует ли член в массиве для того, что было напечатано.
  • наконец, responseFn() вызывается с результатом поиска.

рабочая демонстрация: http://jsbin.com/ezifi

как выглядит:

alt text

Просто примечание: я считаю, что документация по автозаполнению будет довольно незрелой на данный момент. Я не нашел примеров, которые сделали это, и я не мог найти рабочий документ, для которого необходимы файлы .css или какие классы .css будут использоваться. Я узнал все это от проверки кода.

См. также как я могу настроить параметры подключаемого модуля Autocomplete?

Ответ 2

Я использую автозаполнение от Devbridge. http://www.devbridge.com/projects/autocomplete/jquery/

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

alt text

Что касается сопоставления на основе имени или фамилии, вам просто нужно предоставить список поиска с именем и фамилией.

Пример использования:

  var wordlist = [
      'January', 'February', 'March', 'April', 'May', 'June',
      'July', 'August', 'September', 'October', 'November',
      'December' ]; 

      var acOptions = {
          minChars:2,
          delimiter: /(,|;)\s*/, // regex or character
          maxHeight:400,
          width:300,
          zIndex: 9999,
          deferRequestBy: 10, // miliseconds

          // callback function:
          onSelect: function(value, data){
              //$('#input1').autocomplete(acOptions);
              if (typeof data == "undefined") {
                  alert('You selected: ' + value );
              }else {
                  alert('You selected: ' + value + ', ' + data);
              }
          },

          // local autosuggest options:
          lookup: wordlist
      };

Опция lookup которую вы передаете для инициализации элемента управления автозаполнением, может быть списком или объектом. Выше показан простой список. Если вы хотите, чтобы к предложениям были возвращены некоторые данные, то сделайте опцию lookup объектом, например так:

var lookuplist = {
    suggestions:   [ "Jan", "Feb", "Mar", "Apr", "May" ],
    data :         [ 31, 28, 31, 30, 31, ]
};

Ответ 3

спасибо cheeso для создания jsbin.com,

i расширил ваш код для поддержки совпадений с первым и последним.

  $("#input1").autocomplete({
      source: function(req, responseFn) {
          addMessage("search on: '" + req.term + "'<br/>");

          var matches = new Array();
          var needle = req.term.toLowerCase();

          var len = wordlist.length;
          for(i = 0; i < len; ++i)
          {
              var haystack = wordlist[i].toLowerCase();
              if(haystack.indexOf(needle) == 0 ||
                 haystack.indexOf(" " + needle) != -1)
              {
                  matches.push(wordlist[i]);
              }
          }

          addMessage("Result: " + matches.length + " items<br/>");
          responseFn( matches );
      }
  });

demo: http://jsbin.com/ufimu3/

введите 'an' или 're'

Ответ 4

Если вы хотите найти начало каждого слова в строке, более элегантным решением для ханчмана является использование cheeso, но просто используйте специальный символ границы слова регулярного выражения:

var matcher = new RegExp( "\\b" + re, "i" );

Пример: http://jsbin.com/utojoh/2 (попробуйте найти 'bl')

Ответ 5

Theres еще один подключаемый модуль автозаполнения jQuery, который по желанию выполняет поиск только в начале каждого элемента (опция matchContains=false, я думаю, что это тоже значение по умолчанию).

Учитывая отсутствие такой опции в плагине jQuery UI, я предполагаю, что вам придется либо использовать другой плагин, либо переписать тот, который вы используете сейчас.

Ответ 6

Где вы получаете данные для заполнения автозаполнения? Это из базы данных? Если это так, вы можете делать то, что хотите в своем запросе, и возвращать результаты, соответствующие началу каждого слова (имя/фамилия)