jQuery UI autocomplete- no results message - javascript

I'm trying to have a "No Results" message appear in the dropdown menu if there are no results. So for instance, if I type in "ABCD" into the text field, and there is no entity that matches, the message "No Results." will be displayed.
After looking through stackoverflow for the various different ways of accomplishing this, and trying a few of them, I still can't get it to work.
How can I add a "No Results" message to the dropdown menu when no results are found?
jQuery:
$element.autocomplete({
source: function (request, response) {
$.ajax({
url: thUrl + thQS,
type: "get",
dataType: "json",
cache: false,
data: {
featureClass: "P",
style: "full",
maxRows: 12
},
success: function (data) {
response($.map(data, function (item) {
if (data.indexOf(item) === -1) {
return { label: "No Results." }
} else {
return {
label: item.Company + " (" + item.Symbol + ")",
value: item.Company
}
}
}));
}
});
},
minLength: that.options.minLength,
select: function (event, ui) {
reRenderGrid();
}
});
I have tried adding an if() statement with the following but that didn't work.
if (data.length === 0) {
// Do logic for empty result.
}
I am able to overwrite the first entry with the text "No Result" if I do the following...
if (data.indexOf(item) === 0) {
return {
label: "No Results."
}
...but if I set data.indexOf(item) === -1 nothing shows up.
I just recently tried the following, and when there is no data, it goes into the loop, however, "No Results" is not being displayed in the menu:
success: function (data) {
response($.map(data, function (item) {
return {
label: item.Company + " (" + item.Symbol + ")",
value: item.Company
}
}));
if (data.length === 0) {
label: "No Results."
}
}
I have also attempted to use the below example from Andrew Whitaker with no luck:
ANDREW WHITACKER'S FIDDLE: http://jsfiddle.net/J5rVP/128/
SOURCE: http://blog.andrewawhitaker.com/2012/10/08/jqueryui-autocomplete-1-9/

if (!ui.content.length) {
var noResult = { value:"",label:"No results found" };
ui.content.push(noResult);
//$("#message").text("No results found");
}
Fiddle
http://jsfiddle.net/J5rVP/129/
Update
Put the code at the end of your auto-complete setup just after select: function (event, ui) {..}
..........
minLength: that.options.minLength,
select: function (event, ui) {
reRenderGrid();
}, //HERE - make sure to add the comma after your select
response: function(event, ui) {
if (!ui.content.length) {
var noResult = { value:"",label:"No results found" };
ui.content.push(noResult);
}
}
});

Modify the function like this to check for length of data.
success: function (data) {
if(!data.length){
var result = [
{
label: 'No matches found',
value: response.term
}
];
response(result);
}
else{
// normal response
response($.map(data, function (item) {
return {
label: item.CompanyName + " (" + item.SymbolName + ")",
value: item.CompanyName
}
}));
}
}

My answer is almost identical to #neelmeg and #Trever, but I have added an extra check, so user won't be able to select the "no result" message:
$(".my-textbox").autocomplete({
minLength: 2,
open: function () { $('.ui-autocomplete').css('z-index', 50); },
source: function (request, response) {
$.ajax({
url: "/some-url",
type: "POST",
dataType: "json",
data: { prefix: request.term, __RequestVerificationToken: token },
success: function (data) {
if (!data.length) {
var result = [{ label: "no results", value: response.term }];
response(result);
}
else {
response($.map(data, function (item) {
return { label: item.someLabel, value: item.someValue };
}))
}
}
})
},
select: function (event, ui) {
var label = ui.item.label;
if (label === "no results") {
// this prevents "no results" from being selected
event.preventDefault();
}
else {
/* do something with the selected result */
var url = "some-url"
window.location.href = url;
}
}
});

For me the reason, why this messages occured were:
MISSING CSS FILES O JQUERY UI
so adding:
<link rel="stylesheet" href="jqueryui/themes/flick/jquery-ui.css" type="text/css" media="screen" />
<link rel="stylesheet" href="jqueryui/themes/flick/jquery.ui.theme.css" type="text/css" media="screen" />
solved my problem

Related

Ajax in MVC 6 - making search function

