Skip to content

Instantly share code, notes, and snippets.

@zanonnicola
Created November 24, 2017 13:16
Show Gist options
  • Save zanonnicola/6b0ad8d000ef921ef5707ed79a4d71a5 to your computer and use it in GitHub Desktop.
Save zanonnicola/6b0ad8d000ef921ef5707ed79a4d71a5 to your computer and use it in GitHub Desktop.
HTML5 Form validation. Based on https://jsfiddle.net/Loilo/jdct84x6/3/
<form>
<input
type="number"
placeholder="Enter 42"
min="42"
max="42"
required>
<input
type="email"
placeholder="Enter your email"
required>
<button type="submit">Register</button>
</form>
let submitted = false
// 1. Disable native validation UI with `noValidate`
// 2. On submit, run evaluation and prevent if necessary
const form = document.querySelector('form')
form.noValidate = true
form.onsubmit = evt => {
submitted = true
setTimeout(() => {
submitted = false
}, 0)
if (!form.checkValidity()) {
evt.preventDefault()
}
}
// Iterate over fields in form
let invalidOnSubmit = false
for (const field of form.querySelectorAll('input, textarea, select')) {
// Add error container
field.insertAdjacentHTML('afterend', '<div class="error"></div>')
// Show message on `invalid` event
field.oninvalid = () => {
if (submitted && !invalidOnSubmit) {
invalidOnSubmit = true
setTimeout(() => {
invalidOnSubmit = false
}, 1000)
field.focus()
}
field.classList.add('invalid')
field.nextSibling.textContent = field.validationMessage
// Reset invalid state & error message on `input` event, trigger validation check
const inputHandler = () => {
field.oninput = null
field.nextSibling.textContent = ''
field.classList.remove('invalid')
field.checkValidity()
}
field.oninput = inputHandler
}
}
/* Global styles */
html {
height: 100%;
}
body {
font-family: sans-serif;
font-weight: 300;
font-size: 20px;
background: linear-gradient(to top, #e0e7ef, #eef2f7);
min-height: 100%;
color: #798594;
line-height: 1.6;
}
/* Form styles */
form {
background: #f8fafb;
padding: 3em 1em;
border-radius: 3px;
box-shadow: 0 0.1em 0.4em #b7ccde;
max-width: 15em;
margin: 2em auto;
}
button, input, textarea, select {
font: inherit;
color: inherit;
padding: 0.4em 0.6em;
border: 1px solid #ccc;
border-radius: 4px;
width: 100%;
box-sizing: border-box;
margin-bottom: 0.5em;
}
button {
cursor: pointer;
background-color: #e9f1ff;
color: #7e93b7;
}
input {
display: block;
position: relative;
z-index: 1;
}
input::placeholder {
color: #bbb;
}
/* Error styles */
.invalid {
box-shadow: 0 0.15em 0.15em -0.1em rgba(4, 4, 4, 0.1);
}
.error {
display: none;
margin-bottom: 0.5rem;
margin-top: calc(-0.5rem - 4px);
margin-left: 2px;
margin-right: 2px;
padding: calc(0.5rem + 4px) 0.6rem;
background-color: #ffefeb;
color: #b75a41;
border: 1px solid #e6917a;
border-radius: 0 0 4px 4px;
animation: show-error 0.3s;
font-size: 0.8em;
}
.invalid + .error {
display: block;
}
@keyframes show-error {
from {
transform: translateY(-2em) scaleY(0.2);
}
to {
transform: none;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment