Angular2(ES6) Form with Validation

A simple Angular2(ES6) Form Example with Validation

by Guillaume Seguin

HTML

<script src="https://code.angularjs.org/2.0.0-alpha.44/angular2.sfx.dev.js"></script>
<div id="SiteWrapper">
  <div id="SearchContainer">
    <form (submit)="pushtoItemList($event)" [ngFormModel]="form">

      <div class="group">
        <input required ngControl="itemName" type="text" />
        <span class="highlight"></span>
        <span class="bar"></span>
        <label>Item Name (ex: iPhone 6s)</label>
      </div>

      <div class="group">
        <input required ngControl="buyPrice" type="text" />
        <span class="highlight"></span>
        <span class="bar"></span>
        <label>Buy Price (ex: US$ 650)</label>
      </div>

      <div class="group">
        <input required ngControl="sellPrice" type="text" />
        <span class="highlight"></span>
        <span class="bar"></span>
        <label>Buy Price (ex: US$ 675)</label>
      </div>

      <button type="submit" id="Add">Add Item</button>
    </form>
  </div>
</div>

CSS

/*General Styling*/

@import url(http://fonts.googleapis.com/css?family=Open+Sans);
* {
  font-family: 'Open Sans', sans-serif;
  font-size: 18px;
}

body {
  margin: 0;
  padding: 0;
  background: #f1f1f1;
}

#SiteWrapper {
  padding: 2.5em 2em;
  margin: 1em;
  background: #fff;
  border: 2px solid #a5a5a5;
}

#SearchContainer {
  padding: 1em 0;
}

#SearchInput {}


/*Form Design*/

.group {
  position: relative;
  margin-bottom: 55px;
}

input {
  padding: 10px 10px 10px 5px;
  display: block;
  width: 100%;
  border: none;
  border-bottom: 1px solid #ccc;
}

input:focus {
  outline: none;
}


/* Label Design */

label {
  color: #999;
  font-size: 18px;
  font-weight: normal;
  position: absolute;
  pointer-events: none;
  left: 5px;
  top: 10px;
  transition: 0.2s ease all;
  -moz-transition: 0.2s ease all;
  -webkit-transition: 0.2s ease all;
}


/* Active state */

input:focus ~ label,
input:valid ~ label {
  top: -20px;
  font-size: 14px;
  color: #22A7F0;
}


/* Underlining Bars */

.bar {
  position: relative;
  display: block;
  width: 100%;
}

.bar:before,
.bar:after {
  content: '';
  height: 2px;
  width: 0;
  bottom: 1px;
  position: absolute;
  background: #22A7F0;
  transition: 0.2s ease all;
  -moz-transition: 0.2s ease all;
  -webkit-transition: 0.2s ease all;
}

.bar:before {
  left: 50%;
}

.bar:after {
  right: 50%;
}


/* active state */

input:focus ~ .bar:before,
input:focus ~ .bar:after {
  width: 50%;
}


/* Highlighter */

.highlight {
  position: absolute;
  height: 60%;
  width: 100px;
  top: 25%;
  left: 0;
  pointer-events: none;
  opacity: 0.5;
}


/* active state */

input:focus ~ .highlight {
  -webkit-animation: inputHighlighter 0.3s ease;
  -moz-animation: inputHighlighter 0.3s ease;
  animation: inputHighlighter 0.3s ease;
}


/** Animations **/

@-webkit-keyframes inputHighlighter {
  from {
    background: #5264AE;
  }
  to {
    width: 0;
    background: transparent;
  }
}

@-moz-keyframes inputHighlighter {
  from {
   ...

JavaScript

import {
  FORM_DIRECTIVES,
  FormBuilder,
  Validators,
  Control,
  ControlGroup
}
from 'angular2/common';

const forbiddenNameValidator = (nameRe: RegExp) => {
  return (control: AbstractControl): {[key: string]: any} | null => {
    const forbidden = nameRe.test(control.value);
    return forbidden ? {'forbiddenName': {value: control.value}} : null;
  };
}

class formWithValidationExample {
  this.itemName = {};
  this.buyPrice = {};
  this.sellPrice = {};
  constructor(fb: FormBuilder) {

    this.form = fb.group({
      name: ["", Validators.required],
      buyPrice: ["", Validators.required],
      sellPrice: ["", Validators.required]
    });
  }
  pushtoItemList(event) {
    event.preventDefault();
  }
}