<!DOCTYPE html>
<html>
<head>
<title>Angular 2 + TypeScript + Bootstrap 4</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/css/bootstrap.min.css" integrity="sha384-AysaV+vQoT3kOAXZkl02PThvDr8HYKPZhNT5h/CXfBThSRXQ6jW5DO2ekP5ViFdi" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
<script src="https://unpkg.com/core-js/client/shim.min.js"></script>
<script src="https://unpkg.com/zone.js@0.6.25?main=browser"></script>
<script src="https://unpkg.com/reflect-metadata@0.1.8"></script>
<script src="https://unpkg.com/systemjs@0.19.39/dist/system.src.js"></script>
<script src="https://cdn.rawgit.com/angular/angular.io/b3c65a9/public/docs/_examples/_boilerplate/systemjs.config.web.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
</head>
<body>
<app></app>
</body>
</html>
# Angular 2 + TypeScript + Bootstrap 4 (Updated)
## A simple Angular 2 example with ES6, Router, TypeScript, and Form Validation.
Current Version: Angular v2.2.4
Last Updated: Dec 16, 2016
Created By: https://github.com/daveboling
This template contains common use cases and examples similar to those typically
used in Angular 1.
Did I do something bad or forget to update something? **Lemme know!**
*The world is your playground. Why aren't you playing?*
import { Component } from '@angular/core';
@Component({
selector: 'app',
templateUrl: './app/app.html'
})
export class AppComponent {}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule, Routes } from '@angular/router';
import { ReactiveFormsModule } from '@angular/forms';
import { APP_BASE_HREF } from '@angular/common';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { ExampleFormComponent } from './forms/example-form.component';
const appRoutes: Routes = [
{ path: 'forms', component: ExampleFormComponent },
{ path: '', component: HomeComponent },
];
@NgModule({
imports: [
BrowserModule,
ReactiveFormsModule ,
RouterModule.forRoot(appRoutes)
],
declarations: [
AppComponent,
HomeComponent,
ExampleFormComponent,
],
providers: [
{ provide: APP_BASE_HREF, useValue: location.pathname }, // This is specifically for Plunker's baseURL: run.plunkr.co
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
<nav class="navbar navbar-light bg-faded">
<ul class="nav navbar-nav">
<li class="nav-item">
<a class="nav-link" routerLink="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/forms">Example Form</a>
</li>
</ul>
</nav>
<main class='container'>
<router-outlet></router-outlet>
</main>
import { Component } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { emailValidator, matchingPasswords } from '../../app/validators/validators';
@Component({
selector: 'example-form',
templateUrl: './app/forms/example-form.html'
})
export class ExampleFormComponent {
registrationForm: FormGroup;
constructor(public fb: FormBuilder) {
// Example use of FormBuilder, FormGroups, and FormControls
this.registrationForm = fb.group({
dob: ['', Validators.required],
email: ['', Validators.compose([Validators.required, emailValidator])],
password: ['', Validators.required],
confirmPassword: ['', Validators.required],
firstName: ['', Validators.required],
lastName: ['', Validators.required]
}, {validator: matchingPasswords('password', 'confirmPassword')})
}
submitRegistration(value: Object): void {
console.log(value);
}
}
<div class='row'>
<div class='col-xs-12'>
<h2>Registration Form</h2>
<form [formGroup]="registrationForm" (ngSubmit)="registrationForm.valid && submitRegistration(registrationForm.value)" novalidate>
<fieldset class="form-group">
<label for="dob">Date of Birth</label>
<input type="text" class="form-control" placeholder="Date of Birth" formControlName="dob">
<div class='form-text error' *ngIf="registrationForm.controls.dob.touched">
<div *ngIf="registrationForm.controls.dob.hasError('required')">Date of birth is required.</div>
</div>
</fieldset>
<fieldset class="form-group">
<label for="e-mail">E-Mail</label>
<input type="email" class="form-control" placeholder="E-mail" formControlName="email">
<div class="form-text error" *ngIf="registrationForm.controls.email.touched">
<div *ngIf="registrationForm.controls.email.hasError('required')">Email is required.</div>
<div *ngIf="registrationForm.controls.email.hasError('invalidEmail')">Email is invalid.</div>
</div>
</fieldset>
<fieldset class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" placeholder="Password" minlength='6' formControlName="password">
<div class='form-text error' *ngIf="registrationForm.controls.password.touched">
<div *ngIf="registrationForm.controls.password.hasError('required')">Password is required.</div>
<div *ngIf="registrationForm.controls.password.hasError('minlength')">Password isn't long enough.</div>
</div>
</fieldset>
<fieldset class="form-group">
<label for="confirm-password">Confirm Password</label>
<input type="password" class="form-control" placeholder="Confirm Password" formControlName="confirmPassword">
<div class='form-text error' *ngIf="registrationForm.controls.confirmPassword.touched">
<div *ngIf="registrationForm.hasError('mismatchedPasswords')">Passwords do not match.</div>
</div>
</fieldset>
<fieldset class="form-group">
<label for="first-name">First Name</label>
<input type="text" class="form-control" placeholder="First Name" formControlName="firstName">
<div class='form-text error' *ngIf='registrationForm.controls.firstName.touched'>
<div *ngIf="registrationForm.controls.firstName.hasError('required')">First name is required.</div>
</div>
</fieldset>
<fieldset class="form-group">
<label for="last-name">Last Name</label>
<input type="text" class="form-control" placeholder="Last Name" formControlName="lastName">
<div class='form-text error' *ngIf='registrationForm.controls.lastName.touched'>
<div *ngIf="registrationForm.controls.lastName.hasError('required')">Last name is required.</div>
</div>
</fieldset>
<button class='btn btn-primary' type='submit' [disabled]='!registrationForm.valid'>Submit Registration Form</button>
</form>
<pre>{{registrationForm.value | json}}</pre>
</div>
</div>
/*
Custom validators to use everywhere.
*/
// SINGLE FIELD VALIDATORS
export function emailValidator(control: FormControl): {[key: string]: any} {
var emailRegexp = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
if (control.value && !emailRegexp.test(control.value)) {
return { invalidEmail: true };
}
}
// FORM GROUP VALIDATORS
export function matchingPasswords(passwordKey: string, confirmPasswordKey: string) {
return (group: FormGroup): {[key: string]: any} => {
let password = group.controls[passwordKey];
let confirmPassword = group.controls[confirmPasswordKey];
if (password.value !== confirmPassword.value) {
return {
mismatchedPasswords: true
};
}
}
}
app {
.error {
color: #FF4500;
font-size: small;
}
}
import { Component } from '@angular/core';
@Component({
selector: 'home',
directives: [],
template: `<div></div>`
})
export class HomeComponent {}