JQuery RangeError On form submit - javascript

I have a form I am implementing some custom validation on. This is the block of JavaScript that handles the final check before the form is submitted:
$('.enquiry-form-container form').submit(function (e) {
e.preventDefault();
var invalid = false;
var isblank = false;
//Loop through each input and check if valid or empty
$('.validate').each(function () {
if ($(this).hasClass('invalid')) {
isInValid($(this));
invalid = true;
} else {
//Any fields are blank
if ($(this).val() === "") {
$(this).addClass('blank');
isblank = true;
} else {
$(this).addClass('valid');
isValid($(this));
$(this).removeClass('blank empty');
}
}
});
if (!invalid & !isblank){ //SEND
$(this).find(":submit").prop("disabled", true); //Prevent submit to prevent duplicate submissions
$(this).submit();
} else { //DONT SEND
}
});
Each time I fill out the form and attempt to submit I get the following error in the console:
Uncaught RangeError: Maximum call stack size exceeded(…)
I understand that this can happen for a number of reasons, usually an infinite loop. Can anyone see where I am going wrong in the above code? Is the .submit() function calling the submit() method again... If so how can I resolve this and send form if it validates?
Just for full clarity, here is my isInValid() and isValid() functions.. They are used to add or remove the appropriate classes so I can style the inputs differently depending on the input.
//VALID INPUT
function isValid(input) {
input.addClass('valid');
input.removeClass('invalid empty blank');
input.parent().parent().next('.hint').css('visibility', 'hidden');
}
//INVALID INPUT
function isInValid(input) {
input.addClass('invalid');
input.removeClass('valid empty blank');
input.parent().parent().next('.hint').css('visibility', 'visible');
}

Generally, you just need to worry about cancelling an event in the if/then branches of your validation logic that indicate a problem. If you don't hit those branches, the form submits as it normally would. This removes the need for you to manually indicate that you want the form submitted.
See comments inline below for details:
$('.enquiry-form-container form').submit(function (e) {
var invalid = false;
var isblank = false;
// Loop through each input and check if valid or empty
$('.validate').each(function () {
if ($(this).hasClass('invalid')) {
isInValid($(this));
invalid = true;
e.preventDefault();
return;
} else {
// Any fields are blank
if ($(this).val() === "") {
$(this).addClass('blank');
isblank = true;
e.preventDefault();
return;
} else {
$(this).addClass('valid');
isValid($(this));
$(this).removeClass('blank empty');
}
}
});
// If we've gotten this far, the form is good and will be submitted.
// No need for an if/then/else here because you've already trapped
// the conditions that would prevent the form from being submitted
// above.
// Prevent submit to prevent duplicate submissions
$(this).find(":submit").prop("disabled", true);
});
It's also a good idea to separate your validation code into its own function, so a reworked example would be:
$('.enquiry-form-container form').submit(function (e) {
// You only need to worry about cancelling the form's submission
// if the form is invalid:
if (!validate()) {
e.preventDefault();
return;
}
// If it is valid, you don't need to interfere in that process, but
// you can certainly do other "valid" operations:
// Prevent submit from being clicked to prevent duplicate submissions
$(this).find(":submit").prop("disabled", true);
});
function validate() {
// This function doesn't worry about cancelling the form's submission.
// Its only job is to check the elements, style them according to
// their validity (and, in a perfect world, the styling would be off-
// loaded to anther function as well) and return whether the form is
// valid or not.
var invalid = false;
var isblank = false;
// Loop through each input and check if valid or empty
$('.validate').each(function () {
if ($(this).hasClass('invalid')) {
isInValid($(this));
invalid = true;
} else {
// Any fields are blank
if ($(this).val() === "") {
$(this).addClass('blank');
isblank = true;
} else {
$(this).addClass('valid');
isValid($(this));
$(this).removeClass('blank empty');
}
}
});
// If invalid or isblank is true, there was a problem and false
// should be returned from the function
return !invalid || !isblank;
}

