import { Component, ViewChild } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import {
GridComponent,
GridDataResult,
DataStateChangeEvent
} from '@progress/kendo-angular-grid';
import { SortDescriptor } from '@progress/kendo-data-query';
import { CategoriesService } from './northwind.service';
@Component({
providers: [CategoriesService],
selector: 'my-app',
template: `
<kendo-grid
[data]="view | async"
[pageSize]="pageSize"
[skip]="skip"
[sortable]="true"
[sort]="sort"
[pageable]="true"
[height]="550"
(dataStateChange)="dataStateChange($event)"
(detailCollapse)="onCollapsesClick($event)"
(detailExpand)="onExpandClick($event)"
>
<kendo-grid-column field="CategoryID" width="100"></kendo-grid-column>
<kendo-grid-column field="CategoryName" width="200" title="Category Name"></kendo-grid-column>
<kendo-grid-column field="Description" [sortable]="false">
</kendo-grid-column>
<div *kendoGridDetailTemplate="let dataItem">
<category-details [category]="dataItem"></category-details>
</div>
</kendo-grid>
`
})
export class AppComponent {
public view: Observable<GridDataResult>;
public sort: Array<SortDescriptor> = [];
public pageSize: number = 10;
public skip: number = 0;
@ViewChild(GridComponent) grid: GridComponent;
constructor(private service: CategoriesService) { }
public ngOnInit(): void {
// Bind directly to the service as it is a Subject
this.view = this.service;
// Fetch the data with the initial state
this.loadData();
}
public onCollapsesClick(event) {
console.log('collapse', event);
}
public onExpandClick(event) {
console.log('expand', event);
}
public dataStateChange({ skip, take, sort }: DataStateChangeEvent): void {
// Save the current state of the Grid component
this.skip = skip;
this.pageSize = take;
this.sort = sort;
// Reload the data with the new state
this.loadData();
}
public ngAfterViewInit(): void {
// Expand the first row initially
this.grid.expandRow(0);
}
private loadData(): void {
this.service.query({ skip: this.skip, take: this.pageSize, sort: this.sort });
}
}
import { Component, ViewChild, Input, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { GridDataResult, GridComponent, PageChangeEvent } from '@progress/kendo-angular-grid';
import { ProductsService } from './northwind.service';
@Component({
selector: 'category-details',
providers: [ProductsService],
template: `
<kendo-grid
[data]="view | async"
[pageSize]="5"
[skip]="skip"
[pageable]="true"
[scrollable]="'none'"
(pageChange)="pageChange($event)"
>
<kendo-grid-column field="ProductID" title="Product ID" width="120">
</kendo-grid-column>
<kendo-grid-column field="ProductName" title="Product Name">
</kendo-grid-column>
<kendo-grid-column field="UnitPrice" title="Unit Price" format="{0:c}">
</kendo-grid-column>
</kendo-grid>
`
})
export class CategoryDetailComponent implements OnInit {
/**
* The category for which details are displayed
*/
@Input() public category: Object;
private view: Observable<GridDataResult>;
private skip: number = 0;
constructor(private service: ProductsService) { }
public ngOnInit(): void {
this.view = this.service;
/*load products for the given category*/
this.service.queryForCategory(this.category, { skip: this.skip, take: 5 });
}
protected pageChange({ skip, take }: PageChangeEvent): void {
this.skip = skip;
this.service.queryForCategory(this.category, { skip, take });
}
}
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { GridDataResult } from '@progress/kendo-angular-grid';
import { toODataString } from '@progress/kendo-data-query';
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import 'rxjs/add/operator/map';
export abstract class NorthwindService extends BehaviorSubject<GridDataResult> {
private BASE_URL: string = 'https://odatasampleservices.azurewebsites.net/V4/Northwind/Northwind.svc/';
constructor(
private http: HttpClient,
protected tableName: string
) {
super(null);
}
public query(state: any): void {
this.fetch(this.tableName, state)
.subscribe(x => super.next(x));
}
protected fetch(tableName: string, state: any): Observable<GridDataResult> {
const queryStr = `${toODataString(state)}&$count=true`;
return this.http
.get(`${this.BASE_URL}${tableName}?${queryStr}`)
.map(response => (<GridDataResult>{
data: response['value'],
total: parseInt(response["@odata.count"], 10)
}));
}
}
@Injectable()
export class ProductsService extends NorthwindService {
constructor(http: HttpClient) { super(http, "Products"); }
public queryForCategory({ CategoryID }: { CategoryID: number }, state?: any): void {
this.query(Object.assign({}, state, {
filter: {
filters: [{
field: "CategoryID", operator: "eq", value: CategoryID
}],
logic: "and"
}
}));
}
public queryForProductName(ProductName: string, state?: any): void {
this.query(Object.assign({}, state, {
filter: {
filters: [{
field: "ProductName", operator: "contains", value: ProductName
}],
logic: "and"
}
}));
}
}
@Injectable()
export class CategoriesService extends NorthwindService {
constructor(http: HttpClient) { super(http, "Categories"); }
queryAll(st?: any): Observable<GridDataResult> {
const state = Object.assign({}, st);
delete state.skip;
delete state.take;
return this.fetch(this.tableName, state);
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClientModule } from '@angular/common/http';
import { GridModule } from '@progress/kendo-angular-grid';
import { AppComponent } from './app.component';
import { CategoryDetailComponent } from './category-details.component';
@NgModule({
imports: [
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
GridModule
],
declarations: [
AppComponent,
CategoryDetailComponent
],
bootstrap: [
AppComponent
]
})
export class AppModule { }
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './ng.module';
enableProdMode();
const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);
System.config({
"transpiler": "ts",
"typescriptOptions": {
"target": "es5",
"module": "system",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
},
"bundles": {
"https://unpkg.com/rxjs-system-bundle@5.5.2/Rx.system.min.js": [
"rxjs",
"rxjs/*",
"rxjs/operator/*",
"rxjs/observable/*",
"rxjs/scheduler/*",
"rxjs/symbol/*",
"rxjs/add/operator/*",
"rxjs/add/observable/*",
"rxjs/util/*"
],
"https://www.telerik.com/kendo-angular-ui/npm/node_modules/@progress/kendo-drawing/dist/systemjs/kendo-drawing.js": [
"@progress/kendo-drawing",
"@progress/kendo-drawing/*"
]
},
"meta": {
"typescript": {
"exports": "ts"
},
"*.json": {
"loader": "systemjs-json-plugin"
}
},
"map": {
"app": "app",
"systemjs-json-plugin": "https://unpkg.com/systemjs-plugin-json@0.3.0",
"@telerik": "https://www.telerik.com/kendo-angular-ui/npm/node_modules/@telerik",
"@progress": "https://www.telerik.com/kendo-angular-ui/npm/node_modules/@progress",
"cldr-data": "https://www.telerik.com/kendo-angular-ui/npm/node_modules/cldr-data",
"@angular": "https://unpkg.com/@angular",
"angular2-in-memory-web-api": "https://unpkg.com/angular2-in-memory-web-api",
"hammerjs": "https://unpkg.com/hammerjs@2.0.8",
"pako": "https://unpkg.com/pako@1.0.5",
"ts": "https://unpkg.com/plugin-typescript@5.3.3/lib/plugin.js",
"tslib": "https://unpkg.com/tslib@1.7.1",
"typescript": "https://unpkg.com/typescript@2.4.2/lib/typescript.js",
"@angular/common/http": "https://unpkg.com/@angular/common@5.0.0/bundles/common-http.umd.js",
"@angular/platform-browser/animations": "https://unpkg.com/@angular/platform-browser@5.0.0/bundles/platform-browser-animations.umd.js",
"@angular/animations/browser": "https://unpkg.com/@angular/animations@5.0.0/bundles/animations-browser.umd.js",
"@angular/common": "https://unpkg.com/@angular/common@5.0.0",
"@angular/compiler": "https://unpkg.com/@angular/compiler@5.0.0",
"@angular/forms": "https://unpkg.com/@angular/forms@5.0.0",
"@angular/core": "https://unpkg.com/@angular/core@5.0.0",
"@angular/platform-browser": "https://unpkg.com/@angular/platform-browser@5.0.0",
"@angular/platform-browser-dynamic": "https://unpkg.com/@angular/platform-browser-dynamic@5.0.0",
"@angular/upgrade": "https://unpkg.com/@angular/upgrade@5.0.0"
},
"packages": {
"app": {
"main": "./main.ts",
"defaultExtension": "ts"
},
"rxjs": {
"defaultExtension": false
},
"pako": {
"defaultExtension": "js",
"main": "./index.js"
},
"@angular/common": {
"main": "/bundles/common.umd.js"
},
"@angular/compiler": {
"main": "/bundles/compiler.umd.js"
},
"@angular/forms": {
"main": "bundles/forms.umd.js",
"defaultExtension": "js"
},
"@angular/core": {
"main": "/bundles/core.umd.js"
},
"@angular/platform-browser": {
"main": "/bundles/platform-browser.umd.js"
},
"@angular/platform-browser-dynamic": {
"main": "/bundles/platform-browser-dynamic.umd.js"
},
"@angular/upgrade": {
"main": "/bundles/upgrade.umd.js"
},
"@angular/animations": {
"main": "/bundles/animations.umd.js"
},
"@progress/kendo-angular-buttons": {
"main": "dist/cdn/js/kendo-angular-buttons.js",
"defaultExtension": "js"
},
"@progress/kendo-angular-l10n": {
"main": "dist/cdn/js/kendo-angular-l10n.js",
"defaultExtension": "js"
},
"@progress/kendo-angular-charts": {
"main": "dist/cdn/js/kendo-angular-charts.js",
"defaultExtension": "js"
},
"@progress/kendo-angular-inputs": {
"main": "dist/cdn/js/kendo-angular-inputs.js",
"defaultExtension": "js"
},
"@progress/kendo-angular-intl": {
"main": "dist/cdn/js/kendo-angular-intl.js",
"defaultExtension": "js"
},
"@progress/kendo-data-query": {
"main": "dist/cdn/js/kendo-data-query.js",
"defaultExtension": "js"
},
"@progress/kendo-file-saver": {
"main": "dist/npm/main.js",
"defaultExtension": "js"
},
"@progress/kendo-angular-dateinputs": {
"main": "dist/cdn/js/kendo-angular-dateinputs.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"
},
"@progress/kendo-angular-grid": {
"main": "dist/cdn/js/kendo-angular-grid.js",
"defaultExtension": "js"
},
"@progress/kendo-angular-popup": {
"main": "dist/cdn/js/kendo-angular-popup.js",
"defaultExtension": "js"
},
"@progress/kendo-angular-label": {
"main": "dist/cdn/js/kendo-angular-label.js",
"defaultExtension": "js"
},
"@progress/kendo-angular-layout": {
"main": "dist/cdn/js/kendo-angular-layout.js",
"defaultExtension": "js"
},
"@progress/kendo-angular-ripple": {
"main": "dist/cdn/js/kendo-angular-ripple.js",
"defaultExtension": "js"
},
"@progress/kendo-angular-scrollview": {
"main": "dist/cdn/js/kendo-angular-scrollview.js",
"defaultExtension": "js"
},
"@progress/kendo-angular-sortable": {
"main": "dist/cdn/js/kendo-angular-sortable.js",
"defaultExtension": "js"
},
"@progress/kendo-angular-upload": {
"main": "dist/cdn/js/kendo-angular-upload.js",
"defaultExtension": "js"
},
"@progress/kendo-angular-excel-export": {
"main": "dist/cdn/js/kendo-angular-excel-export.js",
"defaultExtension": "js"
},
"@progress/kendo-angular-pdf-export": {
"main": "dist/cdn/js/kendo-angular-pdf-export.js",
"defaultExtension": "js"
},
"@progress/kendo-date-math": {
"main": "dist/cdn/js/kendo-date-math.js",
"defaultExtension": "js"
}
}
});
<!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="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<link rel="stylesheet" href="https://www.telerik.com/kendo-angular-ui/npm/node_modules//@progress/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.8.12/dist/zone.js"></script>
<script src="https://unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script>
<script src="https://unpkg.com/systemjs@0.19.27/dist/system.js"></script>
<!-- 2. Configure SystemJS -->
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
<!-- Example-specific styles -->
<style>
html, body { overflow: hidden; }
body { font-family: "RobotoRegular",Helvetica,Arial,sans-serif; font-size: 14px; margin: 0; }
my-app { display: block; width: 100%; overflow: hidden; min-height: 80px; box-sizing: border-box; padding: 30px; }
my-app > .k-icon.k-i-loading { font-size: 64px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
.example-wrapper { min-height: 280px; align-content: flex-start; }
.example-wrapper p, .example-col p { margin: 0 0 10px; }
.example-wrapper p:first-child, .example-col p:first-child { margin-top: 0; }
.example-col { display: inline-block; vertical-align: top; padding-right: 20px; padding-bottom: 20px; }
.example-config { margin: 0 0 20px; padding: 20px; background-color: rgba(0,0,0,.03); border: 1px solid rgba(0,0,0,.08); }
.event-log { margin: 0; padding: 0; max-height: 100px; overflow-y: auto; list-style-type: none; border: 1px solid rgba(0,0,0,.08); background-color: #fff; }
.event-log li {margin: 0; padding: .3em; line-height: 1.2em; border-bottom: 1px solid rgba(0,0,0,.08); }
.event-log li:last-child { margin-bottom: -1px;}
</style>
</head>
<!-- 3. Display the application -->
<body>
<my-app>
<span class="k-icon k-i-loading" style="color: #ff6358"></span>
</my-app>
</body>
</html>