问题
This seems to be a black hole: After an hour of searching the jQuery UI website, Stack Overflow, and googling, I've yet to find the most basic information of how to write the server side of the AutoComplete.
What parameter is passed to the server and what should the JSON response look like?
I must be missing something, because how did everyone else learn how to do this? Sites only seem to discuss the client-side JavaScript code and never the protocol or server-side examples.
I need enough to get the simplest remote example working.
回答1:
What parameter is passed to the server
You need to pass request.term
to your server-side code (from the documentation):
A request object, with a single property called "term", which refers to the value currently in the text input.
Basically, in your autocomplete
code, you'll have something like this:
$("#autocomplete").autocomplete({
// request.term needs to be passed up to the server.
source: function(request, response) { ... }
});
and what should the JSON response look like?
The autocomplete
widget expects an array of JSON objects with label
and value
properties (although if you just specify value
, it will be used as the label). So in the simplest case, you can just return data that looks like this:
[
{ label: 'C++', value: 'C++' },
{ label: 'Java', value: 'Java' }
{ label: 'COBOL', value: 'COBOL' }
]
If you need something more complicated, you can use the success
argument of the $.ajax
function to normalize the data you get back before the autocomplete gets it:
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
}
}));
}
});
This code is taken from the example here (This is a good example overall of ajax + autocomplete works in a more complex scenario).
Basically, what's going is that upon a successful ajax request, the data received is being normalized (using $.map
) to what the autocomplete widget expects.
Hope that helps.
回答2:
In addition to Andrew Whitaker's perfect answer, an alternative method to $.map is to override the renderer, an example of which is shown on the jQuery UI Demo page.
I have used this functionality using a JSON call like so:
JSON Response
{ "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); };
In this example, the _renderItem function is overridden so that the search result list (i.e, the list that appears under the textbox) is filled using attributes of the records that I retrieved from the JSON response.
Whilst not as simple, it allows you to pull off some pretty interesting stuff (using multiple bits of data from a JSON response, for example)
回答3:
Both answers so far are complex and misleading, a key understanding to jQuery UI Auto Complete is the success anonymous function, you have leverage/control of the format of your server side JSON response because of the success callback of AutoComplete. The label,value format is a good one to follow but you can define any JSON format you desire, the key is how you define your success function:
<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 Controller:
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());
}
Here we see a very standard auto complete bind with an ASP.NET backend.
You can return whatever format of JSON you desire server side as long as you map it correctly in the AutoComplete anonymous callback. The label,value name value pair is good enough for most requirements but do as you will server side with your JSON just map it correctly in the AutoComplete success callback.
回答4:
You are not required to tweak the server side script in order to use jQuery UI autocomplete. You can specify a JavaScript function as the source to create custom requests (e.g. use POST or GET, use query string parameters that the serever side script expects) and handle arbitrary responses (e.g. handle XML responses).
Having said that, when you use a string as the source
parameter, then:
[...] the Autocomplete plugin expects that string to point to a URL resource that will return JSON data. It can be on the same host or on a different one (must provide JSONP). The Autocomplete plugin does not filter the results, instead a query string is added with a term field, which the server-side script should use for filtering the results. For example, if the source option is set to
http://example.com
and the user types foo, a GET request would be made tohttp://example.com?term=foo
. The data itself can be in the same format as the local data described above.
Regarding "The data itself can be in the same format as the local data described above", the following JSON (or JSONP) formats will work:
// 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
}]
For the arrays of objects, you are free to specify additional properties besides label and/or value
. All properties will be available inside callbacks.
回答5:
The following code is working for me. This needs json encoded data to work. Once we get data, it modifies it according to jQuery autocomplete format and also enables selection
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
回答6:
<!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>
回答7:
The following Autocomplete is from https://jqueryui.com/autocomplete/#remote-jsonp
A demo link: https://jqueryui.com/resources/demos/autocomplete/remote-jsonp.html
Here is source code:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Autocomplete - Remote JSONP datasource</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<style>
.ui-autocomplete-loading {
background: white url("images/ui-anim_basic_16x16.gif") right center no-repeat;
}
</style>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$( function() {
function log( message ) {
$( "<div>" ).text( message ).prependTo( "#log" );
$( "#log" ).scrollTop( 0 );
}
$( "#birds" ).autocomplete({
source: function( request, response ) {
$.ajax( {
url: "search.php",
dataType: "jsonp",
data: {
term: request.term
},
success: function( data ) {
response( data );
}
} );
},
minLength: 2,
select: function( event, ui ) {
log( "Selected: " + ui.item.value + " aka " + ui.item.id );
}
} );
} );
</script>
</head>
<body>
<div class="ui-widget">
<label for="birds">Birds: </label>
<input id="birds">
</div>
<div class="ui-widget" style="margin-top:2em; font-family:Arial">
Result:
<div id="log" style="height: 200px; width: 300px; overflow: auto;" class="ui-widget-content"></div>
</div>
</body>
</html>
来源:https://stackoverflow.com/questions/5077409/what-does-autocomplete-request-server-response-look-like