formJS

/

Demos

Lite Version

HTML

<form action="../json/data.json" name="my-form">
    <div data-formjs-question class="form-group">
        <div class="answers-box label-move-up">
            <input name="name" type="text" data-length="[3,20]" class="form-control" required />
            <label>Name</label>
        </div>
        <div class="field-error-message small">Write your name! It must be between 3 and 20 chars.</div>
    </div>
    <div data-formjs-question class="form-group">
        <div class="answers-box label-move-up">
            <input name="surname" type="text" data-length="[3,20]" class="form-control" data-validate-if-filled />
            <label>Surname</label>
        </div>
        <div class="field-error-message small">Surname is not mandatory but, if filled, it must be between 3 and 20 chars!</div>
    </div>
    <div data-formjs-question class="form-group">
        <div class="answers-box label-move-up">
            <input name="email" type="email" class="form-control" required />
            <label>Email</label>
        </div>
        <div class="field-error-message small">Check your email address, it is not valid!</div>
    </div>
    <div data-formjs-question class="form-group">
        <p class="mb-2 small">Select your contact preferences <br />( 2 answers max )</p>
        <div class="answers-box">
            <div class="form-check">
                <input name="contactPrefCheck" type="checkbox" value="sms" class="form-check-input" id="checkbox-1-a" required data-checks="[1,2]" />
                <label class="form-check-label" for="checkbox-1-a">SMS</label>
            </div>
            <div class="form-check">
                <input name="contactPrefCheck" type="checkbox" value="email" class="form-check-input" id="checkbox-2-a" required />
                <label class="form-check-label" for="checkbox-2-a">Email</label>
            </div>
            <div class="form-check">
                <input name="contactPrefCheck" type="checkbox" value="app-notiifcation" class="form-check-input" id="checkbox-3-a" required />
                <label class="form-check-label" for="checkbox-3-a">App Notification</label>
            </div>
        </div>
        <div class="field-error-message small">
            You must select at least 1 and at most 2 answers!
        </div>
    </div>
    <div data-formjs-question class="form-group">
        <div class="answers-box">
            <div class="small">
                I agree with the <a href="#" target="_blank">Privacy Policy</a>.
            </div>
            <div class="form-check form-check-inline">
                <input class="form-check-input" type="radio" name="privacyCheck" id="privacyCheck-1-a" value="accepted" required />
                <label class="form-check-label" for="privacyCheck-1-a">Yes</label>
            </div>
            <div class="form-check form-check-inline">
                <input class="form-check-input" type="radio" name="privacyCheck" id="privacyCheck-2-a" value="" required />
                <label class="form-check-label" for="privacyCheck-2-a">No</label>
            </div>
        </div>
        <div class="field-error-message small">You must agree!</div>
    </div>
    <div class="text-center">
        <button type="submit" class="btn btn-light">SEND</button>
    </div>
    <div class="d-none alert mt-5 mb-4" role="alert" data-formjs-global-feedback></div>
</form>

JS

function checkDirtyField($field){
    const containerEl = $field.closest('[data-formjs-question]');
    containerEl.classList.remove('is-dirty');
    if( $field.value ){
        containerEl.classList.add('is-dirty');
    }
}

function setFieldValid(){
    const containerEl = this.closest('[data-formjs-question]');
        containerEl.classList.remove('has-error');
        containerEl.classList.add('is-valid');
}

function showErrorMessage(errors){
    console.log(this, errors);
    const containerEl = this.closest('[data-formjs-question]');
        containerEl.classList.remove('is-valid');
        containerEl.classList.add('has-error');
}

function validateField(event){
    const $field = event.target;
    if( !$field.matches('input:not([type="reset"]):not([type="submit"]):not([type="button"]):not([type="hidden"]), select, textarea') ){
        return;
    }
    formInstance.validateField($field)
        .then(setFieldValid.bind($field))
        .catch(showErrorMessage.bind($field));
}

const $form = document.querySelector('form');

/* VALIDATE FIELDS WITH EVENT DELAGATION */
$form.addEventListener('blur', validateField, true);

/* VALIDATE FIELDS DIRECTLY */
Array.from($form.querySelectorAll('[type="checkbox"], [type="radio"]')).forEach($field => {
    $field.addEventListener('change', validateField, false);
});

$form.addEventListener('submit', event => {
    event.preventDefault();
    formInstance.validateForm()
        .then(fields => {
            alert('Form is valid');
            console.log(fields);
            fields.forEach(obj => {
                setFieldValid.call(obj.$field);
            });
        })
        .catch(fields => {
            alert('Form is NOT valid');
            console.log(fields);
            fields.forEach(obj => {
                if( !obj.result ){
                    showErrorMessage.call(obj.$field, obj.errors);
                }
            });
        });
});

const options = {
    fieldOptions: {
        beforeValidation: function(fieldObj){
            checkDirtyField(fieldObj.$field);
        }
    }
};

const formInstance = new Form( $form, options );

Fill the form:


Write your name! It must be between 3 and 20 chars.
Surname is not mandatory but, if filled, it must be between 3 and 20 chars!
Check your email address, it is not valid!

Select your contact preferences
( 2 answers max )

You must select at least 1 and at most 2 answers!
I agree with the Privacy Policy.
You must agree!