When an POST is made to the controller, the controller responds with exactly what I want the browser to render. But the browser does not render the response. I've verified the response is good in Fiddler.
The code below shows what I think is relavent code. The controller action method that returns the response, part of the template that has the mvc helper code, javascript/jquery code that fires the ajax call with the form inputs.
I want to use the FormCollection. Why doesn't the browser render the response and what can I do to fix it?
BoMController
public ActionResult GetBillOfMaterialsView(FormCollection frmColl){
// snipped out model interaction
return PartialView("~/Views/Project/Index.cshtml", project);
}
Index.cshtml
#using (Html.BeginForm("GetBillOfMaterialsView", "BoM", FormMethod.Post, new {id = "frmGetBom"})) {
// selProj input select code removed for brevity
}
function submitGetBoM() {
var frmGetBom = $('#frmGetBom');
$.ajax({
type: 'POST',
url: frmGetBom.attr('action'),
data: frmGetBom.serialize()
});
}
$(document).ready(function() {
$('#selProj').selectmenu( {
select: function(){submitGetBoM()}
}).addClass("overflow");
});
Invoking $.ajax alone doesn't append the response from the server to the document, you have to use the success callback to manually fetch the response and append it.
For example:
$.ajax({
type: 'POST',
url: frmGetBom.attr('action'),
data: frmGetBom.serialize(),
success: function(response) {
$('#someContainerId').html(response);
}
});
Alternatively, use load() that is a shorthand to the above:
$('#someContainerId').load(frmGetBom.attr('action'), frmGetBom.serializeArray());
See Documentation
Your client code doesn't do anything with the returned values from the server:
function submitGetBoM() {
var frmGetBom = $('#frmGetBom');
$.ajax({
type: 'POST',
url: frmGetBom.attr('action'),
data: frmGetBom.serialize(),
success: function() { alert('ok'); }
});
}
This would popup an alert on success.
Related
I need a way to generate a new unique id for a user when a person focuses out of a textbox. I am using MVC 5 for this application. Here is my controller, everything in the controller has been unit tested and it does return the string value that I need.
Controller. I was able to visit that URL, and I did download a JSON file with the correct data.
public ActionResult GetNewId()
{
string newId = utils.newEmployeeId();
return Json(new {eId = newId}, JsonRequestBehavior.AllowGet);
}
Javascript, JQuery call to that controller. I do not know how to properly reference the ActionResult. I keep getting undefined errors on eId.
$(function () {
$('#employeeId').focusout(function () {
if($("#employeeId").val() === "NP")
$.ajax({
type: 'GET',
url: '#Html.ActionLink("GetNewId", "Employees")',
data: { 'eId': eId },
dataType: 'json',
success: function (response) {
$("#employeeId").val(eId);
},
error: function (response) {
alert(response);
}
});
});
});
The problem is with yout ajax request:
1.you need to change the url in the reuqest but it like this
{{yourcontroller}/GetNewId}
2.remove the "data: { 'eId': eId }" you dont need it, youre not posting anything to the server.
change your $("#employeeId").val(eId); to
$("#employeeId").val(response.eId);
this will 100% work
The code below is working for me, but I'm trying to find a way to read all values from the form instead of having to re-create the view model in JavaScript (vm is the name of the parameter of the object).
I tried to serialize the form and pass it in, but maybe my syntax is incorrect.
Any suggestions?
$.ajax({
type: "POST",
dataType: "json",
url: "/post-details-save",
data: addAntiForgeryToken({
vm: ({
Id: $("#PostImageDetails_Id").val(),
Title: $("#PostImageDetails_Title").val(),
Description: $("#PostImageDetails_Description").val(),
CopyrightOwner: $("#PostImageDetails_CopyrightOwner").val(),
CopyrightUrl: $("#PostImageDetails_CopyrightUrl").val(),
SourceName: $("#PostImageDetails_SourceName").val(),
SourceUrl: $("#PostImageDetails_SourceUrl").val(),
SourceLicenseType: $("#PostImageDetails_SourceLicenseType").val()
})
}),
success: postDetailsSaveSuccess,
error: postDetailsSaveError
});
Confirm Form Setup
#using (Html.BeginForm("ActionName", "ControllerName", FormMethod.Post, new { #id = "formID" }))
I have done similar stuff with submitting forms in partial views.
Basically, you need to confirm that your html form is set up correctly:
The AntiForgeryToken
#Html.AntiForgeryToken()
Data Fields
Could look something like the following with the name attribute being important.
<input type="hidden" name="ApproveUserID" id="ApproveUserID" value="#Model.ApproveUserID" />
AJAX The Form
If your form is set up correctly like explained above, you will be able to submit the data via AJAX with something similar to the JS below.
var form = $("#formID");
$.ajax({
url: form.attr('action'),
type: form.attr('method'),
data: form.serialize(), // data to be submitted
success: function (response) {
if (response == "Success") {
//DO SUCCESS STUFF
} else
{
//DO FAILURE STUFF
}
},
error: function () {
//DO ERROR STUFF
}
});
Pro Tip:
You can always expand the data you send by placing
var formData = form.serialize();
Into a variable and expanding it from there.
Good Luck.
Hello I'm posted a question asking what to use to send information from a view to a model. I realize that the info needs to be send to the controller and then to my model. I got some code that send info from my view to my controller:
Here is the Ajax:
$(document).ready(function () {
$("#cmdSend").click(function () {
// Get he content fom the input box
var mydata = document.getElementById("cmdInput").value;
$.ajax({
type: "POST",
url: "/Terminal/processCommand",
data: { cmd: mydata }, // pass the data to the method in the Terminal Contoller
success: function (data) {
alert(data);
},
error: function (e) { alert(e); }
})
});
});
An this is the code in my controller:
[HttpPost]
public ActionResult processCommand(string cmd)
{
return Json(cmd);
}
I've tested it and send my input in json. However my problem is, I don't know how to take the string out of that and send it to my model. Please any help would be appreciated.
As stated in the comments to your question, the terminology you use is a little confusing, but if understood your question correctly, you want an action on your controller on the server to accept a 'command' and work with it.
The following post can be made, in order for the ajax post to successfully hit the action :
$('#cmdSend').click(function () {
var cmdInput = document.getElementById('cmdInput').value;
$.ajax({
url: 'terminal/sendInfo',
type: 'POST',
data: {cmd : cmdInput},
dataType: 'json',
success: function (data) {
//What you want to do with the returned string with data.cmd
}
});
});
The controller action would be like the following :
public class TerminalController : Controller
{
[HttpPost]
public JsonResult sendInfo(string cmd)
{
//Do what you want to do with 'cmd' here.
return Json(new { cmd = "Whatever you want to send" }, JsonRequestBehavior.AllowGet);
}
}
Hope this helps!
I'm using MVC 4 and I am trying to send a post request and I am getting a successful return from my controller with the resulting view in HTML form, but I'm not sure what to do with it at that point.
JS
$("form").submit(function (e) {
e.preventDefault();
if ($(this).valid()) {
$.ajax({
url: submitUrl, type: "POST", traditional: true,
data: { EventName: 'Name of event'},
success: function(data){
$("#content").html(data);
}
})
}
});
my controller
[HttpPost]
public ActionResult CreateEvent(EventModel model)
{
if(ModelState.IsValid)
{
return RedirectToAction("Index");
}
else
{
return View(model);
}
}
So you can see that my controller either returns a View or a RedirectToAction. In the success callback of my ajax call I am doing the following: $("#content").html(data);
But nothing seems to happen. Can someone help push me in the right direction of properly handling the return of the controller action.
Thank you so much!
If I understand correctly, you have a Create Event form on your page and you want to send an AJAX request to create a new event. Then you want to replace a section in your page #content with the results of the CreateEvent action.
It looks like your AJAX is set up correctly so that CreateEvent returns a successful response. I think you're now confused about the response. You have several options but let's choose two.
JSON response
[HttpPost]
public ActionResult CreateEvent(EventModel model)
{
if(ModelState.IsValid)
{
var event = service.CreateEvent(model); // however you create an event
return Json(event);
}
else
{
// model is not valid so return to original form
return View("Index", model);
}
...
Now you need to generate html markup from the JSON and insert it into #content.
$.ajax({
url: submitUrl, type: "POST", traditional: true,
data: { EventName: 'Name of event'},
success: function(data){
var obj = JSON.Parse(data);
var html; // build html with the obj containing server result
$("#content").html(html);
}
})
or HTML fragment
Instead of returning a full page with a Layout defined we'll return just a PartialView without Layout and all the head and script tags.
[HttpPost]
public ActionResult CreateEvent(EventModel model)
{
if(ModelState.IsValid)
{
var event = service.CreateEvent(model); // however you create an event
return PartialView("CreateEventResult", event);
}
else
{
// model is not valid so return to original form
return View("Index", model);
}
}
Now make a new partial view CreateEventResult.cshtml (Razor)
#model Namespace.EventModelResult
# {
Layout = null;
}
<div>
<!-- this stuff inserted into #content -->
#Model.Date
...
</div>
and the javascript is unchanged
$.ajax({
url: submitUrl, type: "POST", traditional: true,
data: { EventName: 'Name of event'},
success: function(data){
$("#content").html(data);
}
})
Edit:
If your Event creation fails for any reason after you have validated the input, you'll have to decide how you want to respond. One option is to add a response status to the object you return and just display that instead of the newly created Event.
Index.html (View)
<div class="categories_content_container">
#Html.Action("_AddCategory", "Categories")
</div>
_AddCategory.cshtml (PartialView)
<script>
$(document).ready(function () {
$('input[type=submit]').click(function (e) {
e.preventDefault();
$.ajax({
type: "POST",
url: '#Url.Action("_AddCategory", "Categories")',
dataType: "json",
data: $('form').serialize(),
success: function (result) {
$(".categories_content_container").html(result);
},
error: function () {
}
});
});
});
</script>
#using (Html.BeginForm())
{
// form elements
}
Controller
[HttpPost]
public ActionResult _AddCategory(CategoriesViewModel viewModel)
{
if(//success)
{
// DbOperations...
return RedirectToAction("Categories");
}
else
{
// model state is not valid...
return PartialView(viewModel);
}
}
Question: If operation is success I expect that redirect to another page (Categories). But no action, no error message. If operation is not success, it is working like my expected.
How can I do this? How can I route another page with using AJAX post?
Don't redirect from controller actions that are invoked with AJAX. It's useless. You could return the url you want to redirect to as a JsonResult:
[HttpPost]
public ActionResult _AddCategory(CategoriesViewModel viewModel)
{
if(//success)
{
// DbOperations...
return Json(new { redirectTo = Url.Action("Categories") });
}
else
{
// model state is not valid...
return PartialView(viewModel);
}
}
and then on the client test for the presence of this url and act accordingly:
$.ajax({
type: "POST",
url: '#Url.Action("_AddCategory", "Categories")',
data: $('form').serialize(),
success: function (result) {
if (result.redirectTo) {
// The operation was a success on the server as it returned
// a JSON objet with an url property pointing to the location
// you would like to redirect to => now use the window.location.href
// property to redirect the client to this location
window.location.href = result.redirectTo;
} else {
// The server returned a partial view => let's refresh
// the corresponding section of our DOM with it
$(".categories_content_container").html(result);
}
},
error: function () {
}
});
Also notice that I have gotten rid of the dataType: 'json' parameter from your $.ajax() call. That's extremely important as we are not always returning JSON (in your case you were never returning JSON so this parameter was absolutely wrong). In my example we return JSON only in the case of a success and text/html (PartialView) in the case of failure. So you should leave jQuery simply use the Content-Type HTTP response header returned by the server to automatically deduce the type and parse the result parameter passed to your success callback accordingly.
The ajax call you made should not be able to redirect the whole page. It returns data to your asynchronous call only. If you want to perform a redirect, i
the javascript way to redirect is with window.location
So your ajax call should look like this:
<script>
$(document).ready(function () {
$('input[type=submit]').click(function (e) {
e.preventDefault();
$.ajax({
type: "POST",
url: '#Url.Action("_AddCategory", "Categories")',
dataType: "json",
data: $('form').serialize(),
success: function (result) {
window.location='#Url.Action("Categories")';
},
error: function () {
}
});
});
});
</script>
In you action method, instead of returning a partial or redirect, return Json(true);
public ActionResult _AddCategory(CategoriesViewModel viewModel)
{
if(//success)
{
return Json(true);
}
else
{
return Json(false);
}
}