Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Kristian Woods
23,414 PointsWhy does my form validate when I fill in the very last input, even if all the others are empty?
I have a contact form I'm trying to validate. I know you can just use the default 'required' attribute, however, I need to make the validation error messages custom. So, I have created this JS Class - When you initialise the class, you pass in the parameters e.g. the form you are targeting, the inputs within the form, and the submit button.
Here is a link to my codepen: https://codepen.io/Woodenchops/pen/oKxRGq?editors=1010
var contactForm = new FormValidate({
form: "#margeauxForm",
input: ".field.required",
submit: ".cta-2"
});
There is quite a bit going on in this class. However, I'm trying to make it so that if any required fields are empty, the submit button will disable. I've used a jQuery each loop to loop through each input to check the value length. It KINDA works - you can start off with the first input, enter a value and work your way down to the last input - the submit button will stay disabled until you enter the last field. HOWEVER, if you simply go to the last input and enter a value, it will reactive the submit button - even if every other input is empty
- starts at line 16 and ends at line 44
this._input = this._form.querySelectorAll(props.input);
this.checkFieldValue = function() {
jQuery(this._input).each(function() {
console.log(jQuery(this).val().length);
if(jQuery(this).val().length <= 0) {
$('.fake-click').show();
var submitHeight = jQuery(submitButton).innerHeight();
var submitWidth = jQuery(submitButton).innerWidth();
var submitInputTop = jQuery(submitButton).position().top;
var submitInputLeft = jQuery(submitButton).position().left;
$('.fake-click').css({
"background": "none",
"width": submitWidth + 5,
"height": submitHeight + 5,
"position": "absolute",
"top": submitInputTop,
"left": submitInputLeft,
"z-index": "1"
});
$(submitButton).css({
"opacity": .5
});
} else {
$('.fake-click').hide();
$(submitButton).css({
"opacity": 1
});
}
});
}
I'm then calling that function on a 'keyup' event on the inputs
- starts at line 218 and ends at line 242
jQuery(this._input).on('keyup', function(e) {
var input = e.target;
this.checkFieldValue(); // check if fields are empty
jQuery(this._input).each(function() {
var self = this;
if(input.value.length > 0) {
jQuery(input).next('.input-wrapper').find('.form-error-message').removeClass('error');
} else {
jQuery(input).next('.input-wrapper').find('.form-error-message').addClass('error');
}
});
this.setMessageOffset();
}.bind(this._self));
1 Answer
Steven Parker
243,214 PointsThe "each" code is setting the opacity of the submit button for every input, so only the last one matters.
What you probably want is to accumulate the results of the individual tests in a global counter or boolean, and then set the button state after the "each" finishes. Then you could react only when every test passes, not just the last one.
Michael Cook
Full Stack JavaScript Techdegree Graduate 28,975 PointsMichael Cook
Full Stack JavaScript Techdegree Graduate 28,975 Points"I know you can just use the default 'required' attribute, however, I need to make the validation error messages custom."
You can accomplish this with Bootstrap. I recommend reading the documentation on forms and form validation at getbootstrap.com. You are writing an awful lot of custom code to do something that already exists out there in a popular library. If you want to do it for practice, fair enough; but if you are actually trying to accomplish something, you ought to use tried and true reusable code.