Ajax in MVC 6 - making search function - javascript

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 :)

Related

Razor autocomplete doesen't work when submitted

I'm having some problem with the autocomplete on my Razor project. Everytime it returns me error/failure. Maybe it could be even a stupid thing but I'm new to ASP so it would be difficult for me to notice.
Javascript Code
$(function () {
$('#searchCliente').autocomplete({
source: function (request, response) {
$.ajax({
url: '/Index?handler=Search',
data: { "term": request.term },
type: "POST",
success: function (data) {
response($.map(data, function (item) {
return item;
}))
},
error: function (response) {
alert(response.responseText);
},
failure: function (response) {
alert(response.responseText);
}
});
},
select: function (e, i) {
$("#idCliente").val(i.item.val);
$("#idFatt").val(i.item.val);
},
minLength: 3
});
});
Page Model Code
public IActionResult OnPostSearch(string term)
{
var clientefatt = (from cliente in this.context.Arc_Anagrafiche
where cliente.RagioneSociale.StartsWith(term)
select new
{
label = cliente.RagioneSociale,
val = cliente.IdAnag
}).ToList();
return new JsonResult(clientefatt);
}
HTML Code
<input asp-for="intervento.Cliente" class="form-control" id="searchCliente" />
<input asp-for="intervento.IdClienteFatturazione" class="form-control" id="idCliente" type="hidden" />
Perhaps the issue is related to the AntiForgeryToken, try to add the XSRF-TOKEN property in the request header before sending the Ajax request.
Please refer to the following samples and modify your code:
Add AddAntiforgery() service in the ConfigureServices method:
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
In the Ajax beforeSend event, get the RequestVerificationToken from the hidden field, and set the request header:
#page
#model RazorPageSample.Pages.AutocompleteTestModel
<form method="post">
#Html.AntiForgeryToken()
<input type="text" id="txtCustomer" name="label" />
<input type="hidden" id="hfCustomer" name="val" />
<br /><br />
<input type="submit" value="Submit" asp-page-handler="Submit" />
<br />
</form>
#section Scripts{
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.10.0.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.ui/1.9.2/jquery-ui.min.js" type="text/javascript"></script>
<link href="https://ajax.aspnetcdn.com/ajax/jquery.ui/1.9.2/themes/blitzer/jquery-ui.css" rel="Stylesheet" type="text/css" />
<script type="text/javascript">
$(function () {
$("#txtCustomer").autocomplete({
source: function (request, response) {
$.ajax({
url: '/AutocompleteTest?handler=AutoComplete',
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
data: { "prefix": request.term },
type: "POST",
success: function (data) {
response($.map(data, function (item) {
return item;
}))
},
error: function (response) {
alert(response.responseText);
},
failure: function (response) {
alert(response.responseText);
}
});
},
position: { collision: "flip" },
select: function (e, i) {
$("#hfCustomer").val(i.item.val);
},
minLength: 1
});
});
</script>
}
Code in the .cshtml.cs file:
public IActionResult OnPostAutoComplete(string prefix)
{
var customers = new List<Customer>()
{
new Customer(){ ID=101, Name="Dillion"},
new Customer(){ID=102, Name = "Tom"},
new Customer(){ ID=103, Name="David"}
};
return new JsonResult(customers.Where(c=>c.Name.ToLower().StartsWith(prefix.ToLower())).Select(c=> new { label = c.Name, val = c.ID }).ToList());
}
public class Customer
{
public int ID { get; set; }
public string Name { get; set; }
}
Then, the screenshot as below:
Reference: jQuery AutoComplete in ASP.Net Core Razor Pages
Maybe you shall assign the ajax datatype property, and also change the "type" property from post to get, as below:
$.ajax({
url: '/Index?handler=Search',
data: { "term": request.term },
datatype: 'json'
type: "GET",
success: function (data) {
response($.map(data, function (item) {
return item;
}))
},
error: function (response) {
alert(response.responseText);
},
failure: function (response) {
alert(response.responseText);
}
});
Also in the Model code you can try one of the following,
as when returning json the JSONRequestBehavior property shall be specified as AllowGet:
return Json(new {clientefatt = clientefatt}, JsonRequestBehavior.AllowGet);
Change the Model code method's return type to JsonResult, as below
public JsonResult OnPostSearch(string term){
return new JsonResult(clientefatt);
}
Most probably the first options, since you're using .net core, will give you an error "ASP.NET Core - The name 'JsonRequestBehavior' does not exist in the current context"

Select section showing undefined in ajax autocomplete