I have a new project and decided to go with c# .net 6 MVC in VS2022...
In may old projects this code works flawless.
#section Scripts
{
<script type="text/javascript">
$("#Klijent_Name").autocomplete({
source: function (request, response) {
$.ajax({
url: "#Url.Action("SearchKlijenti")",
type: "POST",
dataType: "json",
data: { term: request.term },
success: function (data) {
response($.map(data, function (item) {
return { label: item.label, value: item.label, id: item.id };
}))
}
})
},
minLength: 1,
select: function (event, ui) {
$("#KlijentId").val(ui.item.id);
$("#KlijentLabel").html(ui.item.label);
$("#SearchKupac").val("");
return false;
}
});
</script>
}
and latest variation of controller endpoint:
public JsonResult SearchKlijenti(string term)
{
var klijentVM = _klijent.Search(term);
if (klijentVM != null)
{
var items = klijentVM.Select(x => new { id = x.KlijentId, label = x.FriendlyName });
return new JsonResult(Ok(items));
}
return new JsonResult(Ok());
}
Using latest jQuery 3.6.1, and bootstrap 5.2.0. Tried using jquery-ui.js, jquery.unobtrusive-ajax.js...
Problem is that the call is not triggered, or not finding it's way to controller action. Have tried putting alert(); and omitting data manipulation and calls, but still nothing. When testing jQuery:
$("SearchKupac").keyup(function() {
alert();
});
works.
Tried to debug using Firefox, but either I don't know to use it, or the call is not triggered.
I don't know where and what to look anymore...
EDIT: Here is also HTML snippet
<label asp-for="Klijent.Name">Ime</label>
<input class="form-control ajax" asp-for="Klijent.Name" />
<span asp-validation-for="Klijent.Name" class="text-danger"></span>
I also tried selecting with $("input.ajax")... Tried double and single quotes. Bare in mind, this is a working code from MVC 5 project. It doesn't work in new project
If you want to use keyup event,here is a demo:
<input id="SearchKupac" />
js:
$("#SearchKupac").keyup(function() {
alert();
});
If the id of input is SearchKupac,you need to use $("#SearchKupac") in js.Also,you can use $("#SearchKupac") with autocomplete.
#section Scripts
{
<script type="text/javascript">
$("#SearchKupac").autocomplete({
source: function (request, response) {
$.ajax({
url: "#Url.Action("SearchKlijenti")",
type: "POST",
dataType: "json",
data: { term: request.term },
success: function (data) {
response($.map(data, function (item) {
return { label: item.label, value: item.label, id: item.id };
}))
}
})
},
minLength: 1,
select: function (event, ui) {
$("#KlijentId").val(ui.item.id);
$("#KlijentLabel").html(ui.item.label);
$("#SearchKupac").val("");
return false;
}
});
</script>
}
So Firefox developer tool was of no help. Crome developer tool find an error. It was not apparent immediately, but the jquery-ui.js (of version 1.13.2 in my case) resolved the issue.
<script src="~/js/jquery-ui-1.13.2/jquery-ui.min.js"></script>
There was also an issue in controller. it has to be of type JsonResult and return Json(items) not Json(Ok(items))
public JsonResult SearchKlijenti(string term)
{
var klijentVM = _klijent.Search(term);
if (klijentVM != null)
{
var items = klijentVM.Select(x => new
{
id = x.KlijentId,
name = string.IsNullOrEmpty(x.Name) ? " " : x.Name,
friendly = string.IsNullOrEmpty(x.FriendlyName) ? " " : x.FriendlyName,
person = string.IsNullOrEmpty(x.PersonName) ? " " : x.PersonName,
tel = string.IsNullOrEmpty(x.Contact) ? " " : x.Contact,
mail = string.IsNullOrEmpty(x.Mail) ? " " : x.Mail,
oib = string.IsNullOrEmpty(x.OIB) ? " " : x.OIB,
adresa = string.IsNullOrEmpty(x.Adress) ? " " : x.Adress,
});
return Json(items);
}
return Json(null);
}
And for completeness, here is my script:
#section Scripts
{
<script type="text/javascript">
$("input.ajax").autocomplete({
source: function (request, response) {
$.ajax({
url: "#Url.Action("SearchKlijenti")",
type: "GET",
dataType: "json",
data: { term: request.term, maxResults: 10 },
success: function (data) {
response($.map(data, function (item) {
return {
label: item.friendly,
value: item.friendly,
id: item.id,
name: item.name,
friendly: item.friendly,
person: item.person,
tel: item.tel,
mail: item.mail,
oib: item.oib,
adresa: item.adresa
};
}))
}
})
},
minLength: 1,
select: function (event, ui) {
$("#Klijent_KlijentId").val(ui.item.id);
$("#Klijent_KlijentName").val(ui.item.name)
$("#Klijent_FriendlyName").val(ui.item.label)
$("#Klijent_OIB").val(ui.item.oib)
$("#Klijent_PersonName").val(ui.item.person)
$("#Klijent_Contact").val(ui.item.tel)
$("#Klijent_Mail").val(ui.item.mail)
$("#Klijent_Adress").val(ui.item.adresa)
return false;
}
})
</script>
}
Did not yet test return Json(null), but that is not part of this exercise :)

jquery dynamic autocomplete textbox url

