problem with prevent and continue submit form after ajax execution - javascript

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();
}
})
}
});

Related

How to run JavaScript code on Success of Form submit?

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>

Why POST request will be called multiple times based on the array during submit form via ajax to the server?

I push the id into the array when checkbox is checked.
var items=[];
$("#selection").click(function(e) {
$(":checkbox").each(function() {
if(this.checked === false) {
this.checked = true;
items.push(this.id);
}
});
});
When I submit, the item saved to database but at the "network monitor', it displays a lot of POST request which is unusual.
$('#grid').submit(function(e){
$.ajaxSetup({
headers: { 'X-CSRF-Token' : $('meta[name=_token]').attr('content') }
});
e.preventDefault();
var formdata = {
item:items
};
$.ajax({
type: "POST",
url: "/addItem",
data: formdata ,
dataType:'json',
success: function(data) {
swal(
'Great!',
'Item added!',
'success'
) ;
}
});
});
During submit the first value is always pass null, but all data will be saved as expected just the POST request will be called based on the number of item in items array. Is there anything wrong with my code?

stopping a function after first click, to prevent more executions

I have this function
function display() {
$.ajax({
url: "new.php",
type: "POST",
data: {
textval: $("#hil").val(),
},
success: function(data) {
$('.daily').html(data);
}
});
}
and it serves its purpose, the only problem is, a user can click on for as many times as possible, and it will send just as many requests to new.php.
What I want is to restrict this to just 1 click and maybe till the next page refresh or cache clear.
Simple example would be :
<script>
var exec=true;
function display() {
if(exec){
alert("test");
exec=false;
}
}
</script>
<button onclick="javascript:display();">Click</button>
In your case it would be :
var exec=true;
function display() {
if(exec){
$.ajax({
url: "new.php",
type: "POST",
data: {
textval: $("#hil").val(),
},
success: function(data) {
$('.daily').html(data);
exec=false;
}
});
}
}
This should do what you want:
Set a global var, that stores if the function already was called/executed.
onceClicked=false;
function display() {
if(!onceClicked) {
onceClicked=true;
$.ajax({
url: "new.php",
type: "POST",
data: {
textval: $("#hil").val(),
},
success: function(data) {
$('.daily').html(data);
}
});
}
}
During onclick, set a boolean flag to true to indicate that user clicked the link before invoking the display() function. Inside the display() function, check the boolean flag and continue only if it is true. Reset the flag to false after the AJAX completed processing (successful or failed).
You can use Lock variable like below.
var lock = false;
function display() {
if (lock == true) {
return;
}
lock = true;
$.ajax({
url: "new.php",
type: "POST",
data: {
textval: $("#hil").val(),
},
success: function (data) {
$('.daily').html(data);
lock = false;
}
});
}
you can implement this with that way too
$(function() {
$('#link').one('click', function() {
alert('your execution one occured');
$(this).removeAttr('onclick');
$(this).removeAttr('href');
});
});
function display(){
alert('your execution two occured');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#" onclick="display();" id='link'>Have you only one chance</a>

event.preventDefault(); only works some of the time with submit form

I am using the Mailchimp API to submit a form. The goal is to prevent the default callback provided by Mailchimp. The majority of the time event.preventDefault() is behaving as it should. Then randomly it will not work:
$(function () {
var $form = $('#mc-embedded-subscribe-form');
$('#mc-embedded-subscribe').on('click', function(event) {
if(event) event.preventDefault();
register($form);
});
});
function register($form) {
$.ajax({
type: $form.attr('method'),
url: $form.attr('action'),
data: $form.serialize(),
cache : false,
dataType : 'json',
contentType: "application/json; charset=utf-8",
error : function(err) { alert("Could not connect to the registration server. Please try again later."); },
success : function(data) {
if (data.result != "success") {
// Something went wrong, do something to notify the user. maybe alert(data.msg);
var message = data.msg
var messageSh = data.msg.substring(4);
if (data.msg == '0 - Please enter a value' || data.msg == '0 - An email address must contain a single #') {
$('#notification_container').html('<span class="alert">'+messageSh+'</span>');
} else {
$('#notification_container').html('<span class="alert">'+message+'</span>');
}
} else {
// It worked, carry on...
var message = data.msg;
$('.popup-promo-container').addClass('thanks');
$('.checkboxes, #mc_embed_signup_scroll').addClass('hidden');
$('.complete-promo').html(message).removeClass('hidden');
setTimeout(function() {
document.querySelector('.popup-promo').style.display = "none";
},20000);
}
}
});
}
Try
take off ready function.
remove if on event
Code:
var $form = $('#mc-embedded-subscribe-form');
$('#mc-embedded-subscribe').on('click', function(event) {
event.preventDefault();
register($form);
});

Parsley.js Dont use remote validation, if value is empty

I've got the following problem. Here is the input I want to validate
<input type="text" name="vatid" data-parsley-remote data-parsley-remote-validator='vatid'/>
and this is the asyncValidator
$('[name="vatid"]').parsley()
.addAsyncValidator('vatid', function (xhr) {
return 404 === xhr.status;
}, confighandler.getConfig().apiUrl + '/checkvatids');
My problem is, that also if the user doesn't enter a value parsley sends an request (on form submit) to the api and then the errors-mesage are triggered. How can I avoid this and only validate if the user has entered something?
Update
big thanks to milz, I've got the following solution and it works like charm :)
define([
'jquery',
'confighandler',
'requirejs-i18n!nls/labels',
'parsleyjs'
], function($, confighandler, Labels) {
'use strict';
return {
initialize: function() {
// add custom validators
window.ParsleyValidator
.addValidator('vatid', function(val) {
var isvalid;
$.ajax({
url: confighandler.getConfig().apiUrl + '/checkvatids/' + val,
dataType: 'json',
type: 'get',
async: false,
success: function(response) {
isvalid = (response.result.data.isvalid === 'true') ? true : false;
},
error: function() {
isvalid = false;
}
});
return isvalid;
}, 32).addMessage('de', 'vatid', Labels.validation.vatid);
}
};
});
You can accomplish that, but you can't use ParsleyRemote. The problem with remote validators is that you cannot verify if the value is empty or not before the remote ajax call is made.
A possible solution to this issue is adding a custom validator with .addValidator and then place an ajax call.
In this case you don't even need to check if the input has any content because the validator is only executed when the input is not empty.
<input type="text" name="vatid" data-parsley-vatid />
<script>
$(document).ready(function() {
window.ParsleyValidator
.addValidator('vatid', function (value, requirement) {
var response = false;
$.ajax({
url: confighandler.getConfig().apiUrl + '/checkvatids',
data: {vatid: value},
dataType: 'json',
type: 'get',
async: false,
success: function(data) {
response = true;
},
error: function() {
response = false;
}
});
return response;
}, 32)
.addMessage('en', 'vatid', 'Vatid is invalid.');
});
</script>
You can also check the following question that can provide adicional information: Parsley.js Trigger Error on AJAX

Categories

Resources