I'm doing some jQuery form validation and I came up with an issue. I have the following code so far:
// catch any form submission
$('form').submit(function () {
'use strict';
// if the browser doesn't support HTML5's required attribute
if (!Modernizr.input.required) {
// catch any field that should be required
$(this).find('input[required]').each(function () {
// if is empty
if ($(this).val() === '') {
// create a span that contains a warning to the user
var requiredFieldWarning = document.createElement('span');
requiredFieldWarning.text = 'This field is required.';
// display the span next to the current field
}
});
}
});
I'm trying to "attach" or display a span next to any input of the submitted form that doesn't validate, but I don't know how to. I want to do this unobtrusively, that's why I create the said span inside JavaScript.
Also, how can I prevent the form from being submitted if any of the fields of the submitted form doesn't validate?
why reinvent the wheel? you should use the jquery form validation plugin..
edit: added code to prevent submition of invalid form.
to answer your question:
$('form').submit(function (e) {
'use strict';
var valid = true;
var $form = $(this);
$form.find("span.error").remove();
// if the browser doesn't support HTML5's required attribute
if (!Modernizr.input.required) {
// catch any field that should be required
$form.find(':input[required]').each(function () {
// if is empty
var $this = $(this);
if ($.trim($this.val()) === '') {
// create a span that contains a warning to the user
$this.after("<span class='error'>This field is required.</span>");
valid = false;
}
});
}
if(!valid){
e.preventDefault();
}
});
here is a shorter version:
$('form').submit(function (e) {
'use strict';
Modernizr.input.required ? e[$(this).find("span.error").remove().end()
.find(':input[required][value=""]')
.after("<span class='error'>This field is required.</span>")
.length ? 'preventDefault': 'isDefaultPrevented']() : null;
});
I am adding a span tag after the input. Before the form is revalidated it removes these spans and recreates only if needed. If any of these spans are added the form isn't submitted.
$('form').submit(function (event) {
'use strict';
$('.invalid-error', $(this)).remove();
// remove any old spans
var submit_form = true;
// form submits by default
// if the browser doesn't support HTML5's required attribute
if (!Modernizr.input.required) {
// catch any field that should be required
$(this).find('input[required]').each(function () {
// if is empty
if ($(this).val() === '') {
$(this).after('<span="invalid-error">This field is required.</span>');
// add span after input
submit_form = false;
}
});
}
if(!submit_form) event.preventDefault();
// stop form from submitting
});
jsFiddle ( http://jsfiddle.net/4KxzB/10/ )
Here is my working example, works as expected in chrome.
To stop the form from submitting, just return false;
<form>
<input type="text" required/>
<input type="submit" value="submit"/>
</form>
<script>
$('form').submit(function ()
{
'use strict';
// if the browser doesn't support HTML5's required attribute
if (!Modernizr.input.required)
{
var validInput = true;
// catch any field that should be required
$(this).find('input[required]').each(function ()
{
// if is empty
if ($(this).val() === '')
{
// create a span that contains a warning to the user
var requiredFieldWarning = document.createElement('span');
requiredFieldWarning.text = 'This field is required.';
// Cancels form submit
validInput = false;
}
});
return validInput;
}
});
</script>
var flag = 0;
if ($(this).val() === '') {
flag = 1;
var warningblock = '<span class="warning">This field is required.</span>';
$(this).after(warningblock);
}
//end of each loop
if(flag){ //put this block out side the loop
return false; //form wont submit
}
return true;
CSS
.warning{
/**add styles for warning here***/
}
Related
I have a form with one input field for the emailaddress. Now I want to add a class to the <form> when the input has value, but I can't figure out how to do that.
I'm using this code to add a class to the label when the input has value, but I can't make it work for the also:
function checkForInputFooter(element) {
const $label = $(element).siblings('.raven-field-label');
if ($(element).val().length > 0) {
$label.addClass('input-has-value');
} else {
$label.removeClass('input-has-value');
}
}
// The lines below are executed on page load
$('input.raven-field').each(function() {
checkForInputFooter(this);
});
// The lines below (inside) are executed on change & keyup
$('input.raven-field').on('change keyup', function() {
checkForInputFooter(this);
});
Pen: https://codepen.io/mdia/pen/gOrOWMN
This is the solution using jQuery:
function checkForInputFooter(element) {
// element is passed to the function ^
const $label = $(element).siblings('.raven-field-label');
var $element = $(element);
if ($element.val().length > 0) {
$label.addClass('input-has-value');
$element.closest('form').addClass('input-has-value');
} else {
$label.removeClass('input-has-value');
$element.closest('form').removeClass('input-has-value');
}
}
// The lines below are executed on page load
$('input.raven-field').each(function() {
checkForInputFooter(this);
});
// The lines below (inside) are executed on change & keyup
$('input.raven-field').on('change keyup', function() {
checkForInputFooter(this);
});
I've updated your pen here.
Here it is, using javascript vanilla. I selected the label tag ad form tag and added/removed the class accoring to the element value, but first you should add id="myForm" to your form html tag. Good luck.
function checkForInputFooter(element) {
// element is passed to the function ^
let label = element.parentNode.querySelector('.raven-field-label');
let myForm = document.getElementById("myform");
let inputValue = element.value;
if(inputValue != "" && inputValue != null){
label.classList.add('input-has-value');
myForm.classList.add('input-has-value');
}
else{
label.classList.remove('input-has-value');
myForm.classList.remove('input-has-value');
}
}
You can listen to the 'input' event of the input element and use .closest(<selector>) to add or remove the class
$('input').on('input', function () {
if (!this.value) {
$(this).closest('form').removeClass('has-value');
} else {
$(this).closest('form').addClass('has-value');
}
})
Edit: https://codepen.io/KlumperN/pen/xxVxdzy
I have a form where I'm using twitter typehead & the problem is whenever twitter typehead loads it creates another input field that is blank ¬ shown to user
Now i have this function to validate all inputs
var fields = $('#second_step input[type=text]');
var error = 0;
if (!$("input[name='career']:checked").val()) {
alert('Please Select yes or no'); return false;
}
fields.each(function(){
var value = $(this).val();
if( value.length<1 || value==field_values[$(this).attr('id')]) {
$(this).addClass('error');
$(this).effect("shake", { times:3 }, 50);
error++;
} else {
$(this).addClass('valid');
}
});
if (!$('#reg').valid()) {
return false;
}
Now due to that typehead input whic has no name or id it just have a certain class tt-hint & this input is read only how can i just skip this input from my above validation?
You can use jQuery's NOT function.
var fields = $('#second_step input[type=text]').not('.tt-hint');
You can filter out the fields with:
var fields = $('#second_step input[type=text]:not(.tt-hint)');
Your input has typeahead applied by using a class selector .typeahead.
So in your case you could use the :not pseudo-class selector to filter them out:
var fields = $('#second_step input[type=text]:not(.typeahead)');
That way you skip the typeahead fields.
Personally I would ignore disabled fields, since the user cannot correct them if there is an error. You say the input is read only so that would seem to correlate.
$('#second_step input[type=text]').filter(function(){ return !this.disabled; })
Try this :
fields.each(function(){
var value = $(this).val();
if($(this).hasClass('tt-hint') {
$(this).addClass('valid');
} else {
if( value.length<1 || value==field_values[$(this).attr('id')]) {
$(this).addClass('error');
$(this).effect("shake", { times:3 }, 50);
error++;
} else {
$(this).addClass('valid');
}
}
});
if (!$('#reg').valid()) {
return false;
}
I have a simple form with some form fields. Some of them are required some are not. The required field are required by adding the class 'required'.
When I submit I check the #contact-form fields and on the basis of there I give the empty field error classes and submit the form yes or no.
Adding the error classes to the fields is not a problem, but checking the "error" variable is. Because I don't know where I can check the error variable.
This is my jQuery code:
$('#contact-form').submit(function (event) {
var errors = false;
$(this).find('.required').each(function () {
if ($(this).val().length < 1) {
$(this).addClass('error');
errors = true;
}
});
if (errors == true) {
event.preventDefault();
}
});
JsFiddle
The following code should do what you want, just give your contact form submit button the id of #contact-form-button.
$('#contact-form-button').click(function(e) { // using click function
// on contact form submit button
e.preventDefault(); // stop form from submitting right away
var error = false;
$(this).find('.required').each(function () {
if ($(this).val().length < 1) {
$(this).addClass('error');
error = true;
}
});
if (!error) { // if not any errors
$('#contact-form').submit(); // you submit form
}
});
$('#contact-form').submit(function (event) {
var errors = false;
$(this).find('.required').each(function () {
if ($(this).val().length < 1) {
$(this).addClass('error');
errors = true;
}
});
if (errors == true) {
event.preventDefault();
return false;
}
return true;
})
if validation cross successfully then it return true for submit the form
I found out that my code just works. The reason I thought it was not working, is because I was still using PHP handling my real website where I made 1 field required and in my jQuery not. This made the confusion.
So the following code works:
$('#contact-form').submit(function (event) {
var errors = false;
$(this).find('.required').each(function () {
if ($(this).val().length < 1) {
$(this).addClass('error');
errors = true;
}
});
if (errors == true) {
event.preventDefault();
}
});
I use jquery.hint.js. On page load everiting is fine but when i use back browser button the focus does not hide the hint.
jQuery.fn.hint = function (blurClass) {
if (!blurClass) {
blurClass = 'blur';
}
return this.each(function () {
// get jQuery version of 'this'
var $input = jQuery(this),
// capture the rest of the variable to allow for reuse
title = $input.attr('title'),
$form = jQuery(this.form),
$win = jQuery(window);
function remove() {
if ($input.val() === title && $input.hasClass(blurClass)) {
$input.val('').removeClass(blurClass);
}
}
// only apply logic if the element has the attribute
if (title) {
// on blur, set value to title attr if text is blank
$input.blur(function () {
if (this.value === '') {
$input.val(title).addClass(blurClass);
}
}).focus(remove).blur(); // now change all inputs to title
// clear the pre-defined text when form is submitted
$form.submit(remove);
$win.unload(remove); // handles Firefox's autocomplete
}
});
};
example on normal page load: http://prntscr.com/sik0d
example after using back browser button: http://prntscr.com/sikap (doses not hide the hint on focus, it just add text to input field)
how to fix this. How to force this script to reload on back button? thanks
I finally find jquery.hint.js witch includes a fix for using the browser back button. So here is a link: https://gist.github.com/madmanlear/1723896
JavaScript:
(function ($) {
$.fn.hint = function (blurClass) {
if (!blurClass) blurClass = 'blur';
return this.each(function () {
var $input = $(this),
title = $input.attr('placeholder'),
$form = $(this.form),
$win = $(window);
function remove() {
if ($input.val() === title) {
$input.val('').removeClass(blurClass);
}
}
// only apply logic if the element has the attribute
if (title) {
// on blur, set value to title attr if text is blank
$input.blur(function () {
if (this.value === '' || this.value == title) {
$input.val(title).addClass(blurClass);
}
}).focus(remove).blur(); // now change all inputs to title
// clear the pre-defined text when form is submitted
$form.submit(remove);
$win.unload(remove); // handles Firefox's autocomplete
}
});
};
})(jQuery);
This is part of my jquery function that validades a form i have on my website:
/*
validates errors on all the fieldsets
records if the Form has errors in $('#formElem').data()
*/
function validateSteps(){
var FormErrors = false;
for(var i = 1; i < fieldsetCount; ++i){
var error = validateStep(i);
if(error == -1)
FormErrors = true;
}
$('#formElem').data('errors',FormErrors);
}
/*
validates one fieldset
and returns -1 if errors found, or 1 if not
*/
function validateStep(step){
if(step == fieldsetCount) return;
var error = 1;
var hasError = false;
$('#formElem').children(':nth-child('+ parseInt(step) +')').find(':input:not(button)').each(function(){
var $this = $(this);
var valueLength = jQuery.trim($this.val()).length;
if(valueLength == ''){
hasError = true;
$this.css('background-color','#FFEDEF');
}
else
$this.css('background-color','#A8FC9C'); /* Campo preenchido */
});
var $link = $('#navigation_form li:nth-child(' + parseInt(step) + ') a');
$link.parent().find('.error,.checked').remove();
var valclass = 'checked';
if(hasError){
error = -1;
valclass = 'error';
}
$('<span class="'+valclass+'"></span>').insertAfter($link);
return error;
}
/*
if there are errors don't allow the user to submit
*/
$('#enviar_candidatura').bind('click',function(){
var preenchimentoForm=true;
if($('#formElem').data('errors')){
preenchimentoForm=false;
dadosFormularios(preenchimentoForm);
//return false;
}
else{
dadosFormularios(preenchimentoForm);
}
});
});
However, i'm using too LiveValidation (http://livevalidation.com/) to validade fields client-side. Obiously, if the part validated by jquery is Ok, doesn't matter if there's errors on the LiveValidation part because the form is submitted.
So, what i want is to add an if clause or something like that inside this jquery code to verify if there are LV_invalid_fields. If 'yes' then block form from submitting like it's done with the jquery validation part, but i don't know how to do it neither where is the right place in the code above to put this verification. I would appreciate some help. Thanks!
//... live validation codes here
$("#myform").submit( function (event) ) {
event.preventDefault();
if ($(".LV_invalid").length > 0) {
//do not submit
}
else {
//do form submission here
}
}
First, you have to change the binding on the click to a binding on the submit action on the form.
And your function must return false on the submit action to stop the submitting action.
So, change your code like this :
$('#formElem').submit( function (event) ) {
var preenchimentoForm = true;
if ($('#formElem').data('errors')){
preenchimentoForm = false;
}
return preenchimentoForm;
}
You can read some explications about unobtrusive javascript here.
There is an option in the LiveValidation library which is not explained in the documentation http://livevalidation.com/documentation
To prevent LiveValidation's submission while still keeping its validation events, you may use the "afterValidation" option.
Example:
var prevent = function (e) {
e.preventDefault();
};
var yourValidation = new LiveValidation(
"inputID", {
//Your other options
afterValidation: prevent
}
);
yourValidation.add( Validate.Presence, { your options } );