4

I have a page that I'm building and do not have the option to import jQuery. I need to be able to determine if any textboxes are marked with an html 5 invalid psuedoclass using a pure javascript solution. Said more simply: I need to use javascript to determine if any of the textboxes have the red outline that textboxes get marked with if you, for example, put text in a type=number field.

Just for completeness, here's some sample code:

<input type="number" min="1" max="31" id="txtCalDays" placeholder="##"/>
<input type="button" onclick="ValidateForm()"/> 
...
<script>
...
function ValidateForm(){
    ... //magic happens here
    if (numberInvalidTextboxes == 0){ SubmitFormViaAjax(); }
}
2
  • 3
    ":invalid" is a css selector you can use to find them Commented Oct 8, 2015 at 20:22
  • 1
    To add to @dandavis 's answer, :invalid is supported only from IE10+, if that's any consideration to you. Commented Oct 8, 2015 at 20:28

5 Answers 5

3

You can use checkValidity() method to detect the validity of a html5 input element.

document.getElementById('txtCalDays').checkValidity()

Here is the fiddle:

http://jsfiddle.net/k7moorthi/saobbfzo/

Sign up to request clarification or add additional context in comments.

3 Comments

I'll end up going with this, iterating through each of the inputs in the containing control. I prefer the cleaner input:invalid pseudoclass solution but this is what I have to use since we still support IE 9. Thank you!
@MetalPhoenix You will still need to polyfill the <input type="number"> like @hexaheart pointed out.
Just a note: checkValidity is not supported in IE BUT the other validation that I am doing makes up for that (both server and clientside) - they all work together to validate no matter which browser our staff is using. CheckValidity ends up working beautifully on every other browser except IE9 so this is a "win" solution. Thanks.
2

You can use querySelectorAll

document.querySelectorAll('input:invalid') return an array of all invalid input in the document, you can replace document by any type of node.

Add some css like :invalid{background-color: rgba(250,0,0,.15);} can be usefull also.

6 Comments

The document.querySelectorAll('input:invalid').length > 0 solution is exactly what I was looking for and seems to work in firefox, chrome, and IE. Thank you.
Older version of IE doesn't support html5 input anyway :P
Okay, not what I was looking for. We still have to support a few computers with IE 9.
IE9 is ok with :invalid & querySelectorAll, only the type="number" isn't supported :/.
@Tim MetalPhoenix doesn't want to use jQuery that's probably the case for any lib.
|
2

Give an id or a class for each element and give the code this way:

window.onload = function () {
  document.getElementById("theFrm").onsubmit = function () {
    var inputs = document.querySelectorAll(".input");
    for (var i in inputs)
      if (!inputs[i].validity.valid) {
        inputs[i].focus();
        return false;
      }
    ajaxSubmit();
    return false;
  };
};
*:invalid, .error {border: 1px solid #f00; background: #f99;}
<form action="" id="theFrm">
  <input type="number" min="1" max="31" id="txtCalDays" required placeholder="##" class="input" />
  <input type="submit" onclick="ValidateForm()" /> 
</form>

8 Comments

how does that implement html5 validation state?
@dandavis It will not allow the user to submit, by returning false.
Not only does this not use the valid/invalid state of the controls, it ties the script to the shape of the database. This is not acceptable since the amount of changes that need to be made when a column is added or removed must be minimized.
The updated answer STILL ignores the html 5 validation types. Adding a class to a control isn't the solution I need
@MetalPhoenix Updated again. Sorry.
|
1

I think the method you are looking for is checkValidity().

https://developer.mozilla.org/en-US/docs/Web/API/HTMLSelectElement/checkValidity

;(function(w,d,undefined) {
  
  "use strict";
  
  function init() {
    // bind checkValidity() to button click
    d.querySelector("button.validity").addEventListener("click",checkValidity);
  }
  
  // loop through inputs and check validity
  var checkValidity = function() {
    var inputs = d.querySelectorAll('#f input');
    [].forEach.call(inputs,function(input) {
      alert( 'validness of ' + input.name + ' is ' + input.checkValidity() );
    });
  };
  
  // inititalize only when the DOM is ready
  d.addEventListener("DOMContentLoaded",init);
  
})(window,document);
body {
  background-color: #DEF;
}
#f {
  width: 222px;
  position: relative;
  padding: 2em;
  margin: auto;
}
#f > * {
  margin-bottom: .25em;
}
#f label, button {
  float: left;
  clear: left;
  width: 100px;
}
#f input, #f button {
  float: left;
  width: 100px;
}
<form id="f">
  
  <label for="tel">Just Numbers</label><input type="text" name="numbrz" pattern="\d+" />
  
  <label for="email">Email</label><input type="email" name="email" />
  
  <button type="button" class="validity">check validity</button>
  
</form>

Comments

0

You can use ValidityState.valid:

var input = document.getElementById("test");

input.addEventListener("change", function (event) {
    
    if (test.validity.valid) {
        input.classList.add("valid");
        input.classList.remove("invalid");
    } else {
        input.classList.add("invalid");
        input.classList.remove("valid");
    }
});
input.invalid {
    outline: 1px solid red;
}
<input type="number" id="test">

Now you can check for the input.invalid instead of input:invalid selector.

To make this cross-browser, you can bind this event listener in addition to the change event, also to the input, blur, keyup and keydown events. Furthermore you will need a polyfill for classList.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.