How to run JavaScript code on Success of Form submit? - javascript

I have an Asp.Net MVC web application. I want to run some code on the successful response of the API method which is called on form submit.
I have the below Code.
#using (Html.BeginForm("APIMethod", "Configuration", FormMethod.Post, new { #class = "form-horizontal", id = "formID" }))
{
}
$('#formID').submit(function (e) {
$.validator.unobtrusive.parse("form");
e.preventDefault();
if ($(this).valid()) {
FunctionToBeCalled(); //JS function
}
}
But FunctionToBeCalled() function gets called before the APIMethod(), but I want to run the FunctionToBeCalled() function after the response of APIMethod().
So I made the below changes by referring this link. But now the APIMethod is getting called twice.
$('#formID').submit(function (e) {
$.validator.unobtrusive.parse("form");
e.preventDefault();
if ($(this).valid()) {
//Some custom javasctipt valiadations
$.ajax({
url: $('#formID').attr('action'),
type: 'POST',
data: $('#formID').serialize(),
success: function () {
console.log('form submitted.');
FunctionToBeCalled(); //JS function
}
});
}
}
function FunctionToBeCalled(){alert('hello');}
So I am not able to solve the issue.

If you want to execute some work on success, fail, etc. situation of form submission, then you would need to use Ajax call in your view. As you use ASP.NET MVC, you can try the following approach.
View:
$('form').submit(function (event) {
event.preventDefault();
var formdata = $('#demoForm').serialize();
//If you are uploading files, then you need to use "FormData" instead of "serialize()" method.
//var formdata = new FormData($('#demoForm').get(0));
$.ajax({
type: "POST",
url: "/DemoController/Save",
cache: false,
dataType: "json",
data: formdata,
/* If you are uploading files, then processData and contentType must be set to
false in order for FormData to work (otherwise comment out both of them) */
processData: false, //For posting uploaded files
contentType: false, //For posting uploaded files
//
//Callback Functions (for more information http://api.jquery.com/jquery.ajax/)
beforeSend: function () {
//e.g. show "Loading" indicator
},
error: function (response) {
$("#error_message").html(data);
},
success: function (data, textStatus, XMLHttpRequest) {
$('#result').html(data); //e.g. display message in a div
},
complete: function () {
//e.g. hide "Loading" indicator
},
});
});
Controller:
public JsonResult Save(DemoViewModel model)
{
//...code omitted for brevity
return Json(new { success = true, data = model, message = "Data saved successfully."
}
Update: If SubmitButton calls a JavaScript method or uses AJAX call, the validation should be made in this method instead of button click as shown below. Otherwise, the request is still sent to the Controller without validation.
function save(event) {
//Validate the form before sending the request to the Controller
if (!$("#formID").valid()) {
return false;
}
...
}

Update your function as follows.
$('#formID').submit(function (e) {
e.preventDefault();
try{
$.validator.unobtrusive.parse("form");
if ($(this).valid()) {
$.ajax({
url: $('#formID').attr('action'),
type: 'POST',
data: $('#formID').serialize(),
success: function () {
console.log('form submitted.');
FunctionToBeCalled(); //JS function
}
});
}
}
catch(e){
console.log(e);
}
});
Check the browser console for fetching error. The above code will prevent of submitting the form.
I think line $.validator.unobtrusive.parse("form") were throwing error.
For that use you need to add the following jQuery libraries.
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.9/jquery.validate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.11/jquery.validate.unobtrusive.min.js"></script>

I think you should remove razor form tag if you want to post your form using ajax call and add post api URL directly to ajax request instead of getting it from your razor form tag using id:
Here is the revised version of your code :
<form method="post" id="formID">
<!-- Your form fields here -->
<button id="submit">Submit</button>
</form>
Submit your form on button click like:
$('#submit').on('click', function (evt) {
evt.preventDefault();
$.ajax({
url: "/Configuration/APIMethod",
type: 'POST',
dataType : 'json',
data: $('#formID').serialize(),
success: function () {
console.log('form submitted.');
FunctionToBeCalled(); //JS function
}
});
});
function FunctionToBeCalled(){alert('hello');}

You need to use Ajax.BeginForm, this article should help [https://www.c-sharpcorner.com/article/asp-net-mvc-5-ajax-beginform-ajaxoptions-onsuccess-onfailure/ ]

The major thing here is that I didn't use a submit button, I used a link instead and handled the rest in the js file. This way, the form would nver be submitted if the js file is not on the page, and with this js file, it initiates a form submission by itself rather than th form submitting when the submit button is clicked
You can adapt this to your solution as see how it respond. I have somthing like this in production and it works fine.
(function() {
$(function() {
var _$pageSection = $('#ProccessProductId');
var _$formname = _$pageSection.find('form[name=productForm]');
_$formname.find('.buy-product').on('click', function(e) {
e.preventDefault();
if (!_$formname.valid()) {
return;
}
var formData = _$formname.serializeFormToObject();
//set busy animation
$.ajax({
url: 'https://..../', //_$formname.attr('action')
type: 'POST',
data: formData,
success: function(content) {
AnotherProcess(content.Id)
},
error: function(e) {
//notify user of error
}
}).always(function() {
// clear busy animation
});
});
function AnotherProcess(id) {
//Perform your operation
}
}
}
<div class="row" id="ProccessProductId">
#using (Html.BeginForm("APIMethod", "Configuration", FormMethod.Post, new { #class = "form-horizontal", name="productForm" id = "formID" })) {
<li class="buy-product">Save & Proceed</li>
}
</div>

Related

problem with prevent and continue submit form after ajax execution

I have form with select. If select value is equal to 2 then part of form is sendign asynch via ajax and later the rest of the form should be sending via POST function. My problem is when I click submit ajax execution is performs correctly but POST method stuck, nothing happens. It looks like be page refresh.
My code
$('form').submit(function(e) {
if($('#car_type').val() == 2)
{
e.preventDefault();
e.returnValue = false;
var type = $('#new_type').val();
var number = $('#numer').val();
var form = $(this);
$.ajax({
url: "{{ url('cars/type') }}",
method: "POST",
context: form,
data: {type: type, number: number, _token: "{{ csrf_token() }}"},
success: function (result) {
if (result.result > 0) {
} else {
$("#msg").html("Errors, try again later!");
$("#msg").fadeOut(2000);
}
},
error: function (xhr) {
console.log(xhr.responseText);
},
complete: function() {
this.off('submit');
this.submit();
}
})
}
});

Laravel - do not continue after form validator if ajax request

I want to create a ajax form validation that verifies that form data and gives user instant feedback before really submitting the form.
For this i added a javascript function on form submit:
<form id="x" onsubmit="return dosubmit(this)" action="{{ url('/x') }}" method="POST">
<script>
function dosubmit(form) {
$.ajax({
url: $(form).attr('action'),
type: 'post',
data: $(form).serializeArray()
}).done(function (data) {
form.submit();
}).fail(function (data) {
alert('error');
});
return false;
}
</script>
And i have custom a form validator request:
class X extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required',
];
}
}
When my ajax request fails everything works fine. My form validator returns the error in json and i can display it to user. The problem is that when it is successful it actually posts the data two times - first time from the ajax request and second time because i call form.submit() after ajax request is successful. Because i want to redirect the user after submit i would actually like only the second submit to reach the controller. This means i have to stop the ajax request after validation. My current workaround is that i have a line like this in my controller:
public function store(X $request)
{
if ($request->ajax()) {
return;
}
// only actual request reaches here
}
This works, but its not pretty. I don't like including this line in my controller. I would be happy if i could do something similar in my request validator, but I cant find a good way to return after validation from there. Any ideas how can i accomplish this?
You can try it like this:
<script>
function dosubmit(form) {
$.ajax({
async: false, // make ajax not async
url: $(form).attr('action'),
type: 'post',
data: $(form).serializeArray()
}).done(function (data) {
form.submit();
}).fail(function (data) {
alert('error');
});
return false;
}
</script>
and in controller just do it normally without this...
if ($request->ajax()) {
return;
}
And please give feedback if it works...I am also interested.
Your problem can be solved with some changed in javascript code. I think you're confused about what deferred.done() method will do. In your code, you're submitting your form twice.
Let me break down your js script, the done() method is used to do further actions after submitting your form (Please refer).
In your code, the first $.ajax actually submits your form to backend (here, if there are any errors from backend you can handle them in fail section). If the form submits successfully without any errors, then in done section you can define functions or actions about what you want to do after a successful form submission.
Instead of defining what to do after a successful form submission, you are resubmitting the same form again. So remove that part from js code and also the workaround you've done in your backend.
function dosubmit(form) {
$.ajax({
url: $(form).attr('action'),
type: 'post',
data: $(form).serializeArray()
}).done(function (data) {
// form.submit();
// handle successful form submission
}).fail(function (data) {
alert('error');
});
return false;
}

ASP.NET Ajax Serialize Form & Prevent default submit

I am trying to serialize form data and bind it to the model parameter of my controller actionresult. For some reason I cannot prevent the default submit produced by the jquery/javascript below. You can see that i put multiple e.preventDefault()s .. Obviously I'd only need to use the 1st one (if it worked), but NONE of them work. The Form fully submits everytime, so the .done() part of my ajax call is never run.
$(document).ready(function () {
$('.save-attendance-record-button').click(function() {
$('#form-edit-attendance-record').submit();
$('#form-edit-attendance-record').on('submit', function(e) {
e.preventDefault();
return false;
var formData = $(this).serialize();
$.ajax({
dataType: 'html',
method: 'post',
url: resolveUrl('~/Home/EditAttendanceRecord'),
data: formData
})
.done(function (data) {
e.preventDefault();
$('#attendance-records-partial').html(data);
});
e.preventDefault();
});
});
});
[HttpPost]
public ActionResult EditAttendanceRecord(AttendanceRecord record)
{
//...
}

Submit Ajax Form via php without document.ready

I am submitting a number of forms on my page via php using Ajax. The code works great in forms preloaded with the page. However, I need to submit some dynamic forms that don't load with the page, they are called via other javascript functions.
Please, I need someone to help me review the code for use for forms that don't load with the page. Also the 'failure' condition is not working.
The code is below:
<script type="text/javascript">
feedbar = document.getElementById("feedbar");
jQuery(document).ready(function() {
$('#addressform').on('submit', function (e) {
$.ajax({
type: 'post',
url: 'data/process.php',
data: $('#addressform').serialize(),
success: function () {
feedbar.innerHTML='<div class="text-success">New Addressed Saved Successfully</div>';
},
failure: function () {
feedbar.innerHTML='<div class="text-danger">Error Saving New Address</div>';
}
});
e.preventDefault();
});
});
Thanks.
You need to bind event by existing html (e.g body).
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on()
see api: https://api.jquery.com/on/
Try like this:
$("body").on('submit', '#addressform',function (e) {
$.ajax({
type: 'post',
url: 'data/process.php',
data: $('#addressform').serialize(),
success: function () {
feedbar.innerHTML='<div class="text-success">New Addressed Saved Successfully</div>';
},
failure: function () {
feedbar.innerHTML='<div class="text-danger">Error Saving New Address</div>';
}
});
e.preventDefault();
});
});
you can delegate to document:
$(document).on('submit', '#addressform', function (e) {
$.ajax({
type: 'post',
url: 'data/process.php',
data: $(this).serialize(), // <----serialize with "this"
success: function () {
feedbar.innerHTML='<div class="text-success">New Addressed Saved Successfully</div>';
},
error: function () { //<----use error function instead
feedbar.innerHTML='<div class="text-danger">Error Saving New Address</div>';
}
});
e.preventDefault();
});
});
As you have posted this line as below:
I need to submit some dynamic forms that don't load with the page
What i understand with this line is you want a common submit function for all forms which are generated dynamically, then you can do this:
$(document).on('submit', 'form', function (e) {
$.ajax({
type: 'post',
url: 'data/process.php',
data: $(this).serialize(), // <----"this" is current form context
success: function () {
//some stuff
},
error: function () { //<----use error function instead
//some stuff
}
});
e.preventDefault();
});
});
For your last comment:
You can try to get the text in ajax response like this:
success: function (data) {
feedbar.innerHTML='<div class="text-success">'+ data +'</div>';
},
error: function (xhr) { //<----use error function instead
feedbar.innerHTML='<div class="text-danger">' + xhr.responseText + '</div>';
}
if Success:
here in success function you get the response in data which is the arguement in success function, this holds the response which it requested to the serverside.
if Error:
Same way if something goes wrong at the serverside or any kind of execption has been occured then xhr which is the arguement of error function holds the responseText.
And finally i suggest you that you can place your response in feedbar selector using jQuery this way:
var $feedbar = $('#feedbar');
so in success function:
$feedbar.html('<div class="text-success">'+ data +'</div>');
so in error function:
$feedbar.html('<div class="text-success">'+ xhr.responseText +'</div>');