I think the main problem for you is calling submit() from inside the handle of the submit. the better way to do this is cancel the request just when you see that there is invalid data.
$('.enquiry-form-container form').submit(function (e) {
e.preventDefault();
var invalid = false;
var isblank = false;
//Loop through each input and check if valid or empty
$('.validate').each(function () {
if ($(this).hasClass('invalid')) {
isInValid($(this));
invalid = true;
} else {
//Any fields are blank
if ($(this).val() === "") {
$(this).addClass('blank');
isblank = true;
} else {
$(this).addClass('valid');
isValid($(this));
$(this).removeClass('blank empty');
}
}
});
if (!invalid & !isblank){ //SEND
$(this).find(":submit").prop("disabled", true); //Prevent submit to prevent duplicate submissions
return true;
} else { //DONT SEND
return false;
}
});

I think the main problem for you is calling submit() from inside the handle of the submit. the better way to do this cancels the request just when you see that there is invalid data.
$('.enquiry-form-container form').submit(function (e) {
// remove the e.preventDefault();
var invalid = false;
var isblank = false;
//Loop through each input and check if valid or empty
$('.validate').each(function () {
if ($(this).hasClass('invalid')) {
isInValid($(this));
invalid = true;
} else {
//Any fields are blank
if ($(this).val() === "") {
$(this).addClass('blank');
isblank = true;
} else {
$(this).addClass('valid');
isValid($(this));
$(this).removeClass('blank empty');
}
}
});
if (!invalid & !isblank){ //SEND
$(this).find(":submit").prop("disabled", true); //Prevent submit to prevent duplicate submissions
//$(this).submit(); // this should be removed
} else { //DONT SEND
e.preventDefault();
}
});

Related

addEventListener - is there a more efficient way

I am adding JavaScript to alert users they need to fill out the specified fields. It's not the code that is wrong, but as I have two forms, and each field requires separate JavaScript, I was wondering if there was a more efficient way off writing the script? I know there is the required attribute you can write in the HTML, but I am not interested in that.
function prepareEventHandlers () {
document.getElementById("bookingFrm").addEventListener("submit", function(event) {
// Show message
if (document.getElementById("email").value == "Your Email") {
document.getElementById("errorMessage").innerHTML = "Please provide an email address!";
// to STOP the form from submitting
event.preventDefault(); // Prevent form from submitting // when using addEventListener, return false wont work, in all other cases use return false
} else {
// reset and allow the form to submit
document.getElementById("errorMessage").innerHTML = "";
return true;
}
});
}
function prepareEventHandlersName () {
document.getElementById("bookingFrm").addEventListener("submit", function(event) {
// Show message
if (document.getElementById("name").value == "Your Name") {
document.getElementById("errorMessage1").innerHTML = "Please provide a name!";
// to STOP the form from submitting
event.preventDefault(); // Prevent form from submitting
} else {
// reset and allow the form to submit
document.getElementById("errorMessage1").innerHTML = "";
return true;
}
});
}
function start() {
prepareEventHandlers();
prepareEventHandlersName();
}
window.onload = start;
Why not do both checks within the same function?
function prepareEventHandlersForBoth () {
document.getElementById("bookingFrm").addEventListener("submit", function(event) {
// Show message
if (document.getElementById("email").value == "Your Email") {
document.getElementById("errorMessage").innerHTML = "Please provide an email address!";
event.preventDefault();
} else {
document.getElementById("errorMessage").innerHTML = "";
return true;
}
if (document.getElementById("name").value == "Your Name") {
document.getElementById("errorMessage1").innerHTML = "Please provide a name!";
event.preventDefault();
} else {
document.getElementById("errorMessage1").innerHTML = "";
return true;
}
});
}
}
function start() {
prepareEventHandlersForBoth();
}
window.onload = start;

JQuery on form submit check required fields

I have these JQuery functions:
function CheckRequired() {
$(".required").each(function(event) {
var check = $(this).val();
if(check == '') {
event.preventDefault();
alert("One or more fields cannot be blank");
//alert($(this).attr("id"));
return false;
}
return true;
});
}
$(document).ready(function() {
$("form").each(function() {
$(this).submit(function(event) {
CheckRequired();
});
});
});
so my required fields have a class of required but when submitting a form, its showing the alert error but it still submits the form
how can i stop it submitting the form if there is an error
The result of CheckRequired() is not being returned from the submit handler.
return CheckRequired();
You might also pass the event into that function and in the case that you do not want the submit to happen, inside CheckRequired do
event.preventDefault();
I'll redo the code block...
function CheckRequired(event) {
var $form = $(this);
if ($form.find('.required').filter(function(){ return this.value === '' }).length > 0) {
event.preventDefault();
alert("One or more fields cannot be blank");
return false;
}
}
$(document).ready(function () {
$('form').on('submit', CheckRequired);
});
Try this:
$(document).ready(function() {
$("form").submit(function(event) {
if ( !CheckRequired() ){
event.preventDefault();
}
});
});
And I am smelling bug in the code. You are looping through each form, and for checking required you are doing a global find for .required
and here's the little refactor you can do to the CheckRequired function:
function CheckRequired() {
var field_with_empty_ip = $(".required").filter(function(){
return ( $(this).val() == "" );
});
return ( field_with_empty_ip.length < 0 );
}

