JSFiddle - React, Tailwind, and code Playground
by Krzysztof Safjanowski
HTML
<form id="form">
<div>
<label for="username">Name</label>
<input name="name" type="text" placeholder="Name" pattern="[a-z]{1,15}" id="name">
</div>
<div>
<label for="username">Surname</label>
<input name="surname" type="text" placeholder="Surname" pattern="[a-z]{1,15}" id="surname">
</div>
</form>
CSS
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
font-family: "Trebuchet MS", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Tahoma, sans-serif;
background-color: #ECEFF1;
}
form {
max-width: 300px;
margin-right: auto;
margin-left: auto;
text-align: left;
position: relative;
}
label,
input {
display: block;
}
label {
font-size: 12px;
text-transform: uppercase;
color: #B0BEC5;
margin-bottom: 10px;
}
input {
width: 100%;
padding: 10px;
outline: 0;
border: 2px solid #B0BEC5;
}
input.invalid {
border-color: #DD2C00;
}
.notify {
margin-top: 5px;
padding: 10px;
font-size: 12px;
width: 100%;
color: #fff;
display: block;
width: 100%;
}
.notify.error {
background-color: #DD2C00;
}
JavaScript
class Input {
constructor(name, message, fn) {
this.name = name
this.message = message
this.createErrorLabel(fn)
}
createErrorLabel(fn) {
this.error = fn(this.name)
}
markInvalid() {
this.name.className = 'invalid';
this.error.textContent = this.message;
this.error.className = 'error notify';
this.error.style.display = 'block';
}
markValid() {
this.name.className = '';
this.error.style.display = 'none';
}
}
[
new Input(document.getElementById('name'), 'Name should only contain lowercase letters e.g. john', function(element) {
var error = document.createElement('div');
error.className = 'notify';
error.style.display = 'none';
element.parentNode.appendChild(error);
return error
}),
new Input(document.getElementById('surname'), 'Surname should only contain lowercase letters e.g. john', function(element) {
var error = document.createElement('div');
error.className = 'notify';
error.style.display = 'none';
element.parentNode.appendChild(error);
return error
})
]
.forEach(function(type) {
type.name.addEventListener('invalid', function(event) {
event.preventDefault();
});
type.name.addEventListener('input', function(event) {
event.preventDefault()
if (!event.target.checkValidity()) {
type.markInvalid()
} else {
type.markValid()
}
});
});