Is there a way I can get the returned value from an action using .submit event listener in jQuery?
I have a problem which is when the action is completed it returns a JSON file and my browser navigates to an empty page and just display the JSON returned. I don't want that to happen, I want to be able to read the JSON result and based on it decide what to do.
Here's my POC:
View:
#using (Html.BeginForm("SubmitTest", "DMS", FormMethod.Post, htmlAttributes: new { id = "formId" }))
{
<input type="submit" value="Sumbit" />
}
Controller:
public JsonResult SubmitTest()
{
return Json("Done");
}
Script:
$(document).ready(function () {
$("formId").submit(function () {
alert("Submitted");
});
});
you can add event.preventDefault or return false to prevent the default event from occurring . so it won't navigate to an empty page.
$(document).ready(function () {
$("formId").submit(function () {
alert("Submitted");
return false;
});
});
EDIT:
if you want to get the response you need to make an ajax request and get the form data from the fields. you can't get the response with submit function.
$(document).ready(function () {
$("formId").submit(function () {
/// make an AJAX request
$.post(
$(this).attr('action'), //// action url
$(this).serialize(), //// serialize form fields
function(json) {
alert(json);/// json response
}, 'json');
return false; /// prevent navigation
});
});
Use an AJAX form instead of the HTML form, this way you can check the response after it is submitted and do whatever you need using the OnSuccess handler.
For detailed info refer to this article
Related
I'm uploading a file via a form with the following script tag:
#using (Html.BeginForm("CreateCompResponse", "Surveys", FormMethod.Post, new { enctype = "multipart/form-data", onsubmit = "return myFunction()" }))
Upon successful upload, the controller should RedirectToAction:
return Json(new
{
redirectUrl = Url.Action("CreateBenefitSummary", "Surveys"),
isRedirect = true
});
In the view, I'm handling the function as follows (I copied and pasted this from another SO post, as I don't know JavaScript):
<script type="text/javascript">
success: function(json) {
if (json.isRedirect) {
window.location.href = json.redirectUrl;
}
}
</script>
Rather than returning my desired controller action, it returns a JSON string:
{"redirectUrl":"/Surveys/CreateBenefitSummary","isRedirect":true}
How can I get this to redirect to the proper action?
Thanks!
You are using Html.BeginForm which means that the ActionResult you expect is in the PostBack. The way return Json will work is if you use Ajax.BeginForm and pass the function name to it for onsuccess. You should be doing this:
#using (Ajax.BeginForm("CreateCompResponse", "Surveys", new AjaxOptions { OnSuccess = "onSuccess",HttpMethod = "Post" }))
And your function should be
<script type="text/javascript">
function onSuccess(json) {
if (json.isRedirect) {
window.location.href = json.redirectUrl;
}
}
</script>
If you want to use PostBack then you can use RedirectToAction within the processing controller action to check if the upload is successful or not based on the result you can use the above mentioned return RedirectToAction or return View()
I have a button when that button is clicked I want to set a model property to true and be able to receive it in the back end. Code is a bit messed up but bear with me please as I have taken alot of code out of it.
#model FullConfigurationMV
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "MyForm" }))
{
#Html.HiddenFor(model => model.IsTemplate)
// Code removed for brevity
<button id="DraftName">Click me</button>
}
<script>
$( document ).ready(function() {
debugger;
$("#DraftName").click(function()
{
#Model.IsTemplate = true; // I AM SETTING THE VALUE AS TRUE
SaveStyles();
});
});
</script>
<script>
function SaveStyles() {
var data = $('#MyForm').serialize();
var URL = "SOME URL"
$.ajax({
url: URL,
type: 'POST',
data: data,
success: function (result) {
},
error: function (error) {
}
});
}
</script>
POST ACTION
public JsonResult SaveStyles(FullConfigurationMV data)
{
// data.IsTemplate is coming out to be false
// Rest of the UI control data is coming back properly
}
EDIT
Since I have below code. is that the issue?
var data = $('#MyForm').serialize();
Think about this problem a little differently.
All the view does is render html. Since you have a form in html, all your javascript has to do is to set the form element's value to true.
You should be able to use the jQuery selector like
$('input:hidden[name=IsTemplate]').val(true);
And your form serialize should pick it up.
Razor view are generated in server side. So when you browser get the HTML there is no razor code in it so the following code will not work:
$("#DraftName").click(function()
{
#Model.IsTemplate = true; // <-- this will not work and will not exist in client side
SaveStyles();
});
You should set the hidden field you just put in your form #Html.HiddenFor(model => model.IsTemplate) which generate <input type='hidden' /> and just update your javascript code by doing this:
$("#DraftName").click(function()
{
$("#MyForm input[type='hidden']").val("true"); // <- Replace your Razor code with this.
SaveStyles();
});
I have tried other answers but none have worked. The javascript code is supposed to submit a list of product id's to a php page. When products are selected, the submit button triggers the submit function.
function submit() {
var ids = bundle.map(function(item){
$('#product-'+item.id+' button').attr('disabled', false);
return item.id;
});
console.log(ids);
//send the ids to api
bundle = [];
$('.bundle-list').empty();
$('.total').html('No item in bundle');
$('.submit').addClass('hide');
}
I have tried inserting this line in the function
document.getElementByID("test").value = bundle;
and a hidden tag within the form but can't get the var to submit to PHP
<input type="hidden" id="test" name="test" visibility="hidden"></input>
Where should the position of the hidden element be relative to the JS code? and any other methods of retrieving the ID's?
Either by $.post or $.get variable you can send data to PHP file, but i think you want to save pids in hidden field, but you are not update its value on submit. like
$('#test').html('YOUR DATA')
Try this..
function submit() {
var ids = bundle.map(function(item){
$('#product-'+item.id+' button').attr('disabled', false);
return item.id;
});
$.ajax({
url: 'YOUR_URL HERE',
type: 'POST',
data: { qry: ids },
success: function(data) {
///WHEN SUCCESS
}
},
error: function(e) {
}
});
}
I have this button in a form:
<button id="save" type="submit" formaction="#Url.Action("SaveEvent")" formmethod="post">Save</button>
Which posts to this controller:
public async Task<ActionResult> SaveEventAsync(EventDataModel vm)
{
// save to db etc...
TempData["Saved"] = true;
return RedirectToActionWithReturnUrl("EventDetail", new { eventId = vm.EventId });
}
This redirects me fine to the detail page. But if I then add this JS function to do the post, I don't get redirected nor do I see the value in TempData.
$('#save').click(function(e){
e.preventDefault();
$.post( "SaveEvent", {
EventID: "#Model.EventId",
SomeValue: 123
});
}
I tried redirecting in the JS function but it doesn't return me the newly saved values:
window.location = '#Html.Raw(#Url.Action("EventDetail", new { eventId = #Model.EventId}))';
Could someone please explain why the redirect in the controller does not work when posting from JS?
The Redirect related methods in controller (Redirect,RedirectToAction etc) returns a 302 response with the new url to be redirected to as the value of the location header and browsers will usually issue a new GET request to that.
You should not be making the call to an action method which returns a 302 response from an ajax call. Instead, you should return a json response to the ajax call which is making the request.
public async Task<ActionResult> SaveEventAsync(EventDataModel vm)
{
// save to db etc...
return Json(new {status = "success"});
}
and in your $.post method callback, inspect the response and do the redirection.
$('#save').click(function(e){
e.preventDefault();
var url="#Url.Action("SaveEvent","YourControllerName")";
$.post(url, { EventID: "#Model.EventId", SomeValue: 123 }, function(res){
if (res.status === "success") {
window.location.href =" #Url.Action("EventDetail","YourControllerName",
new { eventId=Model.EventId })";
}
});
});
I updated your code to use Url.Action method to build the correct relative url to the action method(s). If you javascript code is inside a separate js file, build the base url in your razor page and pass to your js code as explained in this post.
I have a formRemote that calls a function in my controller when it is submitted like this:
<g:formRemote name="editIndivRecForm" url="[controller: 'customer', action:'saveEditedIndividualRecord']" onSuccess="doResult();">
This form is submitted by clicking on a button. Rather, a button that is clicked called 'save' will do other things among clicking the form's submit button via Javascript. Here is the click handler for this button:
$('#save').click(function () {
$("#uniqueId").prop('disabled', false); // Have to enable before form submission else it doesn't go back as a param to controller.
$("#secondaryId").prop('disabled', false);
$("#submit").trigger("click"); // formRemote's submit button
$('#editIndivRecForm').reset;
<g:remoteFunction controller="customer"
action="remediationSearch"
update="content_area"
params="{rerender: true}"/>
});
The problem I'm running into is that I need the function of my controller called by the click handler remediationSearch to run AFTER the function of the controller called by the formRemote's submission saveEditedIndividualRecord is done executing. But it is happening the other way around. And for some reason the function onSuccess="doResult();" doesn't even execute otherwise I was going to move the following code into its body to make things work the way I want:
<g:remoteFunction controller="customer"
action="remediationSearch"
update="content_area"
params="{rerender: true}"/>
here is how doResult is now:
function doResult() {
console.log("done.");
}
the formRemote is submitted but the doResult function prints nothing to the console.
Seeing as all of the Grails AJAX related tags have been deprecated, I would recommend trying it this way:
Markup:
<form id="editIndivRecForm" onsubmit="return false;">
<!-- add fields here -->
<input type="text" id="uniqueId" value="${something}">
<input type="text" id="secondaryId" value="${something}">
<button id="save" type="button">
</form>
JavaScript:
// Function to update your content_area div
function updateContentArea() {
var params = { rerender: true };
var url = "${createLink(controller: 'customer', action: 'remediationSearch')}";
$.get(url, params, function(data) {
$("#content_area").empty().append(data);
});
}
$("#save").on('click', function() {
// Collect values from form and submit ajax request
// Using name and description for example fields here:
var data = {
name: $("#name").val(),
description: $("#description").val(),
uniqueId: $("#uniqueId").val(),
secondaryId: $("#secondaryId").val()
};
var url = "${createLink(controller: 'customer', action: 'saveEditedIndividualRecord')}";
// Submit the (first) AJAX request
$.ajax({
type: "post",
url: url,
data: data,
success: function() {
doResult();
$('#editIndivRecForm').reset();
updateContentArea();
}
});
}