<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>DevExtreme Demo</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/17.2.7/css/dx.spa.css" />
<link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/17.2.7/css/dx.common.css" />
<link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/17.2.7/css/dx.light.css" />
<script src="https://unpkg.com/core-js@2.4.1/client/shim.min.js"></script>
<script src="https://unpkg.com/zone.js@0.6.25/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.31/dist/system.js"></script>
<script src="config.js"></script>
<script>
System.import('app')
.then(function(viz) {
System.import("devextreme/viz/themes").then(function(viz) {
viz.currentTheme("generic.light");
viz.refreshTheme();
});
})
.catch(console.error.bind(console));
</script>
</head>
<body class="dx-viewport">
<div class="demo-container">
<demo-app>Loading...</demo-app>
</div>
</body>
</html>
// In real applications, you should not transpile code in the browser. You can see how to create your own application with Angular and DevExtreme here:
// https://github.com/DevExpress/devextreme-angular/blob/master/README.md
System.config({
transpiler: 'ts',
typescriptOptions: {
module: "commonjs",
emitDecoratorMetadata: true,
experimentalDecorators: true
},
meta: {
'typescript': {
"exports": "ts"
}
},
paths: {
'npm:': 'https://unpkg.com/'
},
map: {
'ts': 'npm:plugin-typescript@7.0.6/lib/plugin.js',
'typescript': 'npm:typescript@2.2.2/lib/typescript.js',
'@angular/core': 'npm:@angular/core@5.1.2/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common@5.1.2/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler@5.1.2/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser@5.1.2/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic@5.1.2/bundles/platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http@5.1.2/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router@5.1.2/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms@5.1.2/bundles/forms.umd.js',
'rxjs': 'npm:rxjs@5.3.1',
'devextreme': 'npm:devextreme@17.2',
'jszip': 'npm:jszip@3.1.3/dist/jszip.min.js',
'devextreme-angular': 'npm:devextreme-angular@17.2'
},
packages: {
'app': {
main: './app.component.ts',
defaultExtension: 'ts'
},
'devextreme': {
defaultExtension: 'js'
},
'devextreme-angular': {
main: 'index.js',
defaultExtension: 'js'
}
}
});
<div class="data-grid-container">
<dx-data-grid
id="gridContainer"
class="data-grid"
[dataSource]="dataSource"
keyExpr="ID"
[allowColumnReordering]="true"
(onEditingStart)="logEvent('EditingStart')"
(onInitNewRow)="logEvent('InitNewRow')"
(onRowInserting)="logEvent('RowInserting')"
(onRowInserted)="logEvent('RowInserted')"
(onRowUpdating)="logEvent('RowUpdating')"
(onRowUpdated)="logEvent('RowUpdated')"
(onRowRemoving)="logEvent('RowRemoving')"
(onRowRemoved)="logEvent('RowRemoved')">
<dxo-scrolling mode="virtual"></dxo-scrolling>
<dxo-export [enabled]="true"
fileName="TentativeAppointments"></dxo-export>
<dxo-group-panel [visible]="true"></dxo-group-panel>
<dxo-grouping #expand
[autoExpandAll]="true"></dxo-grouping>
<dxo-selection selectAllMode="allPages"
showCheckBoxesMode="always"
mode="multiple"></dxo-selection>
<dxo-column-chooser [enabled]="true"></dxo-column-chooser>
<dxo-search-panel [visible]="true"
[width]="240"
placeholder="Search..."></dxo-search-panel>
<dxo-editing mode="batch"
[allowUpdating]="true"></dxo-editing>
<dxo-state-storing [enabled]="true"
type="localStorage"
storageKey="GridState"></dxo-state-storing>
<dxi-column dataField="Prefix" caption="Title"></dxi-column>
<dxi-column dataField="FirstName"></dxi-column>
<dxi-column dataField="LastName"></dxi-column>
<dxi-column dataField="Position" [width]="130"></dxi-column>
<dxi-column
dataField="StateID"
caption="State"
[width]="125">
<dxo-lookup
[dataSource]="states"
displayExpr="Name"
valueExpr="ID">
</dxo-lookup>
</dxi-column>
<dxi-column
dataField="BirthDate"
[width]="125"
dataType="date">
</dxi-column>
<dxi-column dataField=""
[width]="66"
[allowFiltering]="false"
[allowSorting]="false"
cellTemplate="buttonColumnTemplate"
[fixed]="true"
fixedPosition="right"></dxi-column>
<div *dxTemplate="let data of 'buttonColumnTemplate'"
class="col-buttons">
<span class="dx-link dx-link-edit dx-icon-edit"
title="Edit this item"></span>
</div>
</dx-data-grid>
</div>
<div id="events">
<div>
<div class="caption">
Fired events
</div>
<dx-button id="clear" text="Clear" (onClick)="clearEvents()"></dx-button>
</div>
<ul>
<li *ngFor="let event of events">{{event}}</li>
</ul>
</div>
import { NgModule, Component, enableProdMode } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { DxDataGridModule, DxButtonModule } from 'devextreme-angular';
import { Service, Employee, State } from './app.service';
if(!/localhost/.test(document.location.host)) {
enableProdMode();
}
@Component({
selector: 'demo-app',
templateUrl: 'app/app.component.html',
styleUrls: ['app/app.component.css'],
providers: [Service]
})
export class AppComponent {
dataSource: Employee[];
states: State[];
events: Array<string> = [];
constructor(service: Service) {
this.dataSource = service.getEmployees();
this.states = service.getStates();
}
logEvent(eventName) {
this.events.unshift(eventName);
}
clearEvents() {
this.events = [];
}
}
@NgModule({
imports: [
BrowserModule,
DxDataGridModule,
DxButtonModule
],
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule { }
platformBrowserDynamic().bootstrapModule(AppModule);
import { Injectable } from '@angular/core';
export class Employee {
ID: number;
FirstName: string;
LastName: string;
Prefix: string;
Position: string;
BirthDate: string;
HireDate: string;
Notes: string;
Address: string;
StateID: number;
}
export class State {
ID: number;
Name: string;
}
let states: State[] = [{
"ID": 1,
"Name": "Alabama"
}, {
"ID": 2,
"Name": "Alaska"
}, {
"ID": 3,
"Name": "Arizona"
}, {
"ID": 4,
"Name": "Arkansas"
}, {
"ID": 5,
"Name": "California"
}, {
"ID": 6,
"Name": "Colorado"
}, {
"ID": 7,
"Name": "Connectictu"
}, {
"ID": 8,
"Name": "Delaware"
}, {
"ID": 9,
"Name": "District of Columbia"
}, {
"ID": 10,
"Name": "Florida"
}, {
"ID": 11,
"Name": "Georgia"
}, {
"ID": 12,
"Name": "Hawaii"
}, {
"ID": 13,
"Name": "Idaho"
}, {
"ID": 14,
"Name": "Illinois"
}, {
"ID": 15,
"Name": "Indiana"
}, {
"ID": 16,
"Name": "Iowa"
}, {
"ID": 17,
"Name": "Kansas"
}, {
"ID": 18,
"Name": "Kentucky"
}, {
"ID": 19,
"Name": "Louisiana"
}, {
"ID": 20,
"Name": "Maine"
}, {
"ID": 21,
"Name": "Maryland"
}, {
"ID": 22,
"Name": "Massachusetts"
}, {
"ID": 23,
"Name": "Michigan"
}, {
"ID": 24,
"Name": "Minnesota"
}, {
"ID": 25,
"Name": "Mississippi"
}, {
"ID": 26,
"Name": "Missouri"
}, {
"ID": 27,
"Name": "Montana"
}, {
"ID": 28,
"Name": "Nebraska"
}, {
"ID": 29,
"Name": "Nevada"
}, {
"ID": 30,
"Name": "New Hampshire"
}, {
"ID": 31,
"Name": "New Jersey"
}, {
"ID": 32,
"Name": "New Mexico"
}, {
"ID": 33,
"Name": "New York"
}, {
"ID": 34,
"Name": "North Carolina"
}, {
"ID": 35,
"Name": "Ohio"
}, {
"ID": 36,
"Name": "Oklahoma"
}, {
"ID": 37,
"Name": "Oregon"
}, {
"ID": 38,
"Name": "Pennsylvania"
}, {
"ID": 39,
"Name": "Rhode Island"
}, {
"ID": 40,
"Name": "South Carolina"
}, {
"ID": 41,
"Name": "South Dakota"
}, {
"ID": 42,
"Name": "Tennessee"
}, {
"ID": 43,
"Name": "Texas"
}, {
"ID": 44,
"Name": "Utah"
}, {
"ID": 45,
"Name": "Vermont"
}, {
"ID": 46,
"Name": "Virginia"
}, {
"ID": 47,
"Name": "Washington"
}, {
"ID": 48,
"Name": "West Virginia"
}, {
"ID": 49,
"Name": "Wisconsin"
}, {
"ID": 50,
"Name": "Wyoming"
}, {
"ID": 51,
"Name": "North Dakota"
}];
@Injectable()
export class Service {
getEmployees() {
// return employees;
return this.generateBunchOfData(200);
}
getStates() {
return states;
}
private generateBunchOfData(numRows) {
var data = [];
for (var idx = 0; idx < numRows; idx++) {
data.push({
"ID": idx,
"FirstName": idx + '',
"LastName": "Hobbs",
"Prefix": "Mr.",
"Position": "Programmer",
"BirthDate": "1984/12/24",
"HireDate": "2011/02/17",
"Notes": "Walter has been developing apps and websites for DevAV since 2011. His passion is software and if you ever walk by his desk, you'll know why.\r\n\r\nWally once worked 72 hours straight - writing code and fixing bugs.",
"Address": "10385 Shadow Oak Dr",
"StateID": 13
});
}
return data;
}
}
::ng-deep .data-grid-container {
height: 25em;
}
::ng-deep .data-grid {
height: 100%;
width: 100%;
}
::ng-deep .dx-datagrid .dx-link {
text-decoration: none;
font-size: 18px;
margin: 0 3px;
}
::ng-deep .dx-datagrid .dx-link {
text-decoration: none;
font-size: 1.2em;
margin: 0 3px;
color: #071689;
}
::ng-deep .dx-datagrid .dx-link:hover {
opacity: 0.8;
}
::ng-deep .dx-datagrid-save-button {
background-color: #5cb85c;
}
::ng-deep .dx-toolbar-text-auto-hide .dx-button .dx-icon-edit-button-save {
color: #FFF;
}
::ng-deep .dx-datagrid-column-chooser .dx-overlay-content .dx-popup-title {
color: #333;
padding: 7px 10px 9px 10px;
}
::ng-deep .dx-datagrid-column-chooser .dx-overlay-content .dx-popup-title .dx-closebutton .dx-icon {
color: #333;
}
::ng-deep .dx-data-row.dx-state-hover:not(.dx-selection):not(.dx-row-inserted):not(.dx-row-removed):not(.dx-edit-row)>td:not(.dx-focused) {
background-color: #6BABE5;
color: #FFF;
}
::ng-deep .dx-datagrid-rowsview .dx-select-checkboxes-hidden>tbody>tr>td>.dx-select-checkbox {
display: block;
}
::ng-deep tr.dx-header-row>td.dx-datagrid-action {
text-align: left !important;
}
::ng-deep tr.dx-header-row>td.dx-datagrid-action>div.dx-column-indicators {
float: right !important;
}
/* Removes the DevEx scrollbars and just uses browser scrollbars */
::ng-deep .dx-scrollbar-horizontal.dx-scrollbar-hoverable .dx-scrollable-scroll.dx-state-invisible .dx-scrollable-scroll-content, .dx-scrollbar-horizontal.dx-scrollbar-hoverable, .dx-scrollbar-horizontal.dx-scrollbar-hoverable .dx-scrollable-scroll, .dx-scrollbar-horizontal.dx-scrollbar-hoverable .dx-scrollable-scroll .dx-scrollable-scroll-content, .dx-scrollbar-vertical.dx-scrollbar-hoverable .dx-scrollable-scroll.dx-state-invisible .dx-scrollable-scroll-content, .dx-scrollbar-vertical.dx-scrollbar-hoverable, .dx-scrollbar-vertical.dx-scrollbar-hoverable .dx-scrollable-scroll, .dx-scrollbar-vertical.dx-scrollbar-hoverable .dx-scrollable-scroll .dx-scrollable-scroll-content, .dx-scrollbar-vertical.dx-scrollbar-hoverable .dx-scrollable-scroll {
transition: none;
}
::ng-deep .dx-scrollable-scroll-content, .dx-scrollbar-hoverable.dx-state-hover, .dx-scrollbar-hoverable.dx-scrollable-scrollbar-active, .dx-scrollbar-hoverable.dx-scrollable-scrollbar-active .dx-scrollable-scroll-content {
background-color: transparent;
box-shadow: none;
transition: none;
}