I am generating dynamic textboxes for autocomplete depending on user input.
var projects = [
{
label: "Test12",
desc: "responsive web application kit"
},
{
label: "Londinium",
desc: "responsive bootstrap 3 admin template"
},
{
label: "It's Brain",
desc: "Bootstrap based "
}
];
// Initialize autocomplete
$(document).on('click', '.ac-custom', function () {
$(this).autocomplete({
minLength: 0,
source: function (request, response)
{
$.ajax({
url: "/Home/GetInfo",
type: "POST",
dataType: "json",
data: { Name: $(this).val() },
success: function (data) {
}
});
},
focus: function (event, ui) {
$(this).val(ui.item.label);
return false;
},
select: function (event, ui) {
$(this).val(ui.item.label);
return false;
}
})
.autocomplete("instance")._renderItem = function (ul, item) {
return $("<li>").append("<span class='text-semibold'>" + item.label + '</span>' + "<br>" + '<span class="text-muted text-size-small">' + item.desc + '</span>').appendTo(ul);
}
});
If I give the source as projects this works but I need to fetch from database so I am calling an action method but somehow this is not working.
Is it because I am binding ajax call to controls created at runtime.
Your help is appreciated. Thanks
You need pass data in response from success callback
// Initialize autocomplete
$(document).on('click', '.ac-custom', function () {
$(this).autocomplete({
minLength: 0,
source: function (request, response)
{
$.ajax({
url: "/Home/GetInfo",
type: "POST",
dataType: "json",
data: { Name: $(this).val() },
success: function (data) {
response( data );
},
error: function (jqXHR, exception) {
var msg = '';
if (jqXHR.status === 0) {
msg = 'Not connect. Verify Network.';
} else if (jqXHR.status == 404) {
msg = 'Requested page not found. [404]';
} else if (jqXHR.status == 500) {
msg = 'Internal Server Error [500].';
} else if (exception === 'parsererror') {
msg = 'Requested JSON parse failed.';
} else if (exception === 'timeout') {
msg = 'Time out error.';
} else if (exception === 'abort') {
msg = 'Ajax request aborted.';
} else {
msg = 'Uncaught Error.';
}
alert(msg + "<br/>responseText: " + jqXHR.responseText);
}
});
},
focus: function (event, ui) {
$(this).val(ui.item.label);
return false;
},
select: function (event, ui) {
$(this).val(ui.item.label);
return false;
}
})
.autocomplete("instance")._renderItem = function (ul, item) {
return $("<li>").append("<span class='text-semibold'>" + item.label + '</span>' + "<br>" + '<span class="text-muted text-size-small">' + item.desc + '</span>').appendTo(ul);
}
});
Update you source function like this
source: function (request, response) {
$.ajax({
url: '/Home/GetInfo',
data: { 'text': $.trim($('#yourtextboxid').val()) },
dataType: 'json',
type: 'post',
success: function (data) {
response($.map(data, function (item) {
return {
label: item.name,
id: item.id
}
}));
}
})
}
This will help you

formatSelection not working in select2.js

