import { Component, Input, Output, EventEmitter } from '@angular/core';
import { Validators, FormGroup, FormControl } from '@angular/forms';
import { Product } from './model';
@Component({
selector: 'kendo-grid-edit-form',
styles: [`
.ng-valid { border-left: 5px solid #42a948; }
.ng-invalid { border-left: 5px solid #a94442; }
form.ng-invalid { border-left: 0; }
.invalid { color: #a94442; }
`],
template: `
<kendo-dialog *ngIf="active" title="Edit" (close)="onCancel()">
<form [formGroup]="editForm">
<div>
<label for="ProductName">ProductName</label>
<input type="text" formControlName="ProductName" [(ngModel)]="dataItem.ProductName" />
<div [hidden]="editForm.controls.ProductName.valid || editForm.controls.ProductName.pristine" class="invalid">
ProductName is required
</div>
</div>
<div>
<label for="UnitPrice">UnitPrice</label>
<input type="text" formControlName="UnitPrice" [(ngModel)]="dataItem.UnitPrice"/>
</div>
<div>
<label for="Discontinued">Discontinued</label>
<input type="checkbox" formControlName="Discontinued" [(ngModel)]="dataItem.Discontinued"/>
</div>
<div>
<label for="UnitsInStock">UnitsInStock</label>
<input type="text" formControlName="UnitsInStock" [(ngModel)]="dataItem.UnitsInStock"/>
<div [hidden]="editForm.controls.UnitsInStock.valid || editForm.controls.UnitsInStock.pristine" class="invalid">
UnitsInStock must be between 0 and 99
</div>
</div>
<div>
<label for="gender">Select gender</label>
<kendo-combobox
formControlName="gender"
[data]="genders"
[textField]="'text'"
[valueField]="'value'"
[valuePrimitive]="true"
>
</kendo-combobox>
</div>
</form>
<kendo-dialog-actions>
<button class="k-button" (click)="onCancel()">Cancel</button>
<button class="k-button k-primary" [disabled]="!editForm.valid" (click)="onSave()">Save</button>
</kendo-dialog-actions>
</kendo-dialog>
`
})
export class GridEditFormComponent {
dataItem;
editForm;
@Input() public set model (product: Product) {
this.dataItem = product;
product === undefined ? this.active = false: this.active = true;
}
@Output() cancel: EventEmitter<any> = new EventEmitter();
@Output() save: EventEmitter<any> = new EventEmitter();
constructor() {
this.editForm = new FormGroup({
'ProductName': new FormControl("", Validators.required),
'UnitPrice': new FormControl(),
'UnitsInStock': new FormControl("", Validators.compose([Validators.required, Validators.pattern('^[0-9]{1,2}')])),
'Discontinued': new FormControl(false),
'gender': new FormControl()
})
}
public active: boolean = false;
public genders: Array<{ text: string, value: number }> = [
{ text: "Male", value: 1 },
{ text: "Female", value: 2 }
];
public onSave(): void {
this.save.emit(this.dataItem);
this.active = false;
return false;
}
public onCancel(): void {
this.active = false;
this.cancel.emit(undefined);
return false;
}
public addProduct() {
this.model = new Product();
this.active = true;
}
}
export class Product {
constructor(
public ProductID?: number,
public ProductName?: string,
public Discountinued?: boolean,
public UnitsInStock?: number
) { }
}
import { Component, ViewChild } from '@angular/core';
import { Jsonp } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/switchMap';
import { Product } from './model';
import { GridEditFormComponent } from './edit-form.component';
@Component({
selector: 'my-app',
template: `
<kendo-grid [data]="view" [height]="400">
<kendo-grid-toolbar>
<button (click)="addProduct()" class="k-button k-button-icontext k-grid-add">Add new</button>
</kendo-grid-toolbar>
<kendo-grid-column field="ProductName"></kendo-grid-column>
<kendo-grid-column field="UnitPrice" title="UnitPrice"></kendo-grid-column>
<kendo-grid-column field="Discontinued" title="Discontinued"></kendo-grid-column>
<kendo-grid-column field="UnitsInStock" title="Units In Stock"></kendo-grid-column>
<kendo-grid-column>
<template kendoCellTemplate let-dataItem>
<button (click)="onEdit(dataItem)" class="k-button k-button-icontext k-grid-edit">Edit</button>
<button (click)="onDelete(dataItem)" class="k-button k-button-icontext k-grid-delete">Delete</button>
</template>
</kendo-grid-column>
</kendo-grid>
<kendo-grid-edit-form [model]="dataItem" (cancel)="onCancel()" (save)="onSave($event)">
</kendo-grid-edit-form>
`
})
export class AppComponent {
public dataItem: Product;
@ViewChild(GridEditFormComponent) protected editFormComponent: GridEditFormComponent;
private view: Array<Product>;
constructor(private jsonp: Jsonp) {
this.getProducts()
.subscribe(data => this.view = data);
}
public onEdit(dataItem: any): void {
this.dataItem = dataItem;
}
public onCancel(): void {
this.dataItem = undefined;
}
public addProduct(): void {
this.editFormComponent.addProduct();
}
public onSave(product: Product): void {
const operation = product.ProductID === undefined ?
this.createProduct(product) :
this.saveProducts(product);
operation.switchMap(x => this.getProducts())
.subscribe((response: Product[]) => {
this.view = response;
});
}
public onDelete(e: Product): void {
this.deleteProduct(e)
.switchMap(x => this.getProducts())
.subscribe((response: Product[]) => {
this.view = response;
});
}
public getProducts(): Observable<Product[]> {
return this.fetch();
}
public saveProducts(data: Product): Observable<Product[]> {
return this.fetch("update", data);
}
public createProduct(data: Product): Observable<Product[]> {
data.ProductID = null;
return this.fetch("create", data);
}
public deleteProduct(data: Product): Observable<Product[]> {
return this.fetch("destroy", data);
}
private fetch(action: string = "", data?: Product): Observable<Product[]> {
return this.jsonp
.get(`http://demos.telerik.com/kendo-ui/service/Products/${action}?callback=JSONP_CALLBACK${this.serializeModels(data)}`)
.map(response => response.json());
}
private serializeModels(data?: Product): string {
return data ? `&models=${JSON.stringify([data])}` : '';
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule, JsonpModule } from '@angular/http';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { DialogModule } from '@progress/kendo-angular-dialog';
import { GridModule } from '@progress/kendo-angular-grid';
import { DropDownsModule } from '@progress/kendo-angular-dropdowns';
import { AppComponent } from './app.component';
import { GridEditFormComponent } from './edit-form.component';
@NgModule({
imports: [
BrowserModule,
HttpModule,
JsonpModule,
FormsModule,
ReactiveFormsModule,
GridModule,
DialogModule,
DropDownsModule
],
declarations: [
AppComponent,
GridEditFormComponent
],
bootstrap: [
AppComponent
]
})
export class AppModule { }
import { AppModule } from './ng.module';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);
<!DOCTYPE html>
<html>
<head>
<title>Angular 2 QuickStart</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://www.telerik.com/kendo-angular-ui/npm/node_modules//@telerik/kendo-theme-default/dist/all.css" />
<!-- 1. Load libraries -->
<!-- Polyfill(s) for older browsers -->
<script src="https://unpkg.com/core-js/client/shim.min.js"></script>
<script src="https://unpkg.com/zone.js@0.6.23?main=browser"></script>
<script src="https://unpkg.com/reflect-metadata@0.1.3"></script>
<script src="https://unpkg.com/systemjs@0.19.27/dist/system.src.js"></script>
<!-- 2. Configure SystemJS -->
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
</head>
<!-- 3. Display the application -->
<body>
<my-app>Loading...</my-app>
</body>
</html>
(function (global) {
var angularVersion = '2.0.0';
System.config({
// DEMO ONLY! REAL CODE SHOULD NOT TRANSPILE IN THE BROWSER
transpiler: 'ts',
typescriptOptions: {
tsconfig: 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',
'@progress': 'http://www.telerik.com/kendo-angular-ui/npm/node_modules/@progress',
'@telerik': 'http://www.telerik.com/kendo-angular-ui/npm/node_modules/@telerik',
// angular bundles
'@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/http/testing': 'npm:@angular/http@' + angularVersion +'/bundles/http-testing.umd.js',
'@angular/forms': 'npm:@angular/forms@' + angularVersion + '/bundles/forms.umd.js',
'@angular/router': 'npm:@angular/router@3.0.0-rc.3/bundles/router.umd.js',
// other libraries
'rxjs': 'npm:rxjs',
'chroma-js': 'npm:chroma-js@1.2.1',
'angular2-in-memory-web-api': 'npm:angular2-in-memory-web-api',
'ts': 'npm:plugin-typescript@4.0.10/lib/plugin.js',
'typescript': 'npm:typescript@1.9.0-dev.20160409/lib/typescript.js'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
"@progress/kendo-angular-grid": {"main":"dist/cdn/js/kendo-angular-grid.js","defaultExtension":"js"},
"@progress/kendo-angular-dialog": {"main":"dist/cdn/js/kendo-angular-dialog.js","defaultExtension":"js"},
"@progress/kendo-angular-dropdowns": {"main":"dist/cdn/js/kendo-angular-dropdowns.js","defaultExtension":"js"},
app: {
main: './main.ts',
defaultExtension: 'ts'
},
rxjs: {
defaultExtension: 'js'
},
'angular2-in-memory-web-api': {
main: './index.js',
defaultExtension: 'js'
}
}
});
})(this);
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
}
}