JSFiddle - React, Tailwind, and code Playground

by justamir

HTML

<meta name="viewport" content="width=device-width, initial-scale=1">
<form>
    <div class="form-row">
        <label for="name">Naam:</label>
        <input type="text" name="name" id="name" maxlength="10" placeholder="John Doe" data-required-message="Vul je naam in." required/>
        <span class="form-error">Naam is verplicht</span>
    </div>
    <div class="form-row">
        <label for="email">E-mail:</label>
        <input type="email" name="email" id="email" maxlength="60" placeholder="[email protected]" data-required-message="Vul je e-mail adres in." required/>
        <span class="form-error">E-mail is verplicht</span>
    </div>
    <div>
        <button>Verzenden</button>
    </div>
</form>

CSS

* { box-sizing: border-box; }
body {
    font-size: 1.2em;
}
body input, body button {
    font-size: 1.2em;
}

form > div {
    margin: 1em;
}
form button {
    width: 100%;
}
label { display: block; }
input {
    width: 100%;
    padding: 0.2em;
}
button {
    padding: 0.2em;
}
.invalid {
    background: red;
    color: white;
}
.error {
    color: red;
}

.form-error {
  display: none;
}

.has-error .form-error {
  display: block;
}

JavaScript

function validate() {
    var errorNode = this.parentNode.querySelector( ".error" ),
        span = document.createElement( "span" )
    
    this.classList.remove( "invalid" );
    if ( errorNode ) {
        errorNode.parentNode.removeChild( errorNode );
    }

    if ( !this.validity.valid ) {
        this.classList.add( "invalid" );
        this.parentNode.appendChild( span );
        span.classList.add( "error" );
        span.innerHTML = this.getAttribute(
            this.validity.valueMissing ? "data-required-message" : "data-type-message" );
    }
};

var form = document.querySelector( "form" ),
    inputs = form.querySelectorAll( "input" );

for ( var i = 0; i < inputs.length; i++ ) {
    inputs[ i ].addEventListener( "blur", validate );
    inputs[ i ].addEventListener( "invalid", validate );
};

// Turn off the bubbles
form.addEventListener( "invalid", function( event ) {
    event.preventDefault();
}, true );

// Support: Safari, iOS Safari, default Android browser
document.querySelector( "form" ).addEventListener( "submit", function( event ) {
    if ( this.checkValidity() ) {
        alert( "Successful submission" );
    } else {
        event.preventDefault();
    }
});