node package manager
Easy sharing. Manage teams and permissions with one click. Create a free org »


Easy-Suite for Material Design for Angular (and later ionic)

This is the home for Easy-Suite. Built for Angular using Material Design.

Component abstraction to allow easy dynamic pages. Build pages from component or in HTML.


The latest release of Easy-Suite can be installed from npm

npm install --save easy-suite

Project status

Easy Suite is currently in beta and under active development. During beta, new features will be added regularly and APIs will evolve based on user feedback.

Feature status:

Feature Status
cards Available
tabs Available
button Available
checkbox Available
checkbox-group Available
radio Available
input Available
select Available
selectKeyValue Available
autocomplete Available
datepicker Available
data-table Available

"Available" means that the components or feature is published and available for use, but may still be missing some behaviors or polish.

Getting started

Step 1: Install Easy Suite

npm install --save easy-suite

Step 2: Import the component modules

Import the NgModule:

import {EasyModule} from 'easy-suite';

Step 3: Hello World

import { Component} from '@angular/core';
import { EasyForm, EasyFormService, EasyField, EasyNotification, Colors, ButtonTypes } from 'easy-suite';
  selector: 'hello-world',
  template: '<easy-form [form]="form"></easy-form>'
export class HelloWorldComponent {
  form: EasyForm;
  constructor(public easyFormService: EasyFormService) { 
   this.form = this.easyFormService.createForm();
  buildForm() {
    let container = this.form.addCardContainer("Hello World Title");
    container.addInputField('helloWorldInput', 'Hello World');
    container.addButtonField('Save', () =>, { key:"1", color: Colors.color_primary, type: ButtonTypes.button_fab, icon: 'done' });
    let tabs = this.form.addTabContainer("Tab 1");
    let tab1 = tabs.container;
    tab1.addInputField("Input 1");
    let tab2 = tabs.tabs.addTabToTabContainer("Tab 2");
    tab2.addInputField("Input 2");
  save() {
    let fields = this.form.fields;
    let text = fields.filter(x => x.key == "helloWorldInput")[0].value;
    alert('Saving ' + text)


At runtime field names are validated to ensure only one key is added to the collection.

One of these exceptions can be thrown


More Methods

Containers :

form.addTabContainer(headerstring, optionsFieldOptions = {})
form.addCardContainer(headerstring, optionsFieldOptions = {})
form.addModalContainer(headerstring, optionsFieldOptions = {})


container.addInputField(labelstring, optionsFieldOptions = {})
container.addAutocompleteField(labelstring, optionsArray<KeyValue>)
container.addAutocompleteKeyValueField(labelstring, optionsArray<KeyValue>)
container.addSelectField(labelstring, itemsArray<string>
container.addSelectKeyValueField(labelstring, itemsArray<string>)
container.addButtonField(labelstring, actionFunction, optionsFieldOptions = {})

Floating Action Buttons (FABS):

this.form = this.easyFormService.createForm();
this.form.addAction("Save", () =>, { icon: Icons.icon_done, color: Colors.color_primary });
this.form.addAction("Back", () => this.back(), { icon: Icons.icon_arrow_back, color: Colors.color_warn });


constructor( private easyModalEasyModalService) {  }
let modal = form.addModalContainer(headerstring, optionsFieldOptions = {})
modal.addAction("Save", () => alert('save'));


export class FieldOptions<T> {
    color?: string
    icon?: string
    type?: string
    format?: string
    showLoader?: boolean
    columnSpan?: number
    value?: T
    key?: string
    label?: string
    required?: boolean
    order?: number
    controlType?: string
    action?: Function
    items?: Array<any>
    xsColumnSize?: string
    smColumnSize?: string
    mdColumnSize?: string
    lgColumnSize?: string
    xlColumnSize?: string
    hide?: boolean;
    maxLength?: number;
    validators?: Validator[]
    updateAction?: Function;

Available static types

Icons, InputTypes, ButtonTypes, Colors, DateFormats
Usage : 
import { ButtonTypes, Icons, Colors, InputTypes } from 'easy-suite';
tab.addInputField('Test Input', { type: InputTypes.input_type_password });

Step 4: Events


All fields expose a subscription property which can be subscribed to for field changes. Use this when fields are dependent on one another or you just need to know when something changes.

Example :

let field = container.addInputField('Hello World');


Example :

let field = container.addInputField('Hello World',{onEnter:()=>alert('Enter Pressed')});

Step 5 : Handling results

To auto map a dto to the fields collection use the mapFields method on EasyForm NB!!! Ensure the properties on the dto have been assigned values otherwise the properties aren't accessible to TypeScript

export class TestDto {
  name: string = ''; //Default value assigned.

To bind updates directly to a dto use the updateAction Function in the field options

 container.addInputField('Hello World', {updateAction:(field:EasyField) => foo = field.value;});

The Form object exposes a fields array. As fields are upated this KeyValue Array is also updated.

 let fields = this.form.fields;
 this.field = fields.filter(x => x.key == "helloWorldInput")[0].value;

Step 7 Component Validators.

Import EasyValidator

import { EasyValidator } from 'easy-suite';

Add validators to field

container.addInputField('Hello World', {validators: [EasyValidator.Required("Message to display")]});

Available validators

EasyValidator.Required("Message to display")
EasyValidator.MinLength(5,"Message to display")
EasyValidator.MaxLength(5,"Message to display")
EasyValidator.Pattern("some regex","Message to display")

Prebuilt validators

EasyValidator.Email("Optional Message")
EasyValidator.IdentityNumber("Optional Message")
EasyValidator.TelephoneNumber("Optional Message")

Checking field validation state before submitting form

let validationResult = this.form.validateForm();

This will return a valid flag and an array of invalid fields. Invalid fields will also be highlighted on the webpage.

Step 7 (Optional): Usage as component directives.

  <easy-checkbox [placeholder]="field.label" [(value)]="field.value"></easy-checkbox>
  <easy-input [placeholder]="field.label" [(value)]="field.value" (change)="valueChanged()"></easy-input>
  <easy-select [placeholder]="field.label" [(selectedValue)]="field.value" [items]="field.items" (selectedValueChange)="valueChanged()"></easy-select>
  <easy-select-key-value [placeholder]="field.label" [(selectedValue)]="field.value" [items]="field.items" (selectedValueChange)="valueChanged()"></easy-select-key-value>
  <easy-autocomplete [placeholder]="field.label" [items]="field.options"></easy-autocomplete>
  <easy-button [color]="field.color" [icon]="field.icon" [type]="field.type" [displayValue]="field.label" [showLoader]="field.showLoader" (onClicked)="executeAction(field.action)"></easy-button>
  <easy-table [rows]="field.rows" [columns]="field.columns" [actions]="field.actions"></easy-table>
  <easy-date-picker [placeholder]="field.label" [(value)]="field.value"></easy-date-picker>

Appendix: Configuring SystemJS

If your project is using SystemJS for module loading, you will need to add easy-suite to the SystemJS configuration:

  // existing configuration options
  map: {
    // ...
    'easy-suite': 'npm:easy-suite/src/',
    'easy-core': 'npm:easy-core/src/'
    // ...
  packages: {
    // ...
      'easy-core': {
        main: 'index.js',
        defaultExtension: 'js'
      'easy-suite': {
        main: 'index.js',
        defaultExtension: 'js'
    // ...