JSFiddle - React, Tailwind, and code Playground

by NOVUSIDEA

HTML

<form id="form-1" data-validate="validate" method="post" action="/echo/html/">
    <div class="row">
        <label>Name</label>
        <input type="text" name="name" class="required" data-message="Bitte füllen Sie diese Feld aus." />
    </div>
    <div class="row">
        <label>Text</label>
        <textarea name="text" class="required" data-message="Bitte füllen Sie diese Feld aus."></textarea>
    </div>
    <div class="row">
        <label>Single Options</label>
        <select name="single-options" class="required" data-message="Bitte füllen Sie diese Feld aus.">
            <option value="">- Chose -</option>
            <option value="1">Option 1</option>
            <option value="2">Option 2</option>
            <option value="3">Option 3</option>
        </select>
    </div>
    <div class="row">
        <label>Multiple Options</label>
        <select name="multiple-options" multiple="multiple" class="required" data-message="Bitte füllen Sie diese Feld aus.">
            <option value="1">Option 1</option>
            <option value="2">Option 2</option>
            <option value="3">Option 3</option>
        </select>
    </div>
    <div class="row">
        <label>Radio-Options</label>
        <label><input type="radio" name="radio-option" value="Option 1" class="required" /> Option 1</label>
        <label><input type="radio" name="radio-option" value="Option 2" class="required" /> Option 2</label>
        <label><input type="radio" name="radio-option" value="Option 3" class="required" /> Option 3</label>
    </div>
    <div class="row">
        <label>Checkbox-Options</label>
        <label><input type="checkbox" name="checkbox-option" value="Option 1" class="required" /> Option 1</label>
       <label> <input type="checkbox" name="checkbox-option" value="Option 2" class="required" /> Option 2</label>
        <label><input type="checkbox" name="checkbox-option" value="Option 3" class="required" /> Option 3</label>
    </div>
    <div...

SCSS

body {
    margin: 0;
}
* {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}
.row {
    padding: 10px;
    label {
        display: block;
        margin-bottom: 5px;
        cursor: pointer;
    }
    input, select, button, textarea {
        padding: 3px 6px;
        font-size: 14px;
        width: 100%;
        border: 1px solid #ccc;
    }
    button,
    input[type="submit"],
    input[type="button"],
    input[type="image"],
    input[type="radio"],
    input[type="checkbox"] {
        width: auto;
        cursor: pointer;
    }
}
.error {
    color: red;
    .required {
        border-color: red;
    }
}
.success {
    color: green;
    .required {
        border-color: green;
    }
}

JavaScript

// Vorerst mit Klassen, später mit dem HTML5-Attribut "required"
$('form[data-validate="validate"]').each(function(formIndex, formElement){

    var form = $(formElement);
    var errors = new Array();

    form.submit(function(ev){

        var fields = form.find('input, select, textarea');
        
        $('.error-message').remove();

        fields.each(function(fieldIndex, fieldElement){

            var field = $(this);
            var target = $(this).parent();
            
            target.removeClass('error success');

            if( field.hasClass('required') ) {

                //console.log( field.attr('type', 'radio') );
                //console.log( field.val() );

                var type = (field.attr('type')) ? field.attr('type') : '';
                var name = (field.attr('name')) ? field.attr('name') : '';

                if( !type.match(/radio|checkbox/i) ) {
                    if( !field.val() ) {
                        target.addClass('error');
                        errors.push({
                            element: field,
                            message: field.data('message') || ''
                        });
                    } else {
                        target.addClass('success');
                    }
                }

                if( type.match(/radio/i) ) {                    
                    if( $('[name="' + name + '"]:checked').length == 0 ) {
                        errors.push({
                            element: field,
                            message: field.data('message') || ''
                        });
                        target.addClass('error');
                    } else {
                        target.addClass('success');
                    }
                }

                if( type.match(/checkbox/i) ) {
                    if( !field.prop('checked') ) {
                        errors.push({
                            element: field,
                            message:...