jQuery form validation check ending up in a loop - javascript

I'm very new if it comes to jQuery. I'm trying to make a good client-side validation for my form. (At the moment only checking if X field is not empty)
But when I submit the form I end up in a forever loop.
I can explain the problem, and I understand the 'why'. But I have no idea how to fix it.
The problem occurs because:
Everytime I submit the form, he runs the validation check again, then submits when there aren't any errors, but because I submit, he checks again-- and so on.
With this code I monitor if the form is getting submitted. (And if so, let the validation begin)
// Form validation on submitting the form
$('form').on('submit', function() {
var id = $(this).attr('id');
console.log('Form is submitted');
submitFormValidation(id);
});
With this code I'm trying to validate every input field.
function submitFormValidation(id) {
event.preventDefault();
var goodCount = 0;
var goodCountMinimum = $('#' + id + ' .c-contact-form-item-input').length;
$('#' + id + ' .c-contact-form-item-input').each(function () {
if ($(this).val().length == 0) {
$(this).parent().find('span').css('background-color', 'red');
$(this).parent().find('span').css('width', 'calc(100% - 30px');
$(this).parent().find('i').css('background-color', 'red');
$(this).parent().find('i').css('animation', 'none');
$(this).parent().find('i').css('opacity', '1');
}
else {
$(this).parent().find('span').css('background-color', 'green');
$(this).parent().find('span').css('width', 'calc(100% - 30px');
$(this).parent().find('i').css('background-color', 'green');
$(this).parent().find('i').css('animation', 'none');
$(this).parent().find('i').css('opacity', '1');
goodCount = goodCount + 1;
return goodCount;
}
});
if (goodCount == goodCountMinimum) {
$('#' + id).submit();
}
}
I hope someone can help me out on how to fix the never ending loop.
Thanks!

