Skip to content

TRIPTYK/ember-base-form-validation

Repository files navigation

ember-base-form-validation

Test Build npm version

Simple ember component based form validation module , only providing base structure and components for validation . His goal is to be flexible and adaptive to any situation.

⚠️ This addon does not provide any types validation methods or checks.

Compatibility

  • Ember.js v2.18 or above
  • Ember CLI v2.13 or above
  • Node.js v8 or above

Installation

ember install ember-base-form-validation

Features

  • Async validation
  • Component level validation
  • You choose when to validate and at which level

Elements

The validation form component

The validation form is the base of the validation , it must contain a @schema attribute in order to provide validation to the inputs.

userform.hbs

<ValidationForm @validateOnInit={{false}} class="form" @schema={{this.validation}} as |form|>
</ValidationForm>

attributes

  • @schema (required) : a Validation schema for the children inputs
  • @validateOnInit (optional) : a boolean to tell the form to validate or not all the children on init.
  • any html attributes(optional)

methods

  • validate : runs the validation for all the children

properties

  • isDirty (boolean) : returns if the form is dirty (any field has been validated)
  • hasErrors (boolean) : returns if the form validator has errors
  • validating (boolean) : returns if the form validator is running validations (for async).

The input component

The validation input is an HTML input who validates its value after some events had been triggered.

<ValidationForm class="form" @schema={{this.validation}} as |form|>
  <ValidationInput @validation="username" @validateOn="change" name="username" @parent={{form}} as |i|>
    {{#if i.error}}
      <p>{{i.error}}</p>
    {{/if}}
  </ValidationInput>
  <ValidationInput @validation="email" @validateOn="focus" name="email" @parent={{form}} as |i|>
    {{#if i.error}}
      <p>{{i.error.message}} for {{i.error.field}}</p>
    {{/if}}
  </ValidationInput>
  <input type="submit" disabled={{form.hasErrors}} {{on "click" this.submit}} value="submit">
</ValidationForm>

attributes

  • @parent (BaseValidationFormComponent) (required) : the parent form.
  • @validation (string) (required) : Tell which validation the validator must use to validate the input value.
  • @validateOn (string) (optional) : an html event to tell the input when to launch its validation.
  • @alone (boolean) (optional) : disable the validation , @parent and @validation attributes become optional.
  • any html attributes(optional)

methods

  • validate : runs the validation for the input

properties

  • isDirty (boolean) : returns if the input value is dirty (has been validated)
  • error (any) : error associated to the input (null if no error)

The validation schema

The validation schema checks if the current value of the input is correct , otherwhise it returns any value indicating there's an error for the field. If it returns null or undefined , the value is correct. The method can be async or sync.

import validator from 'validator'; // external validation module
import { BaseValidator , validationProperty } from 'ember-base-form-validation';

export class UserValidator extends BaseValidator {
    @validationProperty()
    username(str) {
        if (!validator.isLength(str,{
            min : 10
        })) {
            return 'Lenght must be less than 10 characters';
        }
    }

    @validationProperty()
    async email(str) {
        if (!validator.isEmail(str)) {
            return { // can return in any format you want
              message : 'Email not valid',
              field : 'email'
            };
        }
    }
}

The validation property

@validationProperty(ignoreUndefined = true) indicates that the method is a validation method. The parameter ignoreUndefined converts the input value to a null string if it's undefined.

properties

  • errors object : errors of the validator
  • context any : context passed by the constructor

methods

  • waitAndCheckErrors (Promise<boolean>) : wait for the validator to finish validation and returns if it contains errors.

  • hasErrors (boolean) : returns if validator has errors

  • isDirty (boolean) : returns if validator has validated this field at least once

  • validationRunning (boolean) : returns if validator is running async tasks.

Registeting and checking the validation controller side

import Component from '@glimmer/component';
import { UserValidator } from '../validation/user';
import { action } from '@ember/object';

export default class UserFormComponent extends Component {
    validation;

    constructor(...args) {
        super(...args);
        this.validation = new UserValidator(this);
    }
    
    @action
    submit(t) {
        this.validation.waitAndCheckErrors().then(  (hasErrors) => {
          if (hasErrors) {
            return;
          }
          // do your job
        }
    }
}

Custom validation input :

Same as above except for the template. Custom Input let you define you own input to bind the value to and validate.

userform.hbs

<ValidationForm @validateOnInit={{true}} @schema={{this.validation}} as |form|>
  <ValidationInputCustom @parent={{form}} @validation="username" @value={{@model.username}} as |i|>
    <Input type="text" name="username" @value={{i.value}} {{on "change" i.validate}}  />

    {{#if i.error}}
      <p>{{i.error}}</p>
    {{/if}}
  </ValidationInputCustom>

    <ValidationInputCustom @parent={{form}} @validation="email" @value={{@model.email}} as |i|>
    <Input type="text" name="email" @value={{i.value}} {{on "change" i.validate}}  />

    {{#if i.error}}
      <p>{{i.error}}</p>
    {{/if}}
  </ValidationInputCustom>
  
  {{#if form.validating}}
    <p>Validating...</p>
  {{else}}
    <input type="submit" disabled={{form.hasErrors}} {{on "click" this.submit}} value="submit">
  {{/if}}
</ValidationForm>

Create your own components

You can inherit BaseValidationInputComponent class to make your custom input component and BaseValidationFormComponent to make your own validation form

myinput.js

import { action } from '@ember/object';
import { BaseValidationInputComponent } from 'ember-base-form-validation';

export default class MyinputComponent extends BaseValidationInputComponent {
    constructor() {
        super(...arguments);
        console.log("Init custom");
    }

    @action
    validate() {  
        super.validate();
        console.log("Validate " + this.name);
    }
}

myform.js

import { action } from '@ember/object';
import { BaseValidationFormComponent } from 'ember-base-form-validation';

export default class MyformComponent extends BaseValidationFormComponent {
    constructor() {
        super(...arguments);
        console.log("Init custom");
    }

    @action
    validate() {  
        super.validate();
        console.log("Validate all");
    }
}

Contributing

❗ I'm new to EmberJS community , don't hesitate to contribute !

See the Contributing guide for details.

License

This project is licensed under the MIT License.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •