Как выглядит автозаполнение запроса / ответа сервера? - PullRequest
61 голосов
/ 22 февраля 2011

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

Какой параметр передается на сервер и как должен выглядеть ответ JSON?

Должно быть, я что-то упустил, потому что как все остальные научились это делать? Кажется, что сайты обсуждают только код JavaScript на стороне клиента, а не примеры протоколов или серверов.

Мне нужно достаточно, чтобы работал самый простой удаленный пример.

Ответы [ 6 ]

68 голосов
/ 22 февраля 2011

Какой параметр передается на сервер

Вам необходимо передать request.term в свой код на стороне сервера (из документации):

Объект запроса с единственным свойством, называемым «term», который ссылается на значение, которое в данный момент находится в текстовом вводе.

По сути, в вашем коде autocomplete вы получите что-то вроде этого:

$("#autocomplete").autocomplete({
    // request.term needs to be passed up to the server.
    source: function(request, response) { ... }
});

и как должен выглядеть ответ JSON?

Виджет autocomplete ожидает массив объектов JSON со свойствами label и value(хотя, если вы просто укажете value, он будет использоваться в качестве метки).Так что в простейшем случае вы можете просто вернуть данные, которые выглядят следующим образом:

[
    { label: 'C++', value: 'C++' }, 
    { label: 'Java', value: 'Java' }
    { label: 'COBOL', value: 'COBOL' }
]

Если вам нужно что-то более сложное, вы можете использовать аргумент success функции $.ajax для нормализации данныхвы вернетесь до того, как автозаполнение получит его:

source: function( request, response ) {
    $.ajax({
        /* Snip */
        success: function(data) {
            response($.map( data.geonames, function( item ) {
                return {
                    label: item.name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName,
                    value: item.name
                }
            }));
         }
    });

Этот код взят из примера здесь (Это хороший общий пример работы ajax + autocomplete в более сложном сценарии),

По сути, при успешном выполнении запроса ajax полученные данные нормализуются (с использованием $.map) в соответствии с ожиданиями виджета автозаполнения.

Надеюсь, это поможет.

24 голосов
/ 10 октября 2011

В дополнение к идеальному ответу Эндрю Уитакера, альтернативный метод $ .map - это переопределение рендерера, , пример которого показан на демонстрационной странице пользовательского интерфейса jQuery.

Iиспользовали эту функциональность, используя вызов JSON, например:

Ответ JSON

{
   "Records": [
       {
           "WI_ID": "1",
           "Project": "ExampleProject",
           "Work_Item": "ExampleWorkItem",
           "Purchase_Order": "",
           "Price": "",
           "Comments": "",
           "Quoted_Hours": "",
           "Estimated_Hours": "",
           "Achieved": "False",
           "Used_Hours": "0"
       }
   ]
}

jQuery

$("#WorkItem").autocomplete({
      source: function(request, response){
           $.ajax({
               type: "POST",
               url: "ASPWebServiceURL.asmx/WorkItems",
               data: "{'Project_ID':'1'}",
               contentType: "application/json; charset=utf-8",
               dataType: "json",
               success: function (msg) {
                   response($.parseJSON(msg.d).Records);
               },
               error: function (msg) {
                   alert(msg.status + ' ' + msg.statusText);
               }
           })
       },

       select: function (event, ui) {
           $("#WorkItem").val(ui.item.Work_Item);
           return false;
       }
})
.data("autocomplete")._renderItem = function (ul, item) {
    return $("<li></li>")
    .data("item.autocomplete", item)
    .append("<a>" + item.Work_Item + "</a>")
    .appendTo(ul);
};

В этом примере _renderItemФункция переопределяется так, что список результатов поиска (т. е. список, который появляется под текстовым полем) заполняется с использованием атрибутов записей, которые я извлек из ответа JSON.

Хотя это не так просто, он позволяет вамВыделите некоторые довольно интересные вещи (например, используя несколько бит данных из ответа JSON)

7 голосов
/ 01 марта 2014

Оба ответа пока сложны и вводят в заблуждение, ключевым понятием jQuery UI Auto Complete является анонимная функция успеха, вы можете использовать / контролировать формат ответа JSON на стороне сервера из-за успешного обратного вызова AutoComplete.Метка, формат значения подходит для подражания, но вы можете определить любой желаемый формат JSON, ключ в том, как вы определяете свою функцию успеха:

 <input id="refPaymentTerms" class="form-control">

$("#refPaymentTerms").autocomplete({
                source: function (request, response) {
                    $.ajax({
                        type: "POST",
                        url: "/admin/JobPaymentRefs",
                        dataType: "json",
                        data: {
                            term: request.termCode
                        },
                        error: function (xhr, textStatus, errorThrown) {
                            alert('Error: ' + xhr.responseText);
                        },
                        success: function (data) {
                            response($.map(data, function (item) {
                                return {
                                    label: item.label,
                                    value: item.value
                                }
                            }));
                        }
                    });
                }
            });

Контроллер MVC:

public JsonResult JobPaymentRefs()
    {
        var query = from REFTerm in _db.REFTerms
                     select new
                    {
                        label = REFTerm.TermCode,
                        value = REFTerm.TermCode
                    };
        //var refTerms = _db.REFTerms.Select(x => x.TermCode);

        return Json(query.ToArray());
    }

Здесь мы видим очень стандартное автоматическое связывание с серверной частью ASP.NET.

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

2 голосов
/ 03 декабря 2013

Вы не обязаны настраивать сценарий на стороне сервера, чтобы использовать автозаполнение пользовательского интерфейса jQuery. Вы можете указать функцию JavaScript как source для создания пользовательских запросов (например, использовать POST или GET, использовать параметры строки запроса, которые ожидает сценарий на стороне сервера) и обрабатывать произвольные ответы ( например, обрабатывать ответы XML).

Сказав это, когда вы используете строку в качестве параметра source, тогда:

[...] плагин автозаполнения ожидает, что эта строка будет указывать на URL ресурс, который будет возвращать данные JSON. Это может быть на том же хосте или на другой (должен предоставить JSONP). Плагин автозаполнения не фильтруйте результаты, вместо этого добавляется строка запроса с полем term , который серверный скрипт должен использовать для фильтрации результатов. За Например, если опция источника установлена ​​на http://example.com и пользовательские типы foo, запрос GET будет сделан для http://example.com?term=foo. Сами данные могут быть в том же формате как местные данные, описанные выше.

Относительно "Данные могут быть в том же формате, что и локальные данные, описанные выше" , будут работать следующие форматы JSON (или JSONP):

// no matching entries
[]

// array of strings
[
"Option 1",
"Option 2"
]

// array of objects with label property
[{
    "label": "Option 1"
}, {
    "label": "Option 2"
}]

// array of objects with value property
[{
    "value": "Option 1"
}, {
    "value": "Option 2"
}]

// array of objects with label and value properties
[{
    "label": "Option 1",
    "value": 1
}, {
    "label": "Option 2",
    "value": 2
}]

Для массивов объектов вы можете указать дополнительные свойства помимо метки и / или value. Все свойства будут доступны внутри обратных вызовов.

1 голос
/ 18 августа 2017

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

var $url = "http://some-url/get-json";
//name is the id of the textbox where autocomplete needs to be shown
$('#name').autocomplete(
{ 
source: function(request,response)  
{ 

  //gets data from the url in JSON format
  $.get($url, function(data)
  {         
    obj = JSON.parse(data);   //parse the data in JSON (if not already)
    response($.map(obj, function(item)
    {
      return {
        label: item.full_name,
        value: item.full_name,
        id:item.id,
        email:item.email,
        phone:item.phone,
      }
    }
  ));        //end response
});          //end get
},
select:function(event, ui)
{ 
 console.log(ui.item.full_name);
 console.log(ui.item.email);
}   

}); //end of autocomplete
0 голосов
/ 27 сентября 2013
<!doctype html>

<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>jQuery UI Autocomplete - Categories</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
        <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
        <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
        <link rel="stylesheet" href="/resources/demos/style.css" />
        <style>
            .ui-autocomplete-category {
                font-weight: bold;
                padding: .2em .4em;
                margin: .8em 0 .2em;
                line-height: 1.5;
            }
            body {
                font-family: "Trebuchet MS", "Helvetica", "Arial", "Verdana", "sans-serif";
                font-size: 62.5%;
            }
        </style>
        <script>
            $.widget("custom.catcomplete", $.ui.autocomplete, {
                _renderMenu : function(ul, items) {
                    var that = this, currentCategory = "";
                    $.each(items, function(index, item) {
                        if (item.category != currentCategory) {
                            ul.append("<li class='ui-autocomplete-category'>" + item.category + "</li>");
                            currentCategory = item.category;
                        }
                        that._renderItemData(ul, item);
                    });
                }
            });
        </script>
        <script>
            $(function() {
                $("#search").catcomplete({
                    delay : 0,
                    source : function(request, response) {
                        $.ajax({
                            url : "search",
                            dataType : "json",
                            data :"searchText=hk",
                            success : function(data) {
                                response(data);
                            } //success
                        });
                    }
                });
            });
        </script>
    </head>
    <body>enter code here
        <label for="search">Search: </label>
        <input id="search" />
    </body>
</html>
...