I want to use typeahead to retrieve postal codes remotely and it must be post, not get. The call returns following json in the console:
{suggestions: "L-6956 | IM GRUND | KEEN-SUR-DOHEEM"}
{suggestions: "L-6956 | OP DER MOUCK | KEEN-SUR-DOHEEM"}
But the result is not shown under the input field in order to select one of the results. Here is my code:
$('#txtPostalCode').typeahead(
null,
{
name: 'txtPostalCode',
displayKey: 'suggestions',
minLength: 3,
source: function (query, syncResults) {
$.post('/hotbed/sggl/getpipedaddresses', {searchItem: query}, function (data) {
syncResults($.map(data, function (item) {
console.log(item.suggestions);
return item;
}));
}, 'json');
}
});
According to typeahead API, server response should be marked as an Async and your response should be fetched using that asyncCB,
$('#txtPostalCode').typeahead({
null
},
{
name: 'txtPostalCode',
displayKey: 'suggestions',
minLength: 3,
async: true,
source: function (query, processSync, processAsync) {
processSync(['This suggestion appears immediately', 'This one too']);
return $.ajax({
url: "/hotbed/sggl/getpipedaddresses",
type: 'POST',
data: {searchItem: query},
dataType: 'json',
success: function (json) {
// in this example, json is simply an array of strings
return processAsync(json);
}
});
}
});
since there is on open bounty for this question I cant mark it as duplicate but you might find more details at the following question,
Duplicate of this question
Related
so I use this code to make everything that has the $(".select2") element will process ajax according to the rest of the data sent via html
$(".select2").each(function () {
let element = $(this);
element.select2({
theme: "bootstrap",
placeholder: element.data("placeholder"),
ajax: {
url: element.data("url"),
dataType: 'json',
delay: 100,
cache: true,
data: function (params) { return { q: params.term } },
processResults: function (data) {
return {
results: $.map(data.results, function (item) {
return {
text: item.bank_name, /***** this *******/
id: item.id /***** this *******/
}
})
};
}
},
});
})
I've added element.data ("placeholder") and element.data ("url") in jquery, while how to send it with this html code
<select id="bank_id" name="bank_id"
class="fetch_bank form-control select2"
data-placeholder="Choose Bank"
data-url="/api/bank/fetch">
</select>
sending it ajax will return the following results
{
code: 200
error: false
message: "loaded!"
results: [
{id: 1, bank_name: "AMERICAN EXPRESS BANK LTD"},
{id: 2, bank_name: "ANGLOMAS INTERNASIONAL BANK"},
....
]
}
I have 3 records that return json, to display to select2, the column is as below
Bank(id, bank_name)
School(id, school_name)
Status(id, status)
but the problem is, how do i make 'processResults' dynamic? which I have marked with a comment / ***** this ******* /
While the 3 data has different keys, how do I make the select2 function dynamic?
thanks, I hope someone answers my question :)
I am in the biggest problem
**PLEASE DONT REPORT MY QUESTION DUPLICATE BECAUSE I DID NOT GET ANSWER FOR ASP.NET IN GOOGLE.
I am using jquery Autocomplete textbox in asp.net using web service.
my code
$('input.txtE').autocomplete({
source: function (request, response) {
$.ajax({
url: "WebServices.asmx/GetNames",
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: "{ 'txtInput' : '" + request.term + "','userName':'" + userName + "'}",
dataFilter: function (data) { return data; },
success: function (data) {
mydata = data.d;
response($.map(data.d, function (item) {
return {
label: item.split('/')[0],
val: item.split('/')[1]
}
}))
},
error: function (result) {
alert("Error");
}
});
},
multiselect: false,
minLength: 1,
delay: 0,
select: function (e, ui) {
$(hfId).val(ui.item.val);
}
});
<input type="hidden" id="hfId"/>
And my API return data in array format
["Abhishek/128", "Abyss/71", "athansiah/53", "blvsian/138", "DesmondH/91", "destined2hold/62", "dnbdesigns/94", "Dvus_lotus/85", "gserranof/47", "Illusions/89", "isaacwu111/111", "js/39"]
What I need if a user selected remove him from the autocomplete list so we can't select him again.
Please help me to short out it.
Preparation
In first, you need to store setected values. It is possible by using a global variable, hidden input control or arbitrary data associated with your control. In the following example I create an array that is associated with autocomplete control and then store selected values to the array:
$('#my-control').autocomplete({
create: function( e, ui ) {
// initialize array
$(this).data('selected', []);
},
select: function( e, ui ) {
// store unique selected values
var selected = $(this).data('selected');
if(!~selected.indexOf(ui.item.value)) {
selected.push(ui.item.value);
}
},
// another options here
});
Now it is possible to consider the selected values for list filtering.
Server-side solution
The best way is to filter the list on API server side, because it reduces transferred data amount. Just send the stored values through an AJAX request, using data option:
var $control = $('#my-control');
$control.autocomplete({
source: function (request, response) {
$.ajax({
// some AJAX options
data: {
term: request.term,
selected: $control.data('selected') // send stored values
}
});
},
// some autocomplete options here
});
Then you have to implement server-side filtration in accordance to selected query string parameter.
For example
public class AutocompleteSourceController : ApiController
{
[HttpGet]
public JsonResult<IEnumerable<MyClass>> GetItems(
[FromUri]string term,
[FromUri]int[] selected)
{
// Load data
// Fliter by term substring
// Exclude selected items
// Return the result
}
}
Client-side solution
Another way is to filter responded list on client side, using success AJAX callback. In my example I will use fake online REST API server. The server ignores the term field of query string, so I also have to implement it on client-side.
$control = $('#my-input');
$control.autocomplete({
create: function(e, ui) {
$(this).data('selected', []);
},
source: function(request, response) {
$.ajax({
url: "https://jsonplaceholder.typicode.com/users",
type: "GET",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(data) {
var items = data
// filter by term
.filter(function(user) {
return ~user.name.toLowerCase().indexOf(request.term.toLowerCase());
})
// exclude stored selected values
.filter(function(user) {
return !~$control.data('selected').indexOf(user.id);
})
// cast to an objects with label and value properties
.map(function(user) {
return {
label: user.name,
value: user.id
}
});
response(items);
},
error: function(result) {
alert("Error");
}
});
},
multiselect: false,
minLength: 1,
delay: 0,
select: function(e, ui) {
e.preventDefault();
$ctrl = $(this);
var selected = $control.data('selected');
if (!~selected.indexOf(ui.item.value)) {
// store selected value
selected.push(ui.item.value);
// set label instead of value
$ctrl.val(ui.item.label);
}
},
});
<link rel="stylesheet" type="text/css" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>
<input id="my-input" type="text">
Type L to the input control. The first item will be Leanne Graham, select it. Then clean the input field and type L again, there will no Leanne Graham in the dropdown menu. Select Ervin Howell, then clean the input field and type L again. There will be neither Leanne Graham nor Ervin Howell in the dropdown menu.
If you want to consider only current selected value, you could store only latest value instead of an array and modify the success callback and the select event handler.
Try to remove selected value from array using jQuery.
x = jQuery.grep(x, function(val) {return val != Item;});
I have two jQuery autocomplete components on my site. Both nearly exactly the same however, one displays correctly and one doesnt.
The code for the working one is:
#Html.TextBoxFor(model => model.Part, new { #id = "txtPartCode" })
$('#txtPartCode').autocomplete({
minLength: 3,
source: function (request, response) {
$.ajax({
url: apiEndpoint + 'api/Part/Filtered/' + $('#txtPartCode').val(),
method: 'GET',
dataType: 'json',
contentType: 'application/json',
success: function (data) {
response(data);
}
});
}
});
The code for the failing one is:
#Html.TextBoxFor(model => model.ParentRequestId, new { #id = "txtParentRequest" })
$('#txtParentRequest').autocomplete({
minLength: 1,
source: function (request, response) {
$.ajax({
url: apiEndpoint + 'api/Request/' + $('#txtParentRequest').val(),
method: 'GET',
dataType: 'json',
contentType: 'application/json',
success: function (data) {
response(data);
}
});
}
});
As you can see they are very similar. The response from the API for the working one is ["string1", "string2", "string3"] and for the broken one is [1,2,3,4].
The jQuery libraries are included in my bundles so should be the same on all pages. I have used jquery.js, jquery-ui.js and jquery-ui.css.
I cant work out the difference between them as to why the one does not display correctly.
The broken one displays as follows:
Any help with this would be greatly appreciated. Please let me know if more info is required
EDIT - Solution But Why?
So the issue appeared to be that the jQuery Autocomplete component did not like an input of an array of integers.
This seems quite strange to me and I believe an autocomplete should be able to cope with integers. Does anybody know why this is or if there is a setting to handle it?
jquery-ui autocomplete would work good with String responses. Your response data should be a list of strings and not integers (as the value attribute for the input element is always a string).
Try converting the response data to string either at client side or server side. I prefer doing it at the client side.
$('#txtParentRequest').autocomplete({
minLength: 1,
source: function (request, response) {
$.ajax({
url: apiEndpoint + 'api/Request/' + $('#txtParentRequest').val(),
method: 'GET',
dataType: 'json',
contentType: 'application/json',
success: function (data) {
// Convert the integer list to a string list
var stringList = $.map(data, function(element){
return element + "";
})
response(stringList );
}
});
}
});
It's because JQuery autocomplete supports only two array formats as explained below:-
source Type:
Array or String or Function( Object request, Function
response( Object data ) ) Default: none; must be specified Defines the
data to use, must be specified. Independent of the variant you use,
the label is always treated as text. If you want the label to be
treated as html you can use Scott González' html extension. The demos
all focus on different variations of the source option - look for one
that matches your use case, and check out the code.
Multiple types supported: Array: An array can be used for local data.
There are two supported formats: An array of strings: [ "Choice1",
"Choice2" ] An array of objects with label and value properties: [ {
label: "Choice1", value: "value1" }, ... ] The label property is
displayed in the suggestion menu. The value will be inserted into the
input element when a user selects an item.
You can have a look at API documentation for more details:
http://api.jqueryui.com/autocomplete/
So as per me you can convert your array to string from backend or you can convert it by Javascript like this:-
$('#txtParentRequest').autocomplete({
minLength: 1,
source: function (request, response) {
$.ajax({
url: apiEndpoint + 'api/Request/' + $('#txtParentRequest').val(),
method: 'GET',
dataType: 'json',
contentType: 'application/json',
success: function (data) {
if(data!=null && data.length>0){
var numberArray=data.map(String);
response(numberArray);
//Or response(data.map(String));
}
}
});
}
});
I am trying to write a test for a Javascript select2 control and I would like to automatically select the first item. Since it's using ajax I do not know what the first item is. All the examples I have seen create <option> however they assume knowledge of the value. How can I select the first item without knowledge? (Note this example only runs the ajax command after 3 items are entered).
var $selector = $("#foo");
$selector.show().select2({
allowClear: true,
placeholder: "--------",
minimumInputLength: 3,
ajax: {
url: "...",
type: 'GET',
dataType: 'json',
delay: 250,
data: function(term, page) {
return {
number__icontains: term
};
},
results: function(data) {
return {
results: $.map(data.objects, function(option) {
return {
'id': option.id,
'text': option.desc
};
})
};
},
cache: false
},
initSelection: function(element, callback) {
...
}
});
I'm trying to use Typeahead. I'm using AJAX to get my source :
$(document).ready(function() {
$('input.typeahead').typeahead(
{
hint: true,
highlight: true,
minLength: 1
},
{
source: function(query, process) {
jQuery.ajax({
url: 'suggestion.php',
dataType: "json",
data: {
type: 'abc'
},
success: function(data) {
suggestion = [];
for(var i in data)
{
suggestion.push(data[i]);
}
console.log(data);
}
});
process(suggestion);
return suggestion;
}
});
});
But there is the result :
But when I see the logs :
I've an array with strings !
There the console message :
I can see an error appear at the first char typed but only the first time. All the time, I've "undefined" x 5 proposed.
What's the matter ? I guess the format, but I've tried mainly things from stacks, without results (only errors). My Php code return ("echo") an json_encode($array) ! It's my first time using Ajax and Typeahead..
Sorry for my english.
I think that suggestion must be this kind of array :
[{ "value": "CBOXXX" }, { "value": "CBAXXX" }]