<!DOCTYPE html>
<!--suppress ALL -->
<html>
<head>
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/css/bootstrap.min.css">
<script src="https://unpkg.com/core-js/client/shim.min.js"></script>
<script src="https://unpkg.com/zone.js@0.7.4?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="systemjs.config.js"></script>
<script>
System.import('script.ts').catch(function (err) {
console.error(err);
});
</script>
</head>
<body class="container m-t-1">
<app>Loading...</app>
</body>
</html>
import {
NgModule,
Component,
OnInit,
ViewChild
} from '@angular/core';
import {
FormsModule,
FormGroup,
FormControl
} from '@angular/forms';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
class Signup {
constructor(public firstName: string = '',
public lastName: string = '',
public email: string = '',
public password: string = '',
public language: string = '') {
}
}
@Component({
selector: 'template-form',
template: `<!--suppress ALL -->
<form novalidate
(ngSubmit)="onSubmit()"
#f="ngForm">
<fieldset ngModelGroup="name">
<div class="form-group"
[ngClass]="{
'has-danger': firstName.invalid && (firstName.dirty || firstName.touched),
'has-success': firstName.valid && (firstName.dirty || firstName.touched)
}">
<label>First Name</label>
<input type="text"
class="form-control"
name="firstName"
[(ngModel)]="model.firstName"
required
#firstName="ngModel">
<div class="form-control-feedback"
*ngIf="firstName.errors && (firstName.dirty || firstName.touched)">
<p *ngIf="firstName.errors.required">First name is required</p>
</div>
</div>
<div class="form-group"
[ngClass]="{
'has-danger': lastName.invalid && (lastName.dirty || lastName.touched),
'has-success': lastName.valid && (lastName.dirty || lastName.touched)
}">
<label>Last Name</label>
<input type="text"
class="form-control"
name="lastName"
[(ngModel)]="model.lastName"
required
#lastName="ngModel">
<div class="form-control-feedback"
*ngIf="lastName.errors && (lastName.dirty || lastName.touched)">
<p *ngIf="lastName.errors.required">Last name is required</p>
</div>
</div>
</fieldset>
<div class="form-group"
[ngClass]="{
'has-danger': email.invalid && (email.dirty || email.touched),
'has-success': email.valid && (email.dirty || email.touched)
}">
<label>Email</label>
<input type="email"
class="form-control"
name="email"
[(ngModel)]="model.email"
required
pattern="[^ @]*@[^ @]*"
#email="ngModel">
<div class="form-control-feedback"
*ngIf="email.errors && (email.dirty || email.touched)">
<p *ngIf="email.errors.required">Email is required</p>
<p *ngIf="email.errors.pattern">Email must contain at least the @ character</p>
</div>
</div>
<div class="form-group"
[ngClass]="{
'has-danger': password.invalid && (password.dirty || password.touched),
'has-success': password.valid && (password.dirty || password.touched)
}">
<label>Password</label>
<input type="password"
class="form-control"
name="password"
[(ngModel)]="model.password"
required
minlength="8"
#password="ngModel">
<div class="form-control-feedback"
*ngIf="password.errors && (password.dirty || password.touched)">
<p *ngIf="password.errors.required">Password is required</p>
<p *ngIf="password.errors.minlength">Password must be at least 8 characters long</p>
</div>
</div>
<div class="form-group">
<label>Language</label>
<select class="form-control"
name="language"
[(ngModel)]="model.language">
<option value="">Please select a language</option>
<option *ngFor="let lang of langs"
[value]="lang">{{lang}}
</option>
</select>
</div>
<button type="submit"
class="btn btn-primary"
[disabled]="f.invalid">Submit
</button>
<pre>{{f.value | json}}</pre>
</form>
`
})
class TemplateFormComponent {
model: Signup = new Signup();
@ViewChild('f') form: any;
langs: string[] = [
'English',
'French',
'German',
];
onSubmit() {
if (this.form.valid) {
console.log("Form Submitted!");
this.form.reset();
}
}
}
@Component({
selector: 'app',
template: `<template-form></template-form>`
})
class AppComponent {
}
@NgModule({
imports: [
BrowserModule,
FormsModule
],
declarations: [
AppComponent,
TemplateFormComponent
],
bootstrap: [
AppComponent
],
})
class AppModule {
}
platformBrowserDynamic().bootstrapModule(AppModule);
/**
* WEB ANGULAR VERSION
* (based on systemjs.config.js in angular.io)
* System configuration for Angular samples
* Adjust as necessary for your application needs.
*/
(function(global) {
System.config({
// DEMO ONLY! REAL CODE SHOULD NOT TRANSPILE IN THE BROWSER
transpiler: "ts",
typescriptOptions: {
// Copy of compiler options in standard tsconfig.json
target: "es5",
module: "commonjs",
moduleResolution: "node",
sourceMap: true,
emitDecoratorMetadata: true,
experimentalDecorators: true,
lib: ["es2015", "dom"],
noImplicitAny: true,
suppressImplicitAnyIndexErrors: true
},
meta: {
typescript: {
exports: "ts"
}
},
paths: {
// paths serve as alias
"npm:": "https://unpkg.com/"
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
app: "app",
// angular bundles
"@angular/animations":
"npm:@angular/animations@5/bundles/animations.umd.js",
"@angular/animations/browser":
"npm:@angular/animations@5/bundles/animations-browser.umd.js",
"@angular/core": "npm:@angular/core@5/bundles/core.umd.js",
"@angular/common": "npm:@angular/common@5/bundles/common.umd.js",
"@angular/common/http":
"npm:@angular/common@5/bundles/common-http.umd.js",
"@angular/compiler": "npm:@angular/compiler@5/bundles/compiler.umd.js",
"@angular/platform-browser":
"npm:@angular/platform-browser@5/bundles/platform-browser.umd.js",
"@angular/platform-browser/animations":
"npm:@angular/platform-browser@5/bundles/platform-browser-animations.umd.js",
"@angular/platform-browser-dynamic":
"npm:@angular/platform-browser-dynamic@5/bundles/platform-browser-dynamic.umd.js",
"@angular/http": "npm:@angular/http@5/bundles/http.umd.js",
"@angular/router": "npm:@angular/router@5/bundles/router.umd.js",
"@angular/router/upgrade":
"npm:@angular/router@5/bundles/router-upgrade.umd.js",
"@angular/forms": "npm:@angular/forms@5/bundles/forms.umd.js",
"@angular/upgrade": "npm:@angular/upgrade@5/bundles/upgrade.umd.js",
"@angular/upgrade/static":
"npm:@angular/upgrade@5/bundles/upgrade-static.umd.js",
// other libraries
rxjs: "npm:rxjs@5.5.3",
"rxjs/operators": "npm:rxjs@5.5.3/operators/index.js",
tslib: "npm:tslib/tslib.js",
"angular-in-memory-web-api":
"npm:angular-in-memory-web-api@0.4@5/bundles/in-memory-web-api.umd.js",
ts: "npm:plugin-typescript@5.2.7/lib/plugin.js",
typescript: "npm:typescript@2.4.2/lib/typescript.js"
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
main: "./main.ts",
defaultExtension: "ts",
meta: {
"./*.ts": {
loader: "systemjs-angular-loader.js"
}
}
},
rxjs: {
defaultExtension: "js"
}
}
});
})(this);
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [
"es2015",
"dom"
],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"typeRoots": [
"../node_modules/@types/"
]
},
"compileOnSave": true,
"exclude": [
"node_modules/*",
"**/*-aot.ts"
]
}
var templateUrlRegex = /templateUrl\s*:(\s*['"`](.*?)['"`]\s*)/gm;
var stylesRegex = /styleUrls *:(\s*\[[^\]]*?\])/g;
var stringRegex = /(['`"])((?:[^\\]\\\1|.)*?)\1/g;
module.exports.translate = function(load){
if (load.source.indexOf('moduleId') != -1) return load;
var url = document.createElement('a');
url.href = load.address;
var basePathParts = url.pathname.split('/');
basePathParts.pop();
var basePath = basePathParts.join('/');
var baseHref = document.createElement('a');
baseHref.href = this.baseURL;
baseHref = baseHref.pathname;
if (!baseHref.startsWith('/base/')) { // it is not karma
basePath = basePath.replace(baseHref, '');
}
load.source = load.source
.replace(templateUrlRegex, function(match, quote, url){
var resolvedUrl = url;
if (url.startsWith('.')) {
resolvedUrl = basePath + url.substr(1);
}
return 'templateUrl: "' + resolvedUrl + '"';
})
.replace(stylesRegex, function(match, relativeUrls) {
var urls = [];
while ((match = stringRegex.exec(relativeUrls)) !== null) {
if (match[2].startsWith('.')) {
urls.push('"' + basePath + match[2].substr(1) + '"');
} else {
urls.push('"' + match[2] + '"');
}
}
return "styleUrls: [" + urls.join(', ') + "]";
});
return load;
};
export class Category {
name: string;
}