What am trying to do is to post on form submit to a action and catch response and that works fine.Problem is when RedirectToAction gets called, it just stays on that same view(it doesn't redirect),or in case model is not valid, it doesn't show model validation. So i guess the problem is with url, but how can I correct it?
jQuery
$("form").on("submit", function (e) {
e.preventDefault();
var form = $(this);
var formURL = form.attr("action");
$.ajax({
type: "POST",
url: formURL,
data: $(this).serialize(),
success: function (response) {
if (response !== null && response.success == false) {
alert(response.responseText);
}
}
});
});
c# asp mvc
public ActionResult Add(SomeModel model) {
if (ModelState.IsValid) {
if (true) {
return Json(new { success = false, responseText = "Some error" }, JsonRequestBehavior.AllowGet);
}
return RedirectToAction("Details", new { id = id });
}
//gets called but it doesn't show validation.
return View(model);
}
public ActionResult Details(int id) {
//gets called but it doesn't show the view.
return view(model);
}
Because you're posting your form with an Ajax POST and your in your success function you have alert(response.responseText), you are NOT going to receive a View.
What you need to do is in success function, take the response from Details action and place it inside an HTML element on the page. Like below:
success: function (response) {
$("#div").html(response);
}
On another note, since you're not using a standard FORM and your posting with JavaScript, you wont get built in validation the models provide.
Related
I posted this yesterday but i may not have explained my situation well.
I have 3 grids on a page that are built dynamically through JavaScript.
I then have 3 separate JavaScript methods to set a session when a row is clicked in a certain grid.
Once the session is set i would like it to navigate to the next page.
Here is what i have
OnClick event
$('#clinician-planned').on('click', 'tbody>tr>td:not(:last-child):not(:first-child)', function () {
var ID = $(this).closest("tr").children("td.grid__col--id").find("[name=patient-link]").text().trim();
var Location = '#Url.Action("SetPASession", "Clinician")';
AjaxCall(Location, ID);
});
$('#clinician-recent').on('click', 'tbody>tr>td:not(:last-child):not(:first-child)', function () {
var ID = $(this).closest("tr").children("td.grid__col--id").find("[name=patient-link]").text().trim();
var Location = '#Url.Action("SetRDSession", "Clinician")';
AjaxCall(Location, ID);
});
$('#clinician-theatre').on('click', 'tbody>tr>td:not(:last-child):not(:first-child)', function () {
var ID = $(this).closest("tr").children("td.grid__col--id").find("[name=patient-link]").text().trim();
var Location = '#Url.Action("SetTESession", "Clinician")';
AjaxCall(Location, ID);
});
AJAX Post To Controller
function AjaxCall(Location, ID) {
alert('1');
$.ajax({
type: 'POST',
url: Location,
dataType: 'text',
async: false,
contentType: 'application/json; charset=utf-8',
error: function (response) { alert(JSON.stringify(response)); }
}).done(function (response) {
alert('2');
location.href = "#Url.Action("Summary", "Patient")" + "/" + ID;
});
}
Here are the controller methods
public ActionResult SetPASession()
{
Session.Remove("Clinician");
Session["Clinician"] = "pa";
return Json(null);
}
public ActionResult SetRDSession()
{
Session.Remove("Clinician");
Session["Clinician"] = "rd";
return Json(null);
}
public ActionResult SetTESession()
{
Session.Remove("Clinician");
Session["Clinician"] = "te";
return Json(null);
}
The problem i have is when the row is clicked "alert('1'); shows instantly, however it seems like it takes a while and waits for all grids to be populated before the 2nd alert appears. I have tried putting async: false, but this doesnt seem to work.
Any ideas would be much appreciated.
When I click the button that calls the JavaScript, it executes the script which calls the controller that inserts the record using Entity Framework. But it doesn't always reload the page even when I have the location.reload().
What happens is that it successfully submits the record but doesn't reflect in the grid (the list of records), when I submit another record again the first and 2nd inserted record will now show up. Am I doing something wrong with how I'm handling this?
PS, can someone also review my codes as I'm still quite new to web and MVC. Another question of mine is that my form is set like this: #using (Html.BeginForm("Create", "CableSystemType", FormMethod.Get)) but my submit button is declared POST in formmethod, I'm just wondering if this is good practice and if this has a bearing to my issue.
View
<input type="submit" id="btnSave" value="Save" class="btn btn-success" formmethod="post" onclick="return SaveUser();" />
Javascript
function SaveUser() {
debugger;
var json = {
usrId: $('#usrId').val(),
usrDesc: $('#usrDesc').val(),
usrStatus: $('input[name=usrStatus]:checked').val()
};
var chckUsr = document.getElementById("usrDesc").value;
var chckStat = document.querySelector('input[name="usrStatus"]:checked').value;
if (chckUsr === "") {
alert("Description is required.");
return false;
}
if (chckStat === "") {
alert("Status is required.");
return false;
}
$.ajax({
url: '/User/Save_User',
type: 'POST',
dataType: 'json',
data: JSON.stringify(json),
contentType: 'application/json; charset=utf-8',
success: function (response) {
if (response != null && response.success) {
//User is unique
alert(response.responseText);
} else {
//User already exists
alert("response.responseText);
}
//When I put alert in this area it shows up, but page doesn't refresh. I use Chrome
location.reload();
},
});
};
Controller
public JsonResult Save_User(UserViewModel model)
{
string _message = string.Empty;
using (var _odb = new DBEntities())
{
try
{
if (_odb.USR_MSTR.Any(o => o.USR_DESC == model.usrDesc))
{
return Json(new { success = false, responseText = "User already exists." }, JsonRequestBehavior.AllowGet);
}
else {
USR_MSTR usr_master = new USR_MSTR();
string id = Guid.NewGuid().ToString();
usr_master.USR_ID = Guid.NewGuid().ToString().Remove(5);
usr_master.USR_DESC = model.usrDesc;
usr_master.CREA_DT = DateTime.Now;
if (model.usrStatus == "Active")
{
usr_master.INACTV_DT = null;
}
else if (model.usrStatus == "Inactive")
{
usr_master.INACTV_DT = DateTime.Now;
}
_odb.USR_MSTR.Add(usr_master);
_odb.SaveChanges();
return Json(new { success = true, responseText = "User sucessfully saved." }, JsonRequestBehavior.AllowGet);
}
}
catch (Exception ex)
{
_message = "An error occured.";
_message = ex.InnerException.Message;
}
}
return Json(true);
}
I've got a Spring MVC - JSP web application. Before submitting a specific form I need to fill a text value input with JS/jQuery so the form POSTed contains that info. This text value is the result of an ajax call that should be done when the submit button is clicked but before the form data is send to the controller.
The relevant pieces of code in my JSP are the following:
<script>
//Gets from model a new valid file code number
function getFileCodeNumber(res){
$.ajax({
type: "post",
url: "getFileCodeNumber",
cache: false,
data: { department: $("#department").val(), docType: $("#docType").val() },
success: res,
error: function(){ alert('Error while request..');}
});
}
</script>
<script>
$(function() {
//Other JS code
$("#submitForm").click((function(event) {
if($("#chkLanguage").prop('checked')){
//some stuff
}else{
getFileCodeNumber(function(data){
//do some stuff with 'data'
});
}
}));
});
</script>
<form:form id="form" class="form-horizontal" method="post" action="AddDoc" commandName="document" enctype="multipart/form-data">
<div class="row" style="text-align:center;">
<input id="submitForm" type="submit" class="btn btn-primary btn-lg" name="commit" value="Finish">
</div>
</br>
</form:form>
Just to let you know, the ajax call works perfectly when called from another trigger action in the same JSP, but when called from the "click" function it retrieves an alert error but is shown on screen for less than 1 second and therefore I cannot tell you what does it say. By the way, Firebug throws "NS_ERROR_NOT_AVAILABLE: prompt aborted by user".
Note that I tried to replace "click" trigger for "submit" that happens exactly the same. My guess would be that the form is being submitted before the ajax call is completely done, but I expected "submit" and "click" functions to do the its job before POSTing the data.
Does anybody have a clue?
EDIT : I found out that the alert that I wasn't able to see is printing the error code of the ajax call. However, I've checked the controller's function that gives response to this call and I've seen it gets completed succesfully and retrieves the expected value. What's more, when I call this function from another trigger in the same JSP it works perfectly. Just to let you see the simple code in the controller:
#RequestMapping(value = "getFileCodeNumber", method = RequestMethod.POST, headers = "Accept=*/*")
public #ResponseBody
String getFileCodeNumber(#RequestParam(value = "department", required = true) String department,
#RequestParam(value = "docType", required = true) String docType) {
int n = cdocs.getNewCode(department, docType);
if (n == 0) {
return "EEEE";
} else {
char[] zeros = new char[4];
Arrays.fill(zeros, '0');
DecimalFormat df = new DecimalFormat(String.valueOf(zeros));
System.out.println(df.format(n));
return df.format(n);
}//END_IF
}//END_METHOD
Any ideas?
Try that:
function getFileCodeNumber(res) {
return $.ajax({
type: "post",
url: "getFileCodeNumber",
cache: false,
data: {
department: $("#department").val(),
docType: $("#docType").val()
},
success: res,
error: function () {
alert('Error while request..');
}
});
}
$("#submitForm").click(function (event) {
event.preventDefault();
if ($("#chkLanguage").prop('checked')) {
//some stuff
} else {
getFileCodeNumber(function (data) {
//do some stuff with 'data'
}).done(function () {
$('#form').get(0).submit();
});
}
});
Instead of executing your javascript when the submitbutton is pressed, use a normal button and execute the submit function from the script.
You could do something like this:
function getFileCodeNumber(res){
$.ajax({
type: "post",
url: "getFileCodeNumber",
cache: false,
data: { department: $("#department").val(), docType: $("#docType").val() },
success: res,
error: function(){ alert('Error while request..');}
})
}
$(function() {
if($("#chkLanguage").prop('checked')){
//some stuff
$("#form").submit();
}else{
getFileCodeNumber(function(data){
//do some stuff with 'data'
}).done(function(){
$("#form").submit();
});;
}
});
I have followed this post, but the only thing that works from my solution is the error message alert. :D
My js-ajax code:
$(document).ready(function () {
$('a').click(function (e) {
var data = { 'id': $(this).attr("id") };
var dataVal = JSON.stringify(data);
$.ajax({
type: "POST",
url: "#Url.Action("ActionName", "ControllerName")",
contentType: "application/json; charset=utf-8",
data: dataVal,
dataType: "json",
success: function (id) {
alert(data.d);
alert("yay! it works!");
},
error: function(id){
alert("haha, it doesn't work! Noob!");
}
});
return false;
});
});
It is located at the end of the body, so it loads after all the other html contents are rendered.
This is my call-back function in the controller:
[HttpPost]
public ActionResult Hello(string id)
{
return RedirectToAction(id);
}
and the HTML anchor tag:
Read more
So, what I want is, upon any click of an anchor tag link, this JS to be fired and calling the function from the server-side, passing to it the value of the id parameter, where the call-back function will do its job (which is to call some View, according to the given id).
Buuuuut, I am getting only "haha, it doesn't work! Noob!" alert message. :D Any suggestions ?
Update with some code
RedirectToAction is a method from the framework, that redirects to another action. In this case I redirect to an action that will call me a certain view, for example this one:
public ActionResult Media()
{
//do some stuff here
return View();
}
You have to modify you method
public ActionResult Media()
{
//do some stuff here
return View();
}
to something like
public JsonResult Media()
{
//do some stuff here
return Json(new
{
myData = RenderPartialViewToString("ViewName", optionalModel),
errorMessage = error
});
}
Add following method with reference to ASP.NET MVC Razor: How to render a Razor Partial View's HTML inside the controller action
protected string RenderPartialViewToString(string viewName, object model)
{
if (string.IsNullOrEmpty(viewName))
viewName = ControllerContext.RouteData.GetRequiredString("action");
ViewData.Model = model;
using (StringWriter sw = new StringWriter()) {
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
function ResendEmailInvite(internalUserId, familyMemberId) {
theinternalUserId = internalUserId;
theFamilyMemberId = familyMemberId;
if(confirm('Are you sure you want to resend this family member's invite?')){
$.ajax({
type: "POST",
url:"/Admin/ResendFamilyMemberEmail",
data: {internalUserId : theinternalUserId, familyMemberId : theFamilyMemberId},
success: function(response){
alert(response);
},
error: function(){
alert("Error");
}
});
return false;
}
}
I am using ASP.net MVC 3.
This is an ajax/javascript method in my view.
As far as the syntax goes, is this correct?
The familyMemberId is going to be dynamic, however, the userId is not.
I want to pass the userId from my viewModel to this ajax call, how can I do this?
What you're wanting to do is get the data from the model in your controller into the view. This is what MVC is all about. From the MSDN MVC 4 Tutorial:
Controller:
You can define your model using the VS menu system and the Entity Framework so you're actually accessing the database.
public class YourController : Controller
{
private YourDBContext db = new YourDBContext();
public ActionResult YourAction(int user_id = 0)
{
User user = db.Users.find(user_id);
if(user == null) {
return HttpNotFound(); // Or unauthorized or whatever
}
return View(user);
}
//...
View:
#Model IEnumerable<MvcUser.Models.User>
<!-- other stuff -->
<script type="text/javascript>
// the rest of your script
function ResendEmailInvite(internalUserId, familyMemberId) {
theinternalUserId = #Model.userId;
theFamilyMemberId = familyMemberId;
if(confirm('Are you sure you want to resend this family member's invite?')){
$.ajax({
type: "POST",
url:"/Admin/ResendFamilyMemberEmail",
data: {internalUserId : theinternalUserId, familyMemberId : theFamilyMemberId},
success: function(response){
alert(response);
},
error: function(){
alert("Error");
}
});
return false;
}
}
This works because, as you pointed out, the userId is not dynamic after the page has loaded. You would need to create some other hook in your HTML for javascript to grab if you wanted really dynamic behavior.