Wait for the return of the loop on form submit

I have the code below, the form is needed to be validated before it can submit the form.
But the problem is, the form continues to submit without validating.
<form action='#' method='post' onsubmit='return validate();'>
function validate()
{
$('form').find(':input:not(:submit,:hidden), select, textarea').each(function(e)
{
$(this).removeClass('redBox');
var rq = $(this).attr('requiredz');
if(rq != undefined)
{
if($(this).val().trim() == '')
{
$(this).addClass('redBox');
$("#errorMsg").html('Red boxes cannont be left empty!');
return false;
}
}
});
});
How to handle the return of a loop?
Dont submit the form once encountered return false on the loop.
try this:
function validate()
{
var passes = true;
$('form').find(':input:not(:submit,:hidden), select, textarea').each(function(e)
{
$(this).removeClass('redBox');
var rq = $(this).attr('requiredz');
if(rq != undefined)
{
if($(this).val().trim() == '')
{
$(this).addClass('redBox');
$("#errorMsg").html('Red boxes cannont be left empty!');
passes = false;
}
}
});
return passes;
});
Do not use return.
$('#my-form').on('submit', function(event){
if (validate() === false) {
event.preventDefault(); // like return false;
}
});
For more information see jQuery submit docs.
Each function has it's own returned value, the default returned value is an undefined value. You should check the length of the invalid elements after the each loop and return a proper value, since you are using jQuery I'd suggest:
$('form').on('submit', function (event)
{
var $invalid = $(this)
.find(':input:not(:submit,:hidden), select, textarea')
.removeClass('redBox')
.addClass(function () {
return this.getAttribute('requiredz')
&& $.trim(this.value) === ''
? 'redBox'
: null;
}).filter('.redBox');
if ($invalid.length)
{
$("#errorMsg").html('Red boxes cannont be left empty!');
return false;
}
});

How to prevent submit but still validate required fields?

I have a form, and when is submitted I prevent it with e.preventDefault(), but I still want the browser to validate the required fields before I make the AJAX call.
I don't want to get fancy with javascript validation, I just want the browser to validate the required fields (HTML5).
How can I achieve this?
It works, even if you don't do the checkValidity check. In chrome, it won't call the submit function on the form if form is not valid:
$(document).ready(function(){
$("#calendar_form").submit(function(e){
e.preventDefault();
calendarDoAjax();
});
function calendarDoAjax(){
var proceed = false;
if( $("#calendar_form")[0].checkValidity ){
if ($("#calendar_form")[0].checkValidity()) {
proceed = true;
}
}else{
proceed = true;
}
if (proceed) {
//Do ajax call
}
}
});
Add this in the end of your submit function:
if (evt && evt.preventDefault) {
evt.preventDefault();
} else if (event) {
event.returnValue = false;
}
return false;
And pass the var evt in your function like this:
function(evt) { /* Your Code */ }

Jquery - continue with form submit after validation

I have this code:
kreiraj_korisnika.on('submit', function(){
if(error_count != false) {
kreiraj_korisnika.submit();
} else {
return false;
}
});
How can I continue with form submitting when error_count is true (without AJAX submit)?
You have to use preventDefault() method of event variable to avoid the submit. Try sopmething like:
kreiraj_korisnika.on('submit', function(e) {
if (error_count)
{
// avoid the submit...
e.preventDefault();
// show your erros messages
}
});
If error_countvariable is true, the submit will happen.
Is kreiraj_korisnika actually an jQuery object ?
If you just assigned it to a result of getElementById() it won't work.
In that case:
$(kreiraj_korisnika).on('submit', function(e){
var errorCount = 0;
if(errorCount == 0)
{
this.submit();
}
else
{
alert('Invalid form input !');
e.preventDefault();
}
});
Léon

Categories