Try changing...
$('#' + id).submit();
to...
$('#' + id)[0].submit();
The difference between these two is that the first triggers a submit on the jQuery object, where the second triggers a sumbit on the raw Element. Triggering a submit on the Element, and not the jQuery object, should result in the jQuery submit event handler being skipped.
Example...
$('form').on('submit', function(e){
console.log('submitted!');
e.preventDefault();
setTimeout(function(){
e.target.submit();
}, 5000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="http://www.google.com/">
<button>Go!</button>
</form>

Change
if (goodCount == goodCountMinimum) {
$('#' + id).submit();
}
To
if (goodCount == goodCountMinimum) {
return;
} else {
e.preventDefault();//pass in the event object to the function
}
For this solution to work, change your function to take two parameters:
function submitFormValidation(id, e) {}
And invoke it like this:
$('form').on('submit', function(e) {
var id = $(this).attr('id');
console.log('Form is submitted');
submitFormValidation(id, e);
});
If you submit the form (using jQuery's submit()), the jQuery submit event handler will continuously be called. Just returning will allow the default action of the form to be taken (which is submitting).

Related

Contact form 7 add disabled attr to button to prevent double submission

I have a WordPress site and there is Contact form 7 plugin and I want to add attr to submit button to disable double submission.
Now I have this code to prevent double submission
$(document).on('click', '.wpcf7-submit', function(e){
if( $('.ajax-loader').hasClass('is-active') ) {
e.preventDefault();
return false;
}
});
but I want to add attr disabled while form sending or getting error response for better user experience
Improving on Matt's answer -
$('.wpcf7-form').on('submit', function() {
$(this).find('.wpcf7-submit').attr('disabled', true);
});
This would disable the submit button when clicked on it. Now to get that activated again after success or failure you would need to remove the attribute after the submission is complete(whether success or failure). Since the plugin developer is a bit whimsical about how the events work, I am writing this solution for first quarter of 2019 -
$('.wpcf7').on('wpcf7submit', function (e) {
$(this).find('.wpcf7-submit').removeAttr('disabled');
});
where '.wpcf7' is the parent container of the form, '.wpcf7-form' is the form itself. The 'wpcf7submit' is event listener that the DOM listens to, after the form gets submitted(irrespective of the fact that is valid or invalid).
This will disable the button and submit the form. You need to re-call submit after disabling the button.
jQuery( '.wpcf7-submit' ).click(function() {
jQuery( this ).attr( 'disabled', true );
jQuery( this ).submit();
});
This will re-enable the button if there's an error with the submission.
document.addEventListener( 'wpcf7invalid', function() {
jQuery( '.wpcf7-submit' ).attr( 'disabled', false );
}, false );
$(document).on('click', '.wpcf7-submit', function(e){
$(this).prop('disabled',true);
});
I implemented this script to help prevent multiple submissions. The biggest difference from the others is that it works with multiple CF7 forms on each page. Basically, it disables the form and the submit button on submit (since a form can also be submitted with an Enter-press), adds a new label "Please Wait.." to the submit button, and re-enables them if there are input errors. Also, not dependent on jQuery (Vanilla JS).
(function () {
var elems = document.querySelectorAll('.wpcf7');
if (!elems.length) {
return false;
}
var forms = document.querySelectorAll('.wpcf7-form');
if (!forms.length) {
return false;
}
function _evtFormSubmit() {
this.disabled = true;
var submitBtn = this.querySelector('button[type="submit"]');
submitBtn.disabled = true;
submitBtn.setAttribute('data-default-text', submitBtn.innerText);
submitBtn.innerHTML = '<span>Please wait...</span>';
}
function _evtInvalid(e) {
var thisForm = document.querySelector('#' + e.detail.id + ' form');
thisForm.disabled = false;
var submitBtn = thisForm.querySelector('button[type="submit"]');
setTimeout(function() {
submitBtn.disabled = false;
submitBtn.innerHTML = '<span>' + submitBtn.getAttribute('data-default-text') + '</span>';
}, 600); // give it a bit of time in case it is a fast submit
}
for(var i = forms.length-1; i >= 0; i--) {
forms[i].addEventListener('submit', _evtFormSubmit, false);
}
for(i = elems.length-1; i >= 0; i--) {
elems[i].addEventListener('wpcf7invalid', _evtInvalid, false);
}
})();
Note: if you have more than one submit button (why?), this only affects the first button in the form.
For future people who are looking for a solution here. Simple SCSS/CSS option without Javascript need. For me is work pefect. It always works reliably for me. (2022)
.wpcf7-form {
&.submitting {
.wpcf7-submit {
pointer-events: none;
}
}
}

Customizing a password strength validator plugin

I am using a plugin called pStrength.jquery.js and for some reason its not submitting the form I have, or it is submitting the form even if it is not supposed to (when I changed the code)
The code i am using is:
$(document).ready(function () {
$('#myForm').submit(function () {
return false;
});
$('#myElement1, #myElement2').pStrength({
'changeBackground': false,
'onPasswordStrengthChanged': function (passwordStrength, strengthPercentage) {
if ($(this).val()) {
$.fn.pStrength('changeBackground', this, passwordStrength);
} else {
$.fn.pStrength('resetStyle', this);
}
$('#' + $(this).data('display')).html('Your password strength is ' + strengthPercentage + '%');
},
'onValidatePassword': function (strengthPercentage) {
$('#' + $(this).data('display')).html(
$('#' + $(this).data('display')).html() + ' Great, now you can continue to change your password!');
$('#myForm').submit(function () {
return true;
});
}
});
});
Someone has told me that I should use booleans and inside the validation checks, set it to true or false.
The problem is that i have no idea how to do this
Is there anyone that could help me and show me the code to do this?
Thank you in advance
The reason it was still submitting was because the onValidatePassword function runs on each individual field, whereas you actually had two fields to validate. If one field validates and the other doesn't, the form would still submit because the Boolean had already been set to true, which was the only condition needed to submit.
Updated code below, you can also refer to the fiddle.
$(document).ready(function () {
$('#myForm').submit(function (event) {
// TODO: check that the two field values match as well
if ($('#myElement1').data('valid') === 'yup' &&
$('#myElement2').data('valid') === 'yup') {
// remove these three lines to make it submit
alert('Submitting...');
event.preventDefault();
return false;
// and uncomment this one line
//return true;
} else {
event.preventDefault();
return false;
}
});
$('#myElement1, #myElement2').data('valid', 'nope');
...
Your complete onValidatePassword callback should now look like this:
'onValidatePassword': function (strengthPercentage) {
$('#' + $(this).data('display')).html(
$('#' + $(this).data('display')).html() + ' Great, now you can continue to change your password!');
formValid = strengthPercentage >= 60;
// set for each element
if (strengthPercentage >= 60) {
$(this).data('valid', 'yup');
} else {
$(this).data('valid', 'nope');
}
}
Inside your onValidatePassword, you're binding to the submit event, instead of submitting the form. Replace this code:
$('#myForm').submit(function () {
return true;
});
with
$('#myForm').submit();

form is not doing submit after calling function return false only one time

I am trying to control form submitting after validating user input
the user must select at least one radio otherwise the form wouldn't submit
the first part is working very fine, if the user haven't select any radio input I call
$('form').submit(function () { return false });
else if he selected something I will call
$('form').submit();
but it is not submitting
function validateSelection() {
var temp = false;
$('.lang-radio > input[type=radio]').each(function () {
if ($(this).is(':checked')) {
temp |= $(this).is(':checked')
};
});
if (temp != 1) {
$('form').submit(function () { return false });
$('.high-light').effect("shake");
}
else {
$('form').submit();
}
}
I am calling the function validateSelection from OnClientClick="validateSelection();"
I am using asp.net webforms
When you do
$('form').submit(function () { return false });
you are attaching an event handler to the submit event. Thus, if this line executes first, then every time you do $('form').submit();, the event handler will be triggered and return false and not submit.
If the .Net control is a submit button, you can simply replace the first line with return false (Edit: and change it to OnClientClick="return validateSelection();"), otherwise you can remove it completely.
1) Remove OnClientClick="validateSelection();" from your form
2) Give class="validateForm" to your form
3) put following js code in you are js
$(document).ready(function(){
$('.validateForm').on('submit',function(){
var ckradio = $(this).find('[type=radio]:checked');
if(ckradio.length == 0){
return false;
}else{
return true;
}
});
});

Re-enabling Submit after prevent default

I am trying to unbind or reenable the prevent default so my form will submit on good data.
I have tried multiple examples. Here is my code and some of the examples i tried.
This code works great for what i want to. Just the last thing and resetting the div which i can implement after i get this.
function lengthRestriction(elem, min, max) {
var uInput = elem.value;
if (uInput.length >= min && uInput.length <= max) {
return true;
} else {
var cnt = document.getElementById('field');
cnt.innerHTML = "Please enter between " + min + " and " + max + " characters";
elem.focus();
$('#ShoutTweet').submit(function(e) {
e.preventDefault();
//bind('#ShoutTweet').submit();
//$('#ShoutTweet').trigger('submit');
});
}
}​
i have a jsbin set up too http://jsbin.com/ebedab/93
Don't try to set up and cancel a submit handler from within your validation function, do it the other way around: call the validation from within a single submit handler, and only call .preventDefault() if the validation fails:
$(document).ready(function() {
$('#ShoutTweet').submit(function(e) {
if (/* do validations here, and if any of them fail... */) {
e.preventDefault();
}
});
});
If all of your validations pass just don't call e.preventDefault() and the submit event will then happen by default.
Alternatively you can return false from your submit handler to prevent the default:
$('#ShoutTweet').submit(function(e) {
if (!someValidation())
return false;
if (!secondValidation())
return false;
if (someTestVariable != "somevalue")
return false;
// etc.
});
I'm not completely sure what you are asking, but if your goal is to destroy your custom submit handler, then use this:
$("#ShoutTweet").unbind("submit");
This assumes that you have a normal (not Ajax) form.
Just call submit on the form
$('#ShoutTweet').submit();
This works surely and enable form submission after event.preventDefault();
$('#your-login-form-id').on('submit', onSubmitLoader);
function onSubmitLoader(e) {
e.preventDefault();
var self = $(this);
setTimeout(function () {
self.unbind('submit').submit(); // like if wants to enable form after 1s
}, 1000)
}

Onsubmit validate change background requried fields?

Anyone know of a good tutorial/method of using Javascript to, onSubmit, change the background color of all empty fields with class="required" ?
Something like this should do the trick, but it's difficult to know exactly what you're looking for without you posting more details:
document.getElementById("myForm").onsubmit = function() {
var fields = this.getElementsByClassName("required"),
sendForm = true;
for(var i = 0; i < fields.length; i++) {
if(!fields[i].value) {
fields[i].style.backgroundColor = "#ff0000";
sendForm = false;
}
else {
//Else block added due to comments about returning colour to normal
fields[i].style.backgroundColor = "#fff";
}
}
if(!sendForm) {
return false;
}
}
This attaches a listener to the onsubmit event of the form with id "myForm". It then gets all elements within that form with a class of "required" (note that getElementsByClassName is not supported in older versions of IE, so you may want to look into alternatives there), loops through that collection, checks the value of each, and changes the background colour if it finds any empty ones. If there are any empty ones, it prevents the form from being submitted.
Here's a working example.
Perhaps something like this:
$(document).ready(function () {
$('form').submit(function () {
$('input, textarea, select', this).foreach(function () {
if ($(this).val() == '') {
$(this).addClass('required');
}
});
});
});
I quickly became a fan of jQuery. The documentation is amazing.
http://docs.jquery.com/Downloading_jQuery
if You decide to give the library a try, then here is your code:
//on DOM ready event
$(document).ready(
// register a 'submit' event for your form
$("#formId").submit(function(event){
// clear the required fields if this is the second time the user is submitting the form
$('.required', this).removeClass("required");
// snag every field of type 'input'.
// filter them, keeping inputs with a '' value
// add the class 'required' to the blank inputs.
$('input', this).filter( function( index ){
var keepMe = false;
if(this.val() == ''){
keepMe = true;
}
return keepMe;
}).addClass("required");
if($(".required", this).length > 0){
event.preventDefault();
}
});
);

Categories