|
Review: We saw an example of javascript that was run by the browser; we defined the javascript functions in the head (or, in a separate file which was included via a <script src=… > tag in the head). Then, in various tags we had onclick attributes, whose value was a bit of javascript code, which the browser then evaluated. (e.g. Whatever you do don't click <span onclick="explode();">here</span>.).
Other events that can invoke javascript: onchange, onclick, onfocus, onblur. See w3.org’s definition.
The straightforward way to validate: When the user submits, call a function you've written, which validates all the inputs. The onsubmit attribute of the form tag is the place to call it: <form onsubmit='return validateAll();'>, where your function validateAll should return a boolean; returning false tells the browser not to actually submit.
The browser will submit a form when:
Alternately: the browser will also submit if your javascript
explicitly calls the form’s submit(·) method.
This bypasses steps (a)…(c) above (!).
Calling submit directly is something one might do on a login-page:
as soon as the user types "enter" at the end of typing their username/password
your javascript might trigger the submit
(instead of forcing the user to click on an additional input type='submit' button).
<form id="form4-demo" method="get" action="">
<input type="number" name="stars" min="1" max="10" required="required" placeholder="a number in 1..10" style="width:9em;"/>
<label><input type='checkbox' onclick='document.getElementById("form4-demo").submit();'/>click to force-submit</label>
<span class="additional-info">note how this checkbox bypasses the browser’s validation</span>
<input type="submit" value="submit to self"/>
</form> |
Some oddities:
- An input's pattern attribute doesn't get evaluated onchange — only onsubmit?
- Note CSS's "states":
(however, violating an input's required attribute doesn't cause it to style as :invalid ?)
input:invalid, textarea:invalid, select:invalid { color:red; }
Suppose you have an a field named "age", which should be between at least 21, but not 40 or more1. We've already seen that we want to validate this both by the input tag's onchange, as well as by the form tag's onsubmit. So we definitely want to avoid the repeated code.
function validateAge() { var ageNode = document.getElementById('age'); var age = ageNode.value; var isValid = (21 <= age && age < 40); var ageErrMsgNode = document.getElementById('ageErrMsg'); if (!isValid) { ageErrMsgNode.innerHTML = "Must be between 21 (inclusive) and 40 (non-inclusive)"; // Hmm, might be nice to include the offending value in the error msg? } return isValid; } |
Things to consider:
the example form (a repeat of previous link)
Improved version: Have a validation-function “validateAgeErrMsg” which just returns the error-message-string (perhaps the empty-string, if no error); have a separate function “insertErrMsg” that takes a node and a message, and splices that message-text into the DOM for that node, with a style that indicates an error message2 (perhaps small but angry red font).
You can also see w3.org’s definition of the insertAdjacentHTML method.
There are quite a few different input element types; choosing the right one is often all the validation you need (e.g. for a telephone number, <input type='tel' name='…'/> is likely all the validation you need.
In addition, a lot of validation can be done with html5 attributes. This can shorten — or even eliminate — the need for individual validation functions. And if no individual validation functions are needed, then a validateAll isn't either!
video (20m57s)Note: If a dropdown is required, and you don't want the first option to be used as a (default) value, then the first option must include value="".
<form id='demo-form'> <select name="select-demo" required="required"> <option value="">choose one</option> <option>a</option> <!-- 'a' will be the value, if this option is chosen. --> <option value="bee" formaction="." formmethod="get">b</option> </select> <input type="submit" value="submit to self"/> </form>
<form id='demo3-form'> <input type='text' name='text-demo' required='required' pattern='([a-z]{3})+' title='lower-case letters; length is multiple of 3'/> <input type="text" name="username" required='required' placeholder="username" pattern="[a-z]{1,15}"/> </form> |
When possible, do validation via the pre-defined html attributes, rather than roll-your-own javascript to do the same. Even if you have a nicer way of presenting the information, there is strength in having the user see error messages always presented in the same way across all their sites. It also enables users to configure browser shortcut/hotkeys, plug-ins, etc. to improve their experience on your site.4 The one thing I miss (as of Chrome v56.0, 2017-Mar) is that browser-validation-errors tends to only get revealed one-by-one, as the submit button is pressed, whereas I'd prefer them to be revealed instantly onchange. But, a future version of the browser might well fix this.
Note that CSS provides special support for an input’s “:valid” pseudo-class. For example, you can include:
input:invalid, textarea:invalid, select:invalid { color:red; } |
This page licensed CC-BY 4.0 Ian Barland Page last generated | Please mail any suggestions (incl. typos, broken links) to ibarlandradford.edu |