<!-- https://github.com/ShMcK/ng2Challenges/wiki/Login-Form -->
<!DOCTYPE html>
<html>

<head>
  <link data-require="bootstrap-css@*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
  <link rel="stylesheet" href="style.css" />
  <script src="https://jspm.io/system@0.16.js"></script>
  <script src="https://code.angularjs.org/2.0.0-alpha.24/angular2.dev.js"></script>
</head>

<body>


  <div class="container">
    <div class="card card-container">

      <img id="profile-img" class="profile-img-card" src="//ssl.gstatic.com/accounts/ui/avatar_2x.png" />

      <!-- form directive here -->
      <form-app>Loading...<br></form-app>

      <a href="#" class="forgot-password">
                Forgot the password?
            </a>

    </div>
  </div>


  <script>
    System.config({
      paths: {
        '*': '*.js',
        'angular2/*': 'angular2/*',
      }
    });
    System.import('main');
  </script>
</body>

</html>
/*
  source: http://bootsnipp.com/snippets/featured/google-style-login-extended-with-html5-localstorage
 * Specific styles of signin component
 */
/*
 * General styles
 */
body, html {
    height: 100%;
    background-repeat: no-repeat;
    background-image: linear-gradient(rgb(104, 145, 162), rgb(12, 97, 33));
}

.card-container.card {
    width: 350px;
    padding: 40px 40px;
}

.btn {
    font-weight: 700;
    height: 36px;
    -moz-user-select: none;
    -webkit-user-select: none;
    user-select: none;
    cursor: default;
}

/*
 * Card component
 */
.card {
    background-color: #F7F7F7;
    /* just in case there no content*/
    padding: 20px 25px 30px;
    margin: 0 auto 25px;
    margin-top: 50px;
    /* shadows and rounded borders */
    -moz-border-radius: 2px;
    -webkit-border-radius: 2px;
    border-radius: 2px;
    -moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
    -webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
    box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
}

.profile-img-card {
    width: 96px;
    height: 96px;
    margin: 0 auto 10px;
    display: block;
    -moz-border-radius: 50%;
    -webkit-border-radius: 50%;
    border-radius: 50%;
}

/*
 * Form styles
 */
.profile-name-card {
    font-size: 16px;
    font-weight: bold;
    text-align: center;
    margin: 10px 0 0;
    min-height: 1em;
}

.reauth-email {
    display: block;
    color: #404040;
    line-height: 2;
    margin-bottom: 10px;
    font-size: 14px;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
}

.form-signin #inputEmail,
.form-signin #inputPassword {
    direction: ltr;
    height: 44px;
    font-size: 16px;
}

.form-signin input[type=email],
.form-signin input[type=password],
.form-signin input[type=text],
.form-signin button {
    width: 100%;
    display: block;
    margin-bottom: 10px;
    z-index: 1;
    position: relative;
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
}

.form-signin .form-control:focus {
    border-color: rgb(104, 145, 162);
    outline: 0;
    -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgb(104, 145, 162);
    box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgb(104, 145, 162);
}

.btn.btn-signin {
    /*background-color: #4d90fe; */
    background-color: rgb(104, 145, 162);
    /* background-color: linear-gradient(rgb(104, 145, 162), rgb(12, 97, 33));*/
    padding: 0px;
    font-weight: 700;
    font-size: 14px;
    height: 36px;
    -moz-border-radius: 3px;
    -webkit-border-radius: 3px;
    border-radius: 3px;
    border: none;
    -o-transition: all 0.218s;
    -moz-transition: all 0.218s;
    -webkit-transition: all 0.218s;
    transition: all 0.218s;
}

.btn.btn-signin:hover,
.btn.btn-signin:active,
.btn.btn-signin:focus {
    background-color: rgb(12, 97, 33);
}

.forgot-password {
    color: rgb(104, 145, 162);
}

.forgot-password:hover,
.forgot-password:active,
.forgot-password:focus{
    color: rgb(12, 97, 33);
}
import {ComponentAnnotation as Component, ViewAnnotation as View, bootstrap} from 'angular2/angular2';
import {NgIf} from 'angular2/directives';
import {FormBuilder, Validators, formDirectives, ControlGroup, ControlDirective} from 'angular2/forms';
import {CustomValidators} from 'validators';

@Component({
  selector: 'form-app',
  appInjector: [FormBuilder, CustomValidators]
})
@View({
  templateUrl: 'form.html',
  directives: [formDirectives, NgIf]
})
class FormApp {
  form: ControlGroup;
  constructor(builder: FormBuilder, custom: CustomValidators) {
    this.login = builder.group({
      // controlName: [initValue, Validators, { modelOptions ?}]
      // couldn't figure out how to use modelOptions like debounce yet.
      email: ['', custom.email],
      password: ['', custom.password],
      remember: [false]
    });
  }
  submit() {
    if(this.login.valid) {
      alert('logging in!');
    }
  }
}

bootstrap(FormApp);


/* form validation models
  * value: any
  * status: string
  * valid: boolean
  * errors: boolean
  * pristine: boolean
  * errors: StringMap
  * dirty: boolean
  * valueChanges: Observable
  * setParent(parent)
*/
<!-- input control group -->
<form class="form-signin" [control-group]="login">

<!-- input control -->
  <input control="email" type="email" class="form-control" placeholder="Email address" required autofocus>
  <!-- if valid -->
  <span *ng-if="!login.controls.email.valid">
        <p class="help-block">Invalid email.</p>
        </span>

  <!-- input control -->
  <input control="password" type="password" class="form-control" placeholder="Password" required>
  <!-- add minimum length validation message -->
  <span *ng-if="!login.controls.password.valid">
        <p class="help-block">Password must be 4 or more characters.</p>
        </span>

  <div id="remember" class="checkbox">
    <label>
      <!-- input control -->
      <input control="remember" type="checkbox" value="remember-me">Remember me
    </label>
  </div>

  <!-- disable unless form is valid -->
  <button class="btn btn-lg btn-primary btn-block btn-signin" 
    [disabled]="!login.valid" 
    (click)="submit()"
    type="submit">Sign in</button>
</form>
export class CustomValidators{
  // c: Control
  email(c) {
    var emailRegex = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/;
    if(!c.value.match(emailRegex)) {
      return {
        email: true
      };
    }
    // return null = valid
    return null;
  }
  password(c) {
    var minlength = 4;
    if(c.value.length < 4) {
      return {
        password: true
      };
    }
    return null;
  }
}