jQuery UI Автозаполнение конфигурации поиска виджетов - PullRequest
65 голосов
/ 04 марта 2010

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

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

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

Ответы [ 6 ]

127 голосов
/ 09 марта 2010

В jQuery UI v1.8rc3, виджет автозаполнения принимает параметр source , который может быть либо строкой, массивом, либо функцией обратного вызова. Если это строка, autocomplete выполняет 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() просто вызывает предоставленную функцию для каждого члена в указанном массиве. Функция в этом случае просто использует регулярное выражение, чтобы увидеть, совпадает ли термин в массиве с тем, что было введено.
  • наконец, responseFn () вызывается с результатом поиска.

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

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

alt text

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

См. Также, как мне отформатировать результаты плагина автозаполнения?

6 голосов
/ 05 марта 2010

Я использую автозаполнение от 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, ]
};
5 голосов
/ 09 марта 2010

спасибо за представление jsbin.com,

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

  $("#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 );
      }
  });

демо: http://jsbin.com/ufimu3/

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

2 голосов
/ 16 августа 2011

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

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

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

0 голосов
/ 08 марта 2010

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

0 голосов
/ 08 марта 2010

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

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

...