Reputation: 11417
I have a form which has multiple parts of it which change based on user input. Some fields are required in certain cases but not in others and there is JS which hides and shows the appropriate fields.
I am aware of the checkValidity()
function which can be called on a form object to check if the HTML5 validation passes (attributes like required
, pattern
, etc.).
But my form is too complex for that and checkValidity()
for the form may indicate that my form is invalid but I have intentionally hidden that field from the user based on, e.g. an option chosen in a select box.
Is there something similar to checkValidity()
for an individual field? Or is there another elegant solution to this problem?
EDIT: Here's a working example that demonstrates the issue https://jsfiddle.net/w5ycvtsm/
HTML:
<form id="mainform">
<select id="opts" name="opts">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="_other">Other</option>
</select>
<br/>
<input type="text" id="opt_other" name="opt_other" required>
<br/>
<input type="submit"/>
</form>
JS:
function fixOptsState() {
var v = document.getElementById('opts').value;
var otherEl = document.getElementById('opt_other');
if (v == "_other") {
otherEl.style.display = 'block';
} else {
otherEl.style.display = 'none';
}
}
document.getElementById('opts').addEventListener('change', fixOptsState);
fixOptsState();
document.getElementById('mainform').addEventListener('submit', function(e) {
e.preventDefault();
var mainform = document.getElementById('mainform');
console.log(mainform.checkValidity());
});
checkValidity()
actually gives an error in Chrome, saying
An invalid form control with name='opt_other' is not focusable.
Upvotes: 3
Views: 4323
Reputation: 642
I think you can validate using the following method.
Refer to a link to find more Validity Properties
if (!$("#your_id")[0].validity.valid)
// display your message label
$('#InvalidPhoneNumber').text('Invalid phone number');
You can use the following function to validate single and form both. Notes: you need to update according to your requirement.
function formValidation(
event,
form_id,
list_of_elements = []
) {
var form = $(`#${form_id}`);
if (event != undefined) {
event.preventDefault();
event.stopPropagation();
}
if (list_of_elements.length > 0) {
list_of_elements.forEach(id => {
var ele = $("#"+id)[0];
if (!ele.validity.valid) {
//display error messages
ele.next().text('error message');
}
});
return false;
}
if (form[0].checkValidity() == false) {
form.addClass('was-validated');
return false;
}
return true;
}
Upvotes: 0
Reputation: 123
This works great for me, it is an improvement on Sagar V's. In my case, you don't need to append the form to the body, much cleaner.
function checkInput(el) {
// Clone Input
const clone = el.cloneNode(true);
// Create Temp From
const tempForm = document.createElement('form');
tempForm.appendChild(clone);
// Check Form
console.log('Validity = ' + tempForm.checkValidity());
}
const requiredInputs = querySelectorAll('input[required]');
// or whatever selector applies to your case
requiredInputs.forEach(el => {
el.addEventListener('change', () => { checkInput(el) });
});
Upvotes: 0
Reputation: 12478
How about creating and destroying the input dynamically?
function fixOptsState() {
var v = document.getElementById('opts').value;
var otherEl = document.createElement('input');
otherEl.id="opt_other";
otherEl.setAttribute("required","");
if (v == "_other") {
document.getElementById('mainform').insertBefore(otherEl,document.querySelector('input[type=submit]'));
} else {
document.getElementById('opt_other')!=undefined?document.getElementById('mainform').removeChild(document.getElementById('opt_other')):void(0);
}
}
document.getElementById('opts').addEventListener('change', fixOptsState);
fixOptsState();
document.getElementById('mainform').addEventListener('submit', function(e) {
e.preventDefault();
var mainform = document.getElementById('mainform');
console.log(mainform.checkValidity());
});
<form id="mainform">
<select id="opts" name="opts">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="_other">Other</option>
</select>
<br/>
<input type="text" id="opt_other" name="opt_other" required>
<br/>
<input type="submit"/>
</form>
Upvotes: 1
Reputation: 324
You can use checkValidity function to validate the html5 field as soon as it loose focus. so that it will not validate hidden input field.
$('input').blur(function(event) {
event.target.checkValidity();
}).bind('invalid', function(event) {
setTimeout(function() { $(event.target).focus();}, 50);
});
Upvotes: 1
Reputation: 59
Javascript does enable you to read the input in a single textbox in the form. Just grab it by giving it a unique ID in HTML5 and validate on key update. Then make whatever many functions needed to test all textboxes individually with its own parameters and complexity.
Upvotes: 0