I am using select2.js to populate the field with multiple values using ajax call.
Below is the code that I am using.
HTML
<input id="id_test_name" class="form-control">
Script
<script type="text/javascript">
$("#id_test_name").select2({
placeholder: "Search for an Item",
minimumInputLength: 2,
ajax: {
url: "/resourse/?format=json&name=xyz",
dataType: 'json',
quietMillis: 100,
data: function (term, page) {
return {
option: term
};
},
results: function (data, page) {
return {
results: $.map(data.results, function (item) {
return {
name: item.name,
abbreviation: item.abbreviation,
id: item.id
}
})
};
}
},
formatResult: function (data, term) {
return data.name + '(' + data.abbreviation +')';
},
formatSelection: function (data) {
return data.name + '(' + data.abbreviation +')';
},
dropdownCssClass: "bigdrop",
escapeMarkup: function (m) {
return m;
}
});
</script>
results are populating in dropdown but I am not able to select the populated results, I am not able to find what I am doing wrong?
Also I need the id of selected results in some other(hidden) field.
Update:
jsfiddle: http://jsfiddle.net/n5phohov/2
If you are using the current select2 v4, the parameters formatResult and formatTemplate were replaced by templateResult and templateSelection. Also you can call functions to format the results. Look the example bellow, observe that I used base64 image contained in a data attribute, you can easily replace for an image link matching with the option.
$('#combo').select2({
language : "pt-BR",
allowClear: true,
placeholder: "Selecione",
templateResult: formatSingleResult,
templateSelection: formatSelected
}).on('select2:select', function (e) {
var data = e.params.data;
let thumbnailValue='';
$(data.element.attributes).each( function (){
if ($(this)[0].name == 'data-thumbnail' ){
thumbnailValue = $(this)[0].value;
}
});
function formatSelected(state) {
let img='';
if (printImage == true){
img='<img src="' + $(state.element).attr('data-thumbnail') +'" class="comboImg"/>';
}
$item = $(`<span>${img} ${state.text.trim()}<span>`);
return $item;
}
function formatSingleResult (result) {
if (!result.id) {
return result.text.trim();
}
let img="";
if (printImage == true){
img='<img src="' + $(result.element).attr('data-thumbnail') +'" class="flag"/>';
}
const optionText = result.text.trim();
const $item = $(`<span>${img} ${optionText}<span>`);
return $item;
}

Jquery autocomplete - how modify returned data

I have code like this:
$(document).ready(function () {
if ($('#au').length <= 0) {
return;
}
var $project = $('#au');
$project.autocomplete({
minLength: 4,
source: function (request, response) {
$.ajax({
dataType: "json",
type: 'post',
cache: false,
data: {term: request.term},
url: '/Movies/ajax/',
success: function (data) {
if (isNaN($('#au').val())) {
response($.map(data, function (item) {
return {
label: item.Movies__name + " " + "(" + item.Movies__id + ")",
value: item.Movies__name
}
}));
} else {
response($.map(data, function (item) {
return {
label: item.Movies__id + " " + "(" + item.Movies__name + ")",
value: item.Movies__id
}
}));
}
}
});
},
select: function(event, ui) {
$("#au").val(ui.item.value);
$("#au").submit();
},
create: function (event, ui) {
},
open: function (event, ui) {
}
});
});
This code works fine. Basicly when You type in form "Alie", you will get
Alien(22)
Aliens2(32)
Aliens3(43)
Or when you type Id istead of movie name, you will get:
(22)Alien
(22)Other and so on....
So this code returns list of data - movie and id.
And now i want, to have first result without id, so when You type movie name like "Alie" you will get:
Alien
Alien(22)
Aliens(32)
First match without id.
Thanks for any replies.
response($.map(data, function (item, i) {
return {
label: item.Movies__name + (i != 0 ? " (" + item.Movies__id + ")" : ""),
value: item.Movies__name
}
}));
Use i for index in map function. If 0, you don't show id.

How to populate extra fields with jQuery autocomplete

I am passing complex JSON data to jQuery autocomplete plugin. And it is working fine so it shows the list of Products.
Now I want to get somehow Price that is already included into JSON data and when I select product from autocomlete list I would like to populate input tag with Price.
I really cannot get if it is possible to do. What I know that data is already in JSON but how to get it?
Any clue?
Here is JS for jQuery autocomplete plugin
function CreateAutocomplete() {
var inputsToProcess = $('[data-autocomplete]').each(function (index, element) {
var requestUrl = $(element).attr('data-action');
$(element).autocomplete({
minLength: 1,
source: function (request, response) {
$.ajax({
url: requestUrl,
dataType: "json",
data: { query: request.term },
success: function (data) {
response($.map(data, function (item) {
return {
label: item.Name,
value: item.Name,
realValue: item.UID
};
}));
},
});
},
select: function (event, ui) {
var hiddenFieldName = $(this).attr('data-value-name');
$('#' + hiddenFieldName).val(ui.item.UID);
}
});
});
}
To make clear item.LastPrice has Price data.
And HTML
#Html.AutocompleteFor(x => x.ProductUID, Url.Action("AutocompleteProducts", "Requisition"), true, "Start typing Product name...", Model.Product.Name)
In your ui.item object you should be able to find the the Price property in there and then set the value in the select function.
success: function (data) {
response($.map(data, function (item) {
return {
label: item.Name,
value: item.Name,
realValue: item.UID,
price: item.LastPrice // you might need to return the LastPrice here if it's not available in the ui object in the select function
};
}));
},
..
select: function (event, ui) {
var hiddenFieldName = $(this).attr('data-value-name'),
unitPriceEl = $('#price');
$('#' + hiddenFieldName).val(ui.item.UID);
unitPriceEl.val(ui.item.LastPrice); //set the price here
}
Thanks to dcodesmith!!! I am gonna mark his solution like an answer but just in case I will share my final code that is working fine now.
function CreateAutocomplete() {
var inputsToProcess = $('[data-autocomplete]').each(function (index, element) {
var requestUrl = $(element).attr('data-action');
$(element).autocomplete({
minLength: 1,
source: function (request, response) {
$.ajax({
url: requestUrl,
dataType: "json",
data: { query: request.term },
success: function (data) {
response($.map(data, function (item) {
return {
label: item.Name,
value: item.Name,
realValue: item.UID,
lastPrice: item.LastPrice
};
}));
},
});
},
select: function (event, ui) {
var hiddenFieldName = $(this).attr('data-value-name');
$('#' + hiddenFieldName).val(ui.item.UID);
var unitPriceEl = $('#UnitPrice');
unitPriceEl.val(ui.item.lastPrice);
console.log(ui.item.lastPrice);
}
});
});
}

Categories