<!DOCTYPE html>
<html>

  <head>
    <title>angular2 playground</title>
    <link rel="stylesheet" href="style.css" />
    <script src="https://npmcdn.com/zone.js@0.6.12/dist/zone.js"></script>
    <script src="https://npmcdn.com/reflect-metadata@0.1.3/Reflect.js"></script>
    <script src="https://npmcdn.com/systemjs@0.19.31/dist/system.js"></script>
    <script src="https://npmcdn.com/typescript@1.8.10/lib/typescript.js"></script>
    
    <!-- <script src="https://npmcdn.com/@angular/core@2.0.0-rc.4/bundles/core.umd.min.js"></script>
    <script src="https://npmcdn.com/@angular/common@2.0.0-rc.4/bundles/common.umd.min.js"></script>
    <script src="https://npmcdn.com/@angular/compiler@2.0.0-rc.4/bundles/compiler.umd.min.js"></script>
    <script src="https://npmcdn.com/@angular/forms@2.0.0-rc.4/bundles/forms.umd.min.js"></script>
    <script src="https://npmcdn.com/@angular/platform-browser-dynamic@2.0.0-rc.4/bundles/platform-browser-dynamic.umd.min.js"></script>
    <script src="https://npmcdn.com/@angular/platform-browser@2.0.0-rc.4/bundles/platform-browser.umd.min.js"></script> -->
    
    <script src="config.js"></script>
    <script>
    System.import('app')
      .catch(console.error.bind(console));
  </script>
  </head>

  <body>
    <my-app>
    loading...
  </my-app>
  </body>

</html>
/* Styles go here */

p {
  margin: 0;
  display: inline-block;
}
### Angular2 Starter Plunker - Typescript - RC.0

A simple plunker demonstrating Angular2 usage:
- Uses SystemJS + TypeScript to compile on the fly
- Includes binding, directives, http, pipes, and DI usage.
System.config({
  //use typescript for compilation
  transpiler: 'typescript',
  //typescript compiler options
  typescriptOptions: {
    emitDecoratorMetadata: true
  },
  //map tells the System loader where to look for things
  map: {
    app: "./src",
    // '@angular': 'https://npmcdn.com/@angular',
    '@angular/core': 'https://npmcdn.com/@angular/core@2.0.0-rc.4',
    '@angular/compiler': 'https://npmcdn.com/@angular/compiler@2.0.0-rc.4',
    '@angular/common': 'https://npmcdn.com/@angular/common@2.0.0-rc.4',
    '@angular/forms': 'https://npmcdn.com/@angular/forms@0.3.0',
    '@angular/platform-browser-dynamic': 'https://npmcdn.com/@angular/platform-browser-dynamic@2.0.0-rc.4',
    '@angular/platform-browser': 'https://npmcdn.com/@angular/platform-browser@2.0.0-rc.4',
    'rxjs': 'https://npmcdn.com/rxjs@5.0.0-beta.6'
  },
  //packages defines our app package
  packages: {
    app: {
      main: './main.ts',
      defaultExtension: 'ts'
    },
    '@angular/core': {
      main: 'bundles/core.umd.js',
      defaultExtension: 'js'
    },
    '@angular/compiler': {
      main: 'bundles/compiler.umd.js',
      defaultExtension: 'js'
    },
    '@angular/common': {
      main: 'bundles/common.umd.js',
      defaultExtension: 'js'
    },
    '@angular/forms': {
      main: 'bundles/forms.umd.js',
      defaultExtension: 'js'
    },
    '@angular/platform-browser-dynamic': {
      main: 'bundles/platform-browser-dynamic.umd.js',
      defaultExtension: 'js'
    },
    '@angular/platform-browser': {
      main: 'bundles/platform-browser.umd.js',
      defaultExtension: 'js'
    },
    rxjs: {
      defaultExtension: 'js'
    }
  }
});
//main entry point
import {bootstrap} from '@angular/platform-browser-dynamic';
import { disableDeprecatedForms, provideForms } from '@angular/forms'
import {App} from './app';

bootstrap(App, [
  disableDeprecatedForms(),
  provideForms()
])
.catch(err => console.error(err));
//our root app component
import {Component} from '@angular/core'
import { REACTIVE_FORM_DIRECTIVES, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'

@Component({
  selector: 'my-app',
  directives: [REACTIVE_FORM_DIRECTIVES],
  template: `
    <div>
      <form [formGroup]="mainForm" (ngSubmit)="send()" novalidate style="border:1px solid grey; margin: 5px; padding: 5px">
        <h3>Main form</h3>
        <div [formGroup]="rangeForm" style="border:1px solid grey; margin: 5px; padding: 5px">
          <h3>Range form (subform)</h3>
          <label>
            Ranges:<br>
            <select formControlName="range">
                <option value="">Select a range</option> 
                <option *ngFor="let r of listRanges" [value]="r.id">{{ r.label }}</option> 
            </select>
          </label>
          <p *ngIf="rangeForm.controls.range.errors?.required" style="color:red;">Range required!</p>
          <br><br>
          <label>
            Specific value inside range (optionnal):<br>
            <input formControlName="specificValue" type="number"/>
          </label>
          <p *ngIf="rangeForm.errors?.outsideRange" style="color:red;">Value outside of the range!</p>
        </div>
        <br><br>
        <label>
          normal:<br>
          <input formControlName="inputNormal" type="text"/>
        </label>
        <br><br>
        <label>
          disabled:<br>
          <input formControlName="inputDisabled" type="text" disabled/>
        </label>
        <br><br>
        <label>
          readonly:<br>
          <input formControlName="inputReadonly" type="text" readonly/>
        </label>
        <br><br>
        <button type="submit" [disabled]="!mainForm.valid">SEND</button>
      </form>
    </div>
  `
})
export class App {
  public listRanges: Array<{id: number, label: string, min: number, max: number}>= [
    {id: 0, label: 'range A (11 > 56)', min: 11, max: 56},
    {id: 1, label: 'range B (690 > 1256)', min: 690, max: 1256},
    {id: 2, label: 'range C (6542 > 8956)', min: 6542, max: 8956},
    {id: 3, label: 'range D (11124 > 14656)', min: 11124, max: 14656}
  ]
  
  mainForm: FormGroup
  rangeForm: FormGroup
  
  constructor(public formBuilder: FormBuilder) {
    this.rangeForm = formBuilder.group({
      'range':          new FormControl('', Validators.required),
      'specificValue':  new FormControl(null)
    }, {
      validator: this.specificValueInsideRange.bind(this)
    });
    
    this.mainForm = formBuilder.group({
      'rangeForm': this.rangeForm,
      'inputNormal':    new FormControl('normal input'),
      'inputDisabled': new FormControl('disabled input'),
      'inputReadonly':  new FormControl('readonly input')
    });
  }
  
  send() {
    console.log('VALID=', this.mainForm.valid, ' >>', this.mainForm.value);
  }

  specificValueInsideRange(group: ControlGroup) {
    if(!group.controls.range || !group.controls.range.value || !group.controls.specificValue || !group.controls.specificValue.value) return;
    
    const range = this.listRanges.find(r => r.id === Number(group.value.range));
    if(range && (group.value.specificValue < range.min || group.value.specificValue > range.max)) {
      return {
        outsideRange: true
      };
    }
  }
  
}