Brad Peabody
Brad Peabody

Reputation: 11417

Is there a way to check the validity of a single HTML5 input element? (not the entire form)

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

Answers (5)

hardika
hardika

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

Hunter
Hunter

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

Sagar V
Sagar V

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

Sudhakar
Sudhakar

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

RakNoel
RakNoel

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

Related Questions