MVC3 AJAX passing data to controller. It's being submitted twice

So I have a table that gets transformed to an array using:
var result = $("#enrolledStudents").sortable('toArray');
But when I go a head an pass that into my controller like so:
$("#update-enroll").click(function () {
var result = $("#enrolledStudents").sortable('toArray');
$.ajax({
url: '#Url.Action("Enrollment", "Classroom")',
data: { students: result },
type: 'POST',
traditional: true
});
});
My debugging breakpoint gets set off twice, causing issues to arise. What is the proper way to submit data to my controller on POST?
Per my comments, there are a couple things that could be causing this.
You have have the unobtrusive file(s) loaded multiple times
Your form has an action method defined, and your button is inside the form tag as a submit button. This will submit the form, and then the click will also submit the form - see example
Example
<form action="/somerowout/someaction">
<input type="text" id="text1"/>
<input type="text" id="text1"/>
<input type="submit" />
</form>
If you need to validate a value on your form before posting, don't hook up an additional Ajax call. Your javascript will look something like:
$(document).ready(function () {
$("form").submit(function(){
var result = $("#enrolledStudents").sortable('toArray');
if(result == null){
//do something to show validation failed
return false;
}
return true;
});
});
And your form code would then look something like:
#using (#Ajax.BeginForm(new AjaxOptions { })) {
<input type="text" id="text1"/>
<input type="text" id="text1"/>
<input type="submit" />
}
If you want to use Ajax rather than the Html Helpers, use a div instead of a form, and you won't get a duplicate post. Here's how you could achieve this:
<div id="enrolledStudents">
<--! your elements -->
<button id="saveStudents">Save</button>
</div>
JavaScript
$(document).ready(function () {
$("saveStudents").click(function(){
var result = $("#enrolledStudents").sortable('toArray');
if(result !== null){ /* do some kind of check here. */
$.ajax({
url: '#Url.Action("Enrollment", "Classroom")',
data: { students: result },
type: 'POST',
traditional: true,
success : function(data) {
if (data.status) {
window.location = data.route;
}
}
})
} else {
/* notify ui that save didn't happpen */
}
});
});
Example Controller Action
When posting your data using Ajax, here's an example of how to pass the route
[HttpPost]
public ActionResult SomethingPost(SomeModel model) {
if (Request.IsAjaxRequest()) {
var json = new {
status = true,
route = #Url.RouteUrl("MyRouteName", new { /* route values */ })
};
return Json(json, JsonRequestBehavior.AllowGet);
}
}
Are you sure you are preventing the default behaviour (form POSTING) of the submit button ? use preventDefault to do so.
$("#update-enroll").click(function (e) {
e.preventDefault();
//rest of the code
});
EDIT : As per the comment
To do the redirect in the ajax handler, you need to return the URL to be redirected in a JSON Response back to the calle.
[HttpPost]
public ActionResult Classroom(string students)
{
//do some operaton
if(Request.IsAjax())
{
//This is an Ajax call
return Json(new
{
Status="Success",
NewUrl = Url.Action("Index","Home")
});
}
else
{
//Normal request. Use RedirectToActiom
return RedirectToAction("Index","Home");
}
}
Now in your ajax call check the JSON result and do the redirect.
$.ajax({
url: '#Url.Action("Enrollment", "Classroom")',
data: { students: result },
type: 'POST',
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (data) {
if(data.Status=="Success")
{
window.location.href = data.Newrl;
}
else
{
alert("some error");
}
}
});
Check if you don't have the jquery files loaded twice. I had this behavior and the problem was files loaded twice.

Categories

Resources