Created
November 24, 2017 13:16
-
-
Save zanonnicola/6b0ad8d000ef921ef5707ed79a4d71a5 to your computer and use it in GitHub Desktop.
HTML5 Form validation. Based on https://jsfiddle.net/Loilo/jdct84x6/3/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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