I am working on ASP.NET MVC project. In my home page, I have a search box with a search button.
When User types a Keyword and Click Search, I need to perform 2 independent search Operations (I am using Elasticseach, so two calls to Elasticsearch).
Make a call to SearchItems action method, which will go and get Items from Elasticsearch and returns ItemsPartialView.
Make a call to SearchCategory action method which goes and gets categories from Elasticsearch and returns CategoryPartialView.
In my home page, I want to make 2 ajax calls, to these action methods using AJAX, to display the result.
This Image explains what I want to achieve
Question: Is it possible to make 2 calls to 2 action methods on one event using AJAX?
It's possible. The only real issue is whether you want the ajax requests to be sent in a certain order (and the usual issues of efficiency of code to avoid repeats, the format of the data returned etc). One way of doing this (where the ajax second call is made after the first completes successfully) is sketched out:
<input type="text" id="search-query" value="" />
<button id="test-button">Test Ajax</button>
<div id="ajax-one-result"></div>
<div id="ajax-two-result"></div>
<script>
$(function(){
$(document).on("click", "#test-button", function(){
var qry = $("#search-query").val();
func1(qry);
function func1(queryString) {
var urlOne = "/Path/To/AjaxOne";
return $.ajax({
type: "GET",
url: urlOne,
timeout: 30000,
data: { query: queryString },
dataType: "json",
beforeSend: function () {
},
success: function (transport) {
$("#ajax-one-result").html(transport);
func2(transport);
console.log("AjaxOne success");
},
error: function (xhr, text, error) {
console.log("ERROR AjaxOne");
},
complete: function () {
}
});
}
function func2 (ajaxOneResult) {
var urlTwo = "/Path/To/AjaxTwo";
$.ajax({
type: "GET",
url: urlTwo,
timeout: 30000,
data: { query: ajaxOneResult },
dataType: "json",
beforeSend: function () {
},
success: function (transport) {
$("#ajax-two-result").html(transport);
console.log("AjaxTwo success");
},
error: function (xhr, text, error) {
console.log("ERROR AjaxTwo");
},
complete: function () {
}
});
}
});
});
</script>
with Controller Actions:
public async Task<JsonResult> AjaxOne(string query)
{
// For testing only
System.Threading.Thread.Sleep(5000);
var result = "AjaxOne Result: " + query;
return Json(result, JsonRequestBehavior.AllowGet);
}
public async Task<JsonResult> AjaxTwo(string query)
{
// For testing only
System.Threading.Thread.Sleep(2000);
var result = "AjaxTwo Result: " + query;
return Json(result, JsonRequestBehavior.AllowGet);
}
Related
In my MVC application I don't want the layout page to reload everytime a view is selected. It would be great if the views could be loaded using ajax to keep things nice and fast and allow me to persist certain interface states that are wiped out when you move around.
My initial approach was to add some ajax to the _Layout.cshtml and then whent he view was requested pass that request to the controller method which will grab that page. All I ended up doing however was returning the WHOLE view again.
Here is the code I have so far, am I on the right tracks here or is this totally wrong?
Layout Ajax Script
<script>
$(function () {
var content = document.getElementById('content');
//When a user selects a link, pass the data attribute and
//use it to construct the url
$('#sidebar a').on("click", function () {
var page = $(this).data('page');
console.log("Data Attrib : " + page);
$.ajax({
type: 'GET',
url: '#Url.Content("~/Home/")' + page,
success: function (data) {
$('#content').html(data);
console.log("Success");
},
error: function (xhr, ajaxOptions, thrownError) {
console.log("Error: " + thrownError);
}
})
})
});
</script>
As I say, this sort of works, but it's not perfect as it returns the whole page into the content area including layout, ideally I just want the core view data.
you can create a Single Page Application that have 1 layout and in home controller and index action method create menu or user setting or another things
and now you can load other action with Ajax call with data-content html that does not have layout file and append that in container
when user click another menu clean older content and add new or you can create tab strip or window
Layout.cshtml
<script>
$(function () {
//When a user selects a link, pass the data attribute and
//use it to construct the url
$('#sidebar a').on("click", function () {
var page = $(this).data('page');
$.ajax({
type: 'POST',
url: '/Home/Pages',
data: { pageValue: page },
success: function (data) {
$('#content').html(data);
console.log("Success");
},
error: function (xhr, ajaxOptions, thrownError) {
console.log("Error: " + thrownError);
}
})
})
});
Controller
public class HomeController : Controller
{
[HttpPost]
public string Pages(string pageValue)
{
string result = //Whatever
return result;
}
}
Controller
public ActionResult SomeAction(String someparams)
{
//Make the model
SomeModel someModel = new SomeModel();
someModel.someparams = someparams;
return PartialView("SomePartialView", someModel);
}
In View
$.ajax({
url: "/Home/SomeAction",
type: "POST",
dataType : "html",
data: json,
contentType: 'application/json; charset=utf-8',
success: function(data){
$('#SomeDivID').html(data);
}
});
I have this AJAX in my code:
$(".dogname").click(function () {
var id = $(this).attr("data-id");
alert(id);
$.ajax({
url: '/Home/GetSingleDog',
dataType: 'html',
data: {
dogid: id,
},
success: function (data) {
$('#hidden').html(data);
}
});
});
The alert gets triggered with the correct value but the AJAX-call does not start(the method does not get called).
Here is the method that im trying to hit:
public ActionResult GetSingleDog(int dogid)
{
var model = _ef.SingleDog(dogid);
if (Request.IsAjaxRequest())
{
return PartialView("_dogpartial", model);
}
else
{
return null;
}
}
Can someone see what i am missing? Thanks!
do you know what error does this ajax call throws?
Use fiddler or some other tool to verify response from the server.
try modifying your ajax call as following
$.ajax({
url: '/Home/GetSingleDog',
dataType: 'string',
data: {
dogid: id,
},
success: function (data) {
$('#hidden').html(data);
}
error: function(x,h,r)
{
//Verify error
}
});
Also try
$.get("Home/GetSingleDog",{dogid : id},function(data){
$('#hidden').html(data);
});
Make sure, URL is correct and parameter dogid(case sensitive) is same as in controller's action method
I have a scenario as follows,
Need to put autocomplete functionality on dynamic textbox with onkeyup functionality
My code is as follows, Here i have invoked a function "GetName" on buttonclick where am loadin the dynamic textboxes
function GetName() {
var dataToSend = JSON.stringify({ prefixText: $('#search').val(), Id: $("#SearchType").val()
});
$.ajax({
type: "POST",
data: { jsonData: dataToSend },
url: "GetName",
datatype: "json",
success: function (result) {
$("#ResourceNames").empty();
$("#ResourceNames").append('<table>');
$.each(result, function (i, Name) {
$("#ResourceNames").append('<tr><td ><Label>' + Name.Value + '</label></td><td> <input type="text" id="Supervisor" class = "form-control", onkeyup="GetResource(\'' + Name.Text + '\');"/></td></tr>');
});
},
error: function (xhr, status) {
alert(status);
}
})
$("#ResourceNames").append('</table>');
}
Here onkeyup event of textbox supervisor am calling the below function getresource with an argument
function GetResource(i) {
debugger;
var dataToSend = JSON.stringify({ prefixText: $("#Supervisor").val(), designation: i });
$.ajax({
url: "GetSupervisor",
data: { jsonData: dataToSend },
dataType: 'json',
type: 'POST',
success: function (data) {
$("#Supervisor").autocomplete({source:data});
});
},
error: function (error) {
alert('error; ' + error.text);
}
});
}
am not able to bind autocomplete data to dynamic textbox, can anyone help me out on the same?
You have several issues in your code:
First of all jQuery doesn't concatenates strings into DOM, it creates a DOMElement. So,
$("#ResourceNames").append('<table>'); will append an entire <table> element. Anything you append to #ResourceNames will be added after the table, not inside it.
The HTML you're appending contains id. So there can be multiple elements with same id which is invalid, depending on the response. It's better to use a common classname for those elements instead.
You don't need to manually handle the keyup event. You can specify the url you want to hit as the value of the source option of autocomplete, provided it returns a response suitable for the autocomplete. see this example in docs.
Instead of passing the value via the inline handler, you can store the value as a data-* attribute and access it later.
So your code should be something along:
function GetName() {
var dataToSend = JSON.stringify({ prefixText: $('#search').val(), Id: $("#SearchType").val()});
$.ajax({
type: "POST",
data: { jsonData: dataToSend },
url: "GetName",
datatype: "json",
success: function (result) {
var htmlString ="<table>";
$.each(result, function (i, Name) {
htmlString +="<tr><td ><Label>" + Name.Value + "</label></td><td> <input type='text' class = 'form-control Supervisor' data-name='"+ Name.Text + "'/></td></tr>";
});
},
error: function (xhr, status) {
alert(status);
}
})
$("#ResourceNames").append(htmlString);
$(".Supervisor")..autocomplete({
source: "GetSupervisor" // where GetSupervisor is your data source
});
}
If you want to manually send requests along with data and pass the results into the autocomplete, you can specify an function as the value of source option. (See my another answer for more info). for example:
$(".Supervisor").autocomplete({
source: function(request,response){
/*send the request here.
request.term contains the current value entered in textfield
pass the results you want to display like response(data)*/
}
});
Read the API documentation, play with it for a while and you'll be able to get it working.
I have the following code in my MVC controller:
[HttpPost]
public PartialViewResult GetPartialDiv(int id /* drop down value */)
{
PartyInvites.Models.GuestResponse guestResponse = new PartyInvites.Models.GuestResponse();
guestResponse.Name = "this was generated from this ddl id:";
return PartialView("MyPartialView", guestResponse);
}
Then this in my javascript at the top of my view:
$(document).ready(function () {
$(".SelectedCustomer").change( function (event) {
$.ajax({
url: "#Url.Action("GetPartialDiv/")" + $(this).val(),
data: { id : $(this).val() /* add other additional parameters */ },
cache: false,
type: "POST",
dataType: "html",
success: function (data, textStatus, XMLHttpRequest) {
SetData(data);
}
});
});
function SetData(data)
{
$("#divPartialView").html( data ); // HTML DOM replace
}
});
Then finally my html:
<div id="divPartialView">
#Html.Partial("~/Views/MyPartialView.cshtml", Model)
</div>
Essentially when a my dropdown tag (which has a class called SelectedCustomer) has an onchange fired it should fire the post call. Which it does and I can debug into my controller and it even goes back successfully passes back the PartialViewResult but then the success SetData() function doesnt get called and instead I get a 500 internal server error as below on Google CHromes console:
POST http:// localhost:45108/Home/GetPartialDiv/1 500 (Internal Server
Error) jquery-1.9.1.min.js:5 b.ajaxTransport.send
jquery-1.9.1.min.js:5 b.extend.ajax jquery-1.9.1.min.js:5 (anonymous
function) 5:25 b.event.dispatch jquery-1.9.1.min.js:3
b.event.add.v.handle jquery-1.9.1.min.js:3
Any ideas what I'm doing wrong? I've googled this one to death!
this line is not true: url: "#Url.Action("GetPartialDiv/")" + $(this).val(),
$.ajax data attribute is already included route value. So just define url in url attribute. write route value in data attribute.
$(".SelectedCustomer").change( function (event) {
$.ajax({
url: '#Url.Action("GetPartialDiv", "Home")',
data: { id : $(this).val() /* add other additional parameters */ },
cache: false,
type: "POST",
dataType: "html",
success: function (data, textStatus, XMLHttpRequest) {
SetData(data);
}
});
});
I am using ASP.NET MVC3 with EF Code First. I have not worked previously with jQuery. I would like to add autocomplete capability to a dropdownlist that is bound to my model. The dropdownlist stores the ID, and displays the value.
So, how do I wire up the jQuery UI auto complete widget to display the value as the user is typing but store the ID?
I will need multiple auto complete dropdowns in one view too.
I saw this plugin: http://harvesthq.github.com/chosen/ but I am not sure I want to add more "stuff" to my project. Is there a way to do this with jQuery UI?
Update
I just posted a sample project showcasing the jQueryUI autocomplete on a textbox at GitHub
https://github.com/alfalfastrange/jQueryAutocompleteSample
I use it with regular MVC TextBox like
#Html.TextBoxFor(model => model.MainBranch, new {id = "SearchField", #class = "ui-widget TextField_220" })
Here's a clip of my Ajax call
It initially checks its internal cached for the item being searched for, if not found it fires off the Ajax request to my controller action to retrieve matching records
$("#SearchField").autocomplete({
source: function (request, response) {
var term = request.term;
if (term in entityCache) {
response(entityCache[term]);
return;
}
if (entitiesXhr != null) {
entitiesXhr.abort();
}
$.ajax({
url: actionUrl,
data: request,
type: "GET",
contentType: "application/json; charset=utf-8",
timeout: 10000,
dataType: "json",
success: function (data) {
entityCache[term] = term;
response($.map(data, function (item) {
return { label: item.SchoolName, value: item.EntityName, id: item.EntityID, code: item.EntityCode };
}));
}
});
},
minLength: 3,
select: function (event, result) {
var id = result.item.id;
var code = result.item.code;
getEntityXhr(id, code);
}
});
This isn't all the code but you should be able to see here how the cache is search, and then the Ajax call is made, and then what is done with the response. I have a select section so I can do something with the selected value
This is what I did FWIW.
$(document).ready(function () {
$('#CustomerByName').autocomplete(
{
source: function (request, response) {
$.ajax(
{
url: "/Cases/FindByName", type: "GET", dataType: "json",
data: { searchText: request.term, maxResults: 10 },
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data, function (item) {
return {
label: item.CustomerName,
value: item.CustomerName,
id: item.CustomerID
}
})
);
},
});
},
select: function (event, ui) {
$('#CustomerID').val(ui.item.id);
},
minLength: 1
});
});
Works great!
I have seen this issue many times. You can see some of my code that works this out at cascading dropdown loses select items after post
also this link maybe helpful - http://geekswithblogs.net/ranganh/archive/2011/06/14/cascading-dropdownlist-in-asp.net-mvc-3-using-jquery.aspx