I getting name perfectly but I am not getting their name related ID in ajax autocomplete
Following is the view code,
#Html.TextBoxFor(model => Model.CustomerFullName, new { #class = "form-control" })
#Html.TextAreaFor(model => Model.CustomerId)
$(document).ready(function () {
$("#CustomerFullName").autocomplete({
source: function (request, response) {
$.ajax({
url: '#Url.Action("AutoComplete", "Order")',
datatype: "json",
data: {
term: request.term
},
success: function (data) {
response($.map(data, function (val) {
return {
value: val.Name,
label: val.Name
}
}))
}
})
},
select: function (event, ui) {
alert(ui.item.id);
$("#CustomerId").val(ui.item.id);
}
});
});
Here is the controller,
public JsonResult AutoComplete(string term = "")
{
var objCustomerlist = (from customer in _customerRepository.Table
where customer.Username.StartsWith(term)
select new
{
Name = customer.Username,
ID = customer.Id
}).ToList();
return Json(objCustomerlist);
}
In autocomplete ajax select section alert showing undefined
I tried things to solve like
JSON.Stringfy(ui.item.id)
ui.id
but still didnt work.

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);
}
});
});
}

Uncaught TypeError: Object has no method autocomplete and its blocking to populate dialogue box to delete

I'm sorry similar post is already there in the community, But i'm finding it strange. Its working fine but it affected my other views and not allowing other view pages to populate any dialogue boxes..
I tried to fix it by wrapping it in function() like this
$('#_auto').autocomplete(function(){
But, with this i'm not getting jason values in the _auto textfield and getting unexpected token error with following line.
can anyone help me to solve this please.
source: function(request,response){
this is my code:
$(function () {
$('#_auto').autocomplete({
selectFist: true,
minLength: 2,
source: function (request, response) {
var sval = $('#_auto').val();
//alert(sval);
$.ajax({
url: BASE_URL + '/controller/search/',
type: 'POST',
data: {
'term': sval,
},
dataType: 'json',
success: function (data) {
console.log(data);
var dta = [];
orgdetails = [];
//response(data.d);
for (var i in data) {
dta.push(data[i].name);
orgdetails[data[i].name] = data[i].id;
}
response(dta); //response(dta);
},
error: function (result) {}
}); //ajax
}
}).focus(function () {
$(this).trigger('keydown.autocomplete');
});
});
Many Thanks
I think the for loop should be
var dta = $.map(data, function(v, i){
orgdetails[v.name] = v.id;
return {
label: v.name,
id: v.name
};
});
Fiddle.
Another observation, You can get the current searched term using request.term rather than $('#_auto').val()
Complete code:
$('#_auto').autocomplete({
selectFist: true,
minLength: 2,
source: function (request, response) {
$.ajax({
url: BASE_URL + '/controller/search/',
type: 'POST',
data: {
'term': request.term,
},
dataType: 'json',
success: function (data) {
console.log(data);
orgdetails = {};
var dta = $.map(data, function(v, i){
orgdetails[v.name] = v.id;
return {
label: v.name,
id: v.name
};
});
response(dta); //response(dta);
},
error: function (result) {}
}); //ajax
}
}).focus(function () {
$(this).trigger('keydown.autocomplete');
});

JSON + PHP + JQuery + Autocomplete problem

Only started today but I'm having massive problems trying to understand JSON/AJAX etc, I've gotten my code this far but am stumped on how to return the data being pulled by the AJAX request to the jQuery Auto complete function.
var autocomplete = new function() {
this.init = function() {
$('#insurance_destination').autocomplete({
source: lookup
});
}
function lookup() {
$.ajax({
url: "scripts/php/autocomplete.php",
data: {
query: this.term
},
dataType: "json",
cache: false,
success: function(data) {
for (key in data) {
return {
label: key,
value: data[key][0]
}
}
}
});
}
}
And example of the JSON string being returned by a PHP script
{
"Uganda": ["UGA", "UK4", "Worldwide excluding USA, Canada and the Carribbean"]
}
Normally, you don't have to do ajax query yourself:
$('#insurance_destination').autocomplete('url_here', {options_here});
That's assuming we're talking about standard jquery autocomplete plugin. Do I understand you correctly?
edit
Check api
http://docs.jquery.com/Plugins/Autocomplete/autocomplete#url_or_dataoptions
There are also some examples.
This is the code I've ended up with, it works in Chrome and Firefox but not in IE 6/7...
var autocomplete = new function (){
this.init = function() {
$('#insurance_destination').autocomplete({
source: function(request, response) {
debugger;
$.ajax({
url: "scripts/php/autocomplete.php",
dataType: "json",
data: {query:this.term},
success: function(data) {
response($.map(data.countries, function(item) {
return {
label: '<strong>'+item.name+'</strong>'+' '+item.description,
value: item.name,
code : item.region
}
}))
}
})
},
minLength: 2,
select: function(event, ui) {
$('#insurance_iso_code_hidden').val(ui.item.code);
},
open: function() {
},
close: function() {
}
});
}
}

Categories