Reputation: 1112
I read some apparently similar questions here on StackOverflow but actually for all of them browsing among the children wasn't really necessary and the objects could have been retrieved targeting directly the class name.
My situation is a bit different. What I'm writing is a JavaScript validator for the inputs and I can have several forms in the same page where the checks must be performed. On input
I set all the global vars, included the parent form object parent_form
. What I want to achieve is now re-enabling the submit button but only if in that form there aren't other inputs with the class input-err
(that I add to the input in the function that displays the error and I remove in the function that removes the error). To do that I need to search for the class input-err
not simply through $('.input-err')
, 'cause this would look for the class in the whole document, but among the children of the parent_form
.
I wrote this but it doesn't seem to work
if (parent_form.children('.' + ERR_INPUT).length < 1) {
children_submit_input.prop('disabled', false);
}
This one is the HTML form
<form action="" id="capote">
<div class="input-container">
<input type="email" id="email1" placeholder="Email (not required)" data-thoth-filter="email">
<input type="email" id="email2" placeholder="Email (required)" data-thoth-filter="email" required>
</div>
<div class="input-container">
<input type="email" id="normal1" placeholder="Normal field (not required)">
<input type="email" id="normal2" placeholder="Normal field (required)" required>
</div>
<div class="input-container">
<input type="text" id="cf1" placeholder="C.F. (not required)" data-thoth-filter="codice_fiscale">
<input type="text" id="cf2" placeholder="C.F. (required)" data-thoth-filter="codice_fiscale" required>
</div>
<input type="submit" id="capote-submit" value="Invia">
</form>
Upvotes: 0
Views: 3373
Reputation: 3435
you can do this:
$('form').each(function(){
var err-Input = $(this).find('.' + ERR_INPUT);
if(err-Input).lenght < 1){
//here add your codes
}
});
For each form we find all the children elements with ERR_INPUT
class name and check if we have such element(s) or not.
If you want do this on the input text change:
$('input[type=text]').on('keydown paste', function(){
var thisForm = $(this).parents('form');
var err-Input = thisForm.find('.' + ERR_INPUT);
if(err-Input).lenght < 1){
var submitButton = thisForm.find('input[type=submit]');
submitButton.prop('disabled', 'false'); // or submitButton.removeAttr('disabled');
}
});
Upvotes: 1
Reputation: 253308
One approach, using jQuery, is below:
// binding the anonymous function of the on() method as
// the event-handler for the 'input' event:
$('input').on('input', function() {
// caching the relevant ancestor HTMLFormElement, using the
// HTMLInputElement.form property (also available to
// HTMLTextAreaElement and HTMLSelectElement); and making
// it a jQuery Object:
let form = $(this.form);
// here we toggle the class of 'ERR_INPUT' according to
// the following switch (the class is applied if the
// switch is true/truthy, and removed if the switch is
// false/falsey):
$(this).toggleClass('ERR_INPUT',
// here we test to find if this (the HTMLInputElement)
// is both required AND it is NOT ('!') valid
// (from the HTMLInputElement.validity.valid property):
this.required && !this.validity.valid);
// here we find the <input> element(s) whose 'type' attribute
// is equal to 'submit', and we update its 'disabled' property:
form.find('input[type=submit]').prop('disabled',
// if we find any non-zero number of <input> elements which
// are required and are invalid, this returns Boolean true
// and sets the 'disabled' property to true, otherwise if
// there is a zero number of required <input> elements which
// are invalid, it returns false and so the 'disabled'
// property is false:
form.find('input[required]:invalid').length);
// here we trigger the 'input' event on all elements returned by
// the original selector, in order to apply the relevant class
// and disabled properties on page-load:
}).trigger('input');
// preventing submission of the form (for
// the purposes of the demo).
// Here we bind the anonymous function of the on() method as the
// event-handler for the 'submit', 'animationend' and 'animationEnd'
// events:
$('form').on('submit animationend animationEnd', function(e) {
// preventing submission of the form, for the purposes of avoiding
// problems in this demo:
e.preventDefault();
// here we toggle the 'successfulSubmission' class (used in order
// to demonstrate the working submit buttons when the criteria are
// met); we add the class if the Event.type property is equal to
// 'submit', and remove it if the event.type property is anything
// other (so necessarily either 'animationend' or 'animationEnd'):
$(this).toggleClass('successfulSubmission', e.type === 'submit');
});
$('input').on('input', function() {
let form = $(this.form);
$(this).toggleClass('ERR_INPUT', this.required && !this.validity.valid);
form.find('input[type=submit]').prop('disabled', form.find('input[required]:invalid').length);
}).trigger('input');
// preventing submission of the form (for
// the purposes of the demo):
$('form').on('submit animationend animationEnd', function(e) {
e.preventDefault();
$(this).toggleClass('successfulSubmission', e.type === 'submit');
});
@keyframes onsubmitAnimation {
from {
border-color: #f90;
}
to {
border-color: transparent;
}
}
form {
border: 2px solid transparent;
margin: 1em auto;
width: 90%;
}
form.successfulSubmission {
animation: onsubmitAnimation 1s linear 1;
}
.ERR_INPUT {
background-color: rgba(255, 0, 0, 0.3);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="#" id="capote">
<div class="input-container">
<input type="email" id="email1" placeholder="Email (not required)" data-thoth-filter="email" />
<input type="email" id="email2" placeholder="Email (required)" data-thoth-filter="email" required />
</div>
<div class="input-container">
<input type="email" id="normal1" placeholder="Normal field (not required)">
<input type="email" id="normal2" placeholder="Normal field (required)" required />
</div>
<div class="input-container">
<input type="text" id="cf1" placeholder="C.F. (not required)" data-thoth-filter="codice_fiscale">
<input type="text" id="cf2" placeholder="C.F. (required)" data-thoth-filter="codice_fiscale" required />
</div>
<input type="submit" id="capote-submit" value="Invia">
</form>
<form action="#" id="sinatra">
<div class="input-container">
<input type="email" id="email3" placeholder="Email (not required)" data-thoth-filter="email" />
<input type="email" id="email4" placeholder="Email (required)" data-thoth-filter="email" required />
</div>
<div class="input-container">
<input type="email" id="normal3" placeholder="Normal field (not required)">
<input type="email" id="normal4" placeholder="Normal field (required)" required />
</div>
<div class="input-container">
<input type="text" id="cf3" placeholder="C.F. (not required)" data-thoth-filter="codice_fiscale">
<input type="text" id="cf4" placeholder="C.F. (required)" data-thoth-filter="codice_fiscale" required />
</div>
<input type="submit" id="sinatra-submit" value="Invia">
</form>
<form action="#" id="capone">
<div class="input-container">
<input type="email" id="email5" placeholder="Email (not required)" data-thoth-filter="email" />
<input type="email" id="email6" placeholder="Email (required)" data-thoth-filter="email" required />
</div>
<div class="input-container">
<input type="email" id="normal5" placeholder="Normal field (not required)">
<input type="email" id="normal6" placeholder="Normal field (required)" required />
</div>
<div class="input-container">
<input type="text" id="cf5" placeholder="C.F. (not required)" data-thoth-filter="codice_fiscale">
<input type="text" id="cf6" placeholder="C.F. (required)" data-thoth-filter="codice_fiscale" required />
</div>
<input type="submit" id="capone-submit" value="Invia">
In the above I specifically search not for the elements with the .ERR_INPUT
class, but instead for the elements which are both required and invalid, using the selector:
form.find('input[required]:invalid').length
This is because of the simple, though perhaps wrong, assumption that the ERR_INPUT
class will be applied only to those elements which are both required and invalid.
If my assumption is wrong, though, the above line can of course be re-written instead as:
form.find('input.ERR_INPUT').length
$('input').on('input', function() {
let form = $(this.form);
$(this).toggleClass('ERR_INPUT', this.required && !this.validity.valid);
form.find('input[type=submit]').prop('disabled', form.find('input.ERR_INPUT').length);
}).trigger('input');
// preventing submission of the form (for
// the purposes of the demo):
$('form').on('submit animationend animationEnd', function(e) {
e.preventDefault();
$(this).toggleClass('successfulSubmission', e.type === 'submit');
});
@keyframes onsubmitAnimation {
from {
border-color: #f90;
}
to {
border-color: transparent;
}
}
form {
border: 2px solid transparent;
margin: 1em auto;
width: 90%;
}
form.successfulSubmission {
animation: onsubmitAnimation 1s linear 1;
}
.ERR_INPUT {
background-color: rgba(255, 0, 0, 0.3);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="#" id="capote">
<div class="input-container">
<input type="email" id="email1" placeholder="Email (not required)" data-thoth-filter="email" />
<input type="email" id="email2" placeholder="Email (required)" data-thoth-filter="email" required />
</div>
<div class="input-container">
<input type="email" id="normal1" placeholder="Normal field (not required)">
<input type="email" id="normal2" placeholder="Normal field (required)" required />
</div>
<div class="input-container">
<input type="text" id="cf1" placeholder="C.F. (not required)" data-thoth-filter="codice_fiscale">
<input type="text" id="cf2" placeholder="C.F. (required)" data-thoth-filter="codice_fiscale" required />
</div>
<input type="submit" id="capote-submit" value="Invia">
</form>
<form action="#" id="sinatra">
<div class="input-container">
<input type="email" id="email3" placeholder="Email (not required)" data-thoth-filter="email" />
<input type="email" id="email4" placeholder="Email (required)" data-thoth-filter="email" required />
</div>
<div class="input-container">
<input type="email" id="normal3" placeholder="Normal field (not required)">
<input type="email" id="normal4" placeholder="Normal field (required)" required />
</div>
<div class="input-container">
<input type="text" id="cf3" placeholder="C.F. (not required)" data-thoth-filter="codice_fiscale">
<input type="text" id="cf4" placeholder="C.F. (required)" data-thoth-filter="codice_fiscale" required />
</div>
<input type="submit" id="sinatra-submit" value="Invia">
</form>
<form action="#" id="capone">
<div class="input-container">
<input type="email" id="email5" placeholder="Email (not required)" data-thoth-filter="email" />
<input type="email" id="email6" placeholder="Email (required)" data-thoth-filter="email" required />
</div>
<div class="input-container">
<input type="email" id="normal5" placeholder="Normal field (not required)">
<input type="email" id="normal6" placeholder="Normal field (required)" required />
</div>
<div class="input-container">
<input type="text" id="cf5" placeholder="C.F. (not required)" data-thoth-filter="codice_fiscale">
<input type="text" id="cf6" placeholder="C.F. (required)" data-thoth-filter="codice_fiscale" required />
</div>
<input type="submit" id="capone-submit" value="Invia">
References:
Upvotes: 1
Reputation: 3206
Pure Javascript solution.
var form = document.getElementById('capote');
var submit = document.getElementById('capote-submit');
function hasClass(element, cls) { // Check if contains class
return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
}
function formValidation() {
var formNodes = form.childNodes; // childs of form
var error = false;
for (var i = 0; i < formNodes.length; i++) {
var divNodes = formNodes[i].childNodes; // childs of divs that contains inputs
for (var k = 0; k < divNodes.length; k++) {
if (hasClass(divNodes[k], 'err-input')) { // has class 'err-input'
error = true;
break;
}
}
}
if (!error)
submit.disabled = false; // if there is no input with class 'err-input', enable submit button
}
formValidation();
<form action="" id="capote">
<div class="input-container">
<input type="email" id="email1" placeholder="Email (not required)" data-thoth-filter="email">
<input type="email" id="email2" placeholder="Email (required)" data-thoth-filter="email" required>
</div>
<div class="input-container">
<input type="email" id="normal1" placeholder="Normal field (not required)">
<input type="email" id="normal2" placeholder="Normal field (required)" required>
</div>
<div class="input-container">
<input type="text" id="cf1" placeholder="C.F. (not required)" data-thoth-filter="codice_fiscale">
<input type="text" id="cf2" placeholder="C.F. (required)" data-thoth-filter="codice_fiscale" required>
</div>
<input type="submit" id="capote-submit" value="Invia">
</form>
Upvotes: 1
Reputation: 431
// If you are using jQuery, just go:
$("form#capote:input").each(function(){
// if input has class ERR_INPUT, disable submit button.
});
// Happy Coding.
Upvotes: 0