<!DOCTYPE html>
<html>

<head>
  <base href="." />
  <script type="text/javascript" charset="utf-8">
    window.AngularVersionForThisPlunker = 'latest'
  </script>
  <title>angular - By Advancesharp.com</title>
  <link rel="stylesheet" href="style.css" />
  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
  
  <script src="https://unpkg.com/core-js@2.4.1/client/shim.min.js"></script>
  <script src="https://unpkg.com/zone.js/dist/zone.js"></script>
  <script src="https://unpkg.com/zone.js/dist/long-stack-trace-zone.js"></script>
  <script src="https://unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script>
  <script src="https://unpkg.com/systemjs@0.19.31/dist/system.js"></script>
  <script src="config.js"></script>
  <script>
    System.import('app')
      .catch(console.error.bind(console));
  </script>
</head>
<br>

<body class='container'>
  <h3>By <a href='http://www.advancesharp.com/blog/1214/angular-2-dynamically-add-remove-components'>Advancesharp.com</a> </h3>
  <my-app>
    loading...
  </my-app>
</body>

</html>

.row{
    margin-bottom: 10px;
}
input, button, .btn{border-radius: 0px  !important;}
input[type='text'].ng-invalid,
input[type='password'].ng-invalid{border-left: 1px solid #700;}
var angularVersion;
if(window.AngularVersionForThisPlunker === 'latest'){
  angularVersion = ''; //picks up latest
}
else {
  angularVersion = '@' + window.AngularVersionForThisPlunker;
}

System.config({
  //use typescript for compilation
  transpiler: 'typescript',
  //typescript compiler options
  typescriptOptions: {
    emitDecoratorMetadata: true
  },
  paths: {
    'npm:': 'https://unpkg.com/'
  },
  //map tells the System loader where to look for things
  map: {
    
    'app': './src',
    '@angular/core': 'npm:@angular/core'+ angularVersion + '/bundles/core.umd.js',
    '@angular/common': 'npm:@angular/common' + angularVersion + '/bundles/common.umd.js',
    '@angular/compiler': 'npm:@angular/compiler' + angularVersion  + '/bundles/compiler.umd.js',
    '@angular/platform-browser': 'npm:@angular/platform-browser' + angularVersion + '/bundles/platform-browser.umd.js',
    '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic' + angularVersion + '/bundles/platform-browser-dynamic.umd.js',
    '@angular/http': 'npm:@angular/http' + angularVersion + '/bundles/http.umd.js',
    '@angular/router': 'npm:@angular/router' + angularVersion +'/bundles/router.umd.js',
    '@angular/forms': 'npm:@angular/forms' + angularVersion + '/bundles/forms.umd.js',
    '@angular/animations': 'npm:@angular/animations' + angularVersion + '/bundles/animations.umd.js',
    '@angular/platform-browser/animations': 'npm:@angular/platform-browser' + angularVersion + '/bundles/platform-browser-animations.umd.js',
    '@angular/animations/browser': 'npm:@angular/animations' + angularVersion + '/bundles/animations-browser.umd.js',
    
    '@angular/core/testing': 'npm:@angular/core' + angularVersion + '/bundles/core-testing.umd.js',
    '@angular/common/testing': 'npm:@angular/common' + angularVersion + '/bundles/common-testing.umd.js',
    '@angular/compiler/testing': 'npm:@angular/compiler' + angularVersion + '/bundles/compiler-testing.umd.js',
    '@angular/platform-browser/testing': 'npm:@angular/platform-browser' + angularVersion + '/bundles/platform-browser-testing.umd.js',
    '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic' + angularVersion + '/bundles/platform-browser-dynamic-testing.umd.js',
    '@angular/http/testing': 'npm:@angular/http' + angularVersion + '/bundles/http-testing.umd.js',
    '@angular/router/testing': 'npm:@angular/router' + angularVersion + '/bundles/router-testing.umd.js',
    'tslib': 'npm:tslib@1.6.1',
    'rxjs': 'npm:rxjs',
    'typescript': 'npm:typescript@2.2.1/lib/typescript.js'
  },
  //packages defines our app package
  packages: {
    app: {
      main: './main.ts',
      defaultExtension: 'ts'
    },
    rxjs: {
      defaultExtension: 'js'
    }
  }
});
import {NgModule} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import {Router} from '@angular/router'

import { AppComponent } from './app/app.component';

    
@NgModule({
  imports: [
    BrowserModule, FormsModule, ReactiveFormsModule 
  ],
  declarations: [ AppComponent ],
  exports: [],
  bootstrap: [ AppComponent ]
})
export class AppModule {}

//main entry point
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';


platformBrowserDynamic().bootstrapModule(AppModule)

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';


@Component({
  selector: 'my-app',
  templateUrl: './src/app/app.component.html'
})
export class AppComponent implements OnInit{ 
   register: FormGroup;
   isSubmitted: boolean = false;
   result: any = null;
   constructor(private frmBuilder: FormBuilder) { }
   
   ngOnInit(){
     this.register = this.frmBuilder.group({
       name:["", [Validators.required, Validators.minLength(3),Validators.maxLength(15)]],
       email:["", [Validators.required]],
       password:["", [Validators.required]],
       verify:["", [Validators.required]]
     });
   }
   
   get name() { return this.register.get('name'); }
   get email() { return this.register.get('email'); }
   get password() { return this.register.get('password'); }
   get verify() { return this.register.get('verify'); }
  
   
   save(){
     this.isSubmitted = true;
     if(!this.register.valid)
         return;
     // Code to save the data
     // userService.Save(this.register.value);
     this.result = this.register.value;
      setTimeout(()=> {
       this.result = null;
       this.reset();
      }, 2000);
   }
   
   reset(){
     this.isSubmitted = false;
     this.register.reset();
     
   }
}


<h3>Registration</h3>
<hr />
<form [formGroup]='register' (ngSubmit)='save()' novalidate>
    <div class='row'>
      <div class='col-sm-6'>
        <input type='text' formControlName='name'
               class='form-control'
               placeholder='Display Name'>
        
      	<div *ngIf="name.invalid && (name.dirty || isSubmitted)" class="text-danger">
      	  <div *ngIf="name.errors.required">
      		Name is required.
      	  </div>
      	  <div *ngIf="name.errors.minlength">
      		Name must be at least 4 characters long.
      	  </div>
      	  <div *ngIf="name.errors.maxlength">
      		Name must not exceed 15 characters.
      	  </div>
      	</div>
      </div>
    </div>
    
    <div class='row'>
      <div class='col-sm-6'>
        <input type='text' formControlName='email'
               class='form-control'
               placeholder='Email'>
               
        <div *ngIf="email.invalid && (email.dirty || isSubmitted)" class="text-danger">
      		Email is required.
      	</div>
      </div>
    </div>
    
    <div class='row'>
      <div class='col-sm-6'>
        <input type='password' formControlName='password'
               class='form-control'
               placeholder='Password'>
               
        <div *ngIf="password.invalid && (password.dirty || isSubmitted)" class="text-danger">
      		Password is required.
      	</div>
      </div>
    </div>
    
    
    <div class='row'>
      <div class='col-sm-6'>
        <input type='password' formControlName='verify'
               class='form-control'
               placeholder='Verify Password'>
               
        <div *ngIf="verify.invalid && (verify.dirty || isSubmitted == true)" class="text-danger">
      		Verify Password is required.
      	</div>
      </div>
    </div>
    
    <div class='row'>
      <div class='col-sm-6'>
        <button type='submit' class='btn btn-primary'>Save</button>
        <button type='button' class='btn btn-warning' (click)='reset()'>Reset</button>
      </div>
    </div>
</form>

<pre *ngIf='result != null'>
  {{result | json}}
</pre>




import { Validator } from '@angular/forms';


@Directive({
  selector: '[advs-compare]',
  providers: [{provide: NG_VALIDATORS, useExisting: CompareDirective, multi: true}]
})
class CompareDirective implements Validator {
  
  
  ///constructor(@Attribute('advs-compare') public compare: string){ }
  
  validate(c: Control): {[key: string]: any} {
    debugger;
    let e = c.root.get('advs-compare');
    if(e && c.value !== e.value){
      return {"compare": true};
    }
    return null;
  }
 
}