<!DOCTYPE html>
<html>

  <head>
    <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.21.3/dist/system.js"></script>

    <script>
        var appLocation = '';
        var boilerplatePath = '';
        var systemJsMap = {"ag-grid":"https:\/\/unpkg.com\/ag-grid@18.0.1\/dist\/ag-grid.js","ag-grid\/main":"https:\/\/unpkg.com\/ag-grid@18.0.1\/dist\/ag-grid.js","ag-grid-enterprise":"https:\/\/unpkg.com\/ag-grid-enterprise@18.0.1\/","ag-grid-angular":"npm:ag-grid-angular@18.0.1\/"};
    </script>
    <script src="config.js"></script>
    <script>
    System.import('main.ts').catch(function(err){ console.error(err); });
    </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: Object.assign(
      {
        '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',
        '@angular/common/http': 'npm:@angular/common@5.1.2/bundles/common-http.umd.js',
        'tslib': 'npm:tslib/tslib.js',

        'rxjs': 'npm:rxjs@5.3.1',

        'jszip': 'npm:jszip@3.1.3/dist/jszip.min.js',
      }, systemJsMap),
    packages: {
        app: {
            main: "./main.ts",
            defaultExtension: "ts",
            meta: {
                "./*.ts": {
                    loader: boilerplatePath + "systemjs-angular-loader.js"
                }
            }
        },
        'ag-grid-angular': {
            main: './main.js',
            defaultExtension: 'js'
        },
        'ag-grid-enterprise': {
            main: './main.js',
            defaultExtension: 'js'
        }
    }
});
import { Component } from '@angular/core';
import "ag-grid-enterprise";
import { GridOptions, GridApi, ColumnApi } from 'ag-grid';

import { Employee, Service } from './app.service';

@Component({
    selector: 'demo-app',
    templateUrl: 'app/app.component.html',
    styleUrls: ['app/app.component.css'],
    providers: [Service]
})

export class AppComponent {
  public gridOptions: GridOptions;
  public selectionChangedCount = 0;
  
  private columnDefs;
  private gridApi;
  private gridColumnApi;
  
  currentEmployee: Employee = new Employee();
  employees: Employee[];

  constructor(service: Service) {
      this.employees = service.getEmployees();
      this.columnDefs = [
      {
        checkboxSelection: true,
        headerCheckboxSelection: true,
        headerCheckboxSelectionFilteredOnly: true,
        suppressResize: true,
        suppressAutoSize: true,
        suppressSizeToFit: true,
        suppressMenu: true,
        width: 30,
        minWidth: 30,
        maxWidth: 30
      },
      {
        headerName: "First Name",
        field: "FirstName"
      },
      {
        headerName: "Last Name",
        field: "LastName"
      },
      {
        headerName: "Prefix",
        field: "Prefix"
      },
      {
        headerName: "BirthDate",
        field: "BirthDate"
      },
      {
        headerName: "HireDate",
        field: "HireDate"
      },
      {
        headerName: "Notes",
        field: "Notes"
      },
      {
        headerName: "Address",
        field: "Address"
      }];
      this.gridOptions = <GridOptions>{
        context: this,
        columnDefs: this.columnDefs,
        rowSelection: 'multiple',
        deltaRowDataMode: true,
        onSelectionChanged: (event) => this.onSelectionChanged(),
        getRowNodeId: function (params) {
          return params.ID;
        }
      }
  }
  
  onGridReady(params) {
    this.gridApi = params.api;
    this.gridColumnApi = params.columnApi;
    
     params.api.setRowData(this.employees);
  }
  
  public onSelectionChanged(){
    this.selectionChangedCount++;
  }
  
  public clearData(){
    this.gridApi.setRowData(new Array<Employee>());
  }
  
  public setData(){
    this.gridApi.setRowData(this.employees);
  }
}
 <button type="button" (click)="clearData()">Clear data</button>
 <button type="button" (click)="setData()">Set data</button>
 <div style="height: 600px; box-sizing: border-box;">
  <ag-grid-angular
  #agGrid
  style="width: 100%; height: 100%;"
  id="myGrid"
  class="ag-theme-balham"
  [gridOptions]="gridOptions"
  (gridReady)="onGridReady($event)"
  ></ag-grid-angular>
</div>

<h2>SelectionChanged event fired: {{selectionChangedCount}} times</h2>
::ng-deep #popup {
    padding: 10px;
}
::ng-deep #popup ul {
    list-style-type: none;
    text-align: center;
}
::ng-deep #popup ul li {
    display: inline-block;
    width: 160px;
    margin: 10px;
}
::ng-deep #popup ul li img{
    width: 100px;
}
::ng-deep .button-info {
    margin: 10px;
}
::ng-deep .popup p {
    margin-bottom: 10px;
    margin-top: 0;
}
import { Injectable } from '@angular/core';

export class Employee {
    ID: number;
    FirstName: string;
    LastName: string;
    Prefix: string;
    Position: string;
    Picture: string;
    BirthDate: string;
    HireDate: string;
    Notes: string;
    Address: string;
    Editable: boolean;
}

let employees: Employee[] = [{
    "ID": 7,
    "FirstName": "Sandra",
    "LastName": "Johnson",
    "Prefix": "Mrs.",
    "Position": "Controller",
    "Picture": "https://js.devexpress.com/Demos/WidgetsGallery/JSDemos/images/employees/06.png",
    "BirthDate": "1974/11/15",
    "HireDate": "2005/05/11",
    "Notes": "Sandra is a CPA and has been our controller since 2008. She loves to interact with staff so if you've not met her, be certain to say hi.\r\n\r\nSandra has 2 daughters both of whom are accomplished gymnasts.",
    "Address": "4600 N Virginia Rd.",
    "Editable": false
}, {
    "ID": 10,
    "FirstName": "Kevin",
    "LastName": "Carter",
    "Prefix": "Mr.",
    "Position": "Shipping Manager",
    "Picture": "https://js.devexpress.com/Demos/WidgetsGallery/JSDemos/images/employees/07.png",
    "BirthDate": "1978/01/09",
    "HireDate": "2009/08/11",
    "Notes": "Kevin is our hard-working shipping manager and has been helping that department work like clockwork for 18 months.\r\n\r\nWhen not in the office, he is usually on the basketball court playing pick-up games.",
    "Address": "424 N Main St.",
    "Editable": false
}, {
    "ID": 11,
    "FirstName": "Cynthia",
    "LastName": "Stanwick",
    "Prefix": "Ms.",
    "Position": "HR Assistant",
    "Picture": "https://js.devexpress.com/Demos/WidgetsGallery/JSDemos/images/employees/08.png",
    "BirthDate": "1985/06/05",
    "HireDate": "2008/03/24",
    "Notes": "Cindy joined us in 2008 and has been in the HR department for 2 years. \r\n\r\nShe was recently awarded employee of the month. Way to go Cindy!",
    "Address": "2211 Bonita Dr.",
    "Editable": false
}, {
    "ID": 30,
    "FirstName": "Kent",
    "LastName": "Samuelson",
    "Prefix": "Dr.",
    "Position": "Ombudsman",
    "Picture": "https://js.devexpress.com/Demos/WidgetsGallery/JSDemos/images/employees/02.png",
    "BirthDate": "1972/09/11",
    "HireDate": "2009/04/22",
    "Notes": "As our ombudsman, Kent is on the front-lines solving customer problems and helping our partners address issues out in the field.    He is a classically trained musician and is a member of the Chamber Orchestra.",
    "Address": "12100 Mora Dr",
    "Editable": false
},{
    "ID": 31,
    "FirstName": "Sandra",
    "LastName": "Johnson",
    "Prefix": "Mrs.",
    "Position": "Controller",
    "Picture": "https://js.devexpress.com/Demos/WidgetsGallery/JSDemos/images/employees/06.png",
    "BirthDate": "1974/11/15",
    "HireDate": "2005/05/11",
    "Notes": "Sandra is a CPA and has been our controller since 2008. She loves to interact with staff so if you've not met her, be certain to say hi.\r\n\r\nSandra has 2 daughters both of whom are accomplished gymnasts.",
    "Address": "4600 N Virginia Rd.",
    "Editable": false
}, {
    "ID": 32,
    "FirstName": "Kevin",
    "LastName": "Carter",
    "Prefix": "Mr.",
    "Position": "Shipping Manager",
    "Picture": "https://js.devexpress.com/Demos/WidgetsGallery/JSDemos/images/employees/07.png",
    "BirthDate": "1978/01/09",
    "HireDate": "2009/08/11",
    "Notes": "Kevin is our hard-working shipping manager and has been helping that department work like clockwork for 18 months.\r\n\r\nWhen not in the office, he is usually on the basketball court playing pick-up games.",
    "Address": "424 N Main St.",
    "Editable": false
}, {
    "ID": 33,
    "FirstName": "Cynthia",
    "LastName": "Stanwick",
    "Prefix": "Ms.",
    "Position": "HR Assistant",
    "Picture": "https://js.devexpress.com/Demos/WidgetsGallery/JSDemos/images/employees/08.png",
    "BirthDate": "1985/06/05",
    "HireDate": "2008/03/24",
    "Notes": "Cindy joined us in 2008 and has been in the HR department for 2 years. \r\n\r\nShe was recently awarded employee of the month. Way to go Cindy!",
    "Address": "2211 Bonita Dr.",
    "Editable": false
}, {
    "ID": 34,
    "FirstName": "Kent",
    "LastName": "Samuelson",
    "Prefix": "Dr.",
    "Position": "Ombudsman",
    "Picture": "https://js.devexpress.com/Demos/WidgetsGallery/JSDemos/images/employees/02.png",
    "BirthDate": "1972/09/11",
    "HireDate": "2009/04/22",
    "Notes": "As our ombudsman, Kent is on the front-lines solving customer problems and helping our partners address issues out in the field.    He is a classically trained musician and is a member of the Chamber Orchestra.",
    "Address": "12100 Mora Dr",
    "Editable": false
}];

@Injectable()
export class Service {
    getEmployees(): Employee[] {
        return employees;
    }
}
import { Component, NgModule, enableProdMode } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AgGridModule } from "ag-grid-angular";

import { AppComponent } from "./app.component";

@NgModule({
    imports: [
        BrowserModule,
        FormsModule,
        AgGridModule.withComponents([])
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent]
})

export class AppModule { }
// Angular entry point file
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from 'app/app.module';

platformBrowserDynamic().bootstrapModule(AppModule);
// Angular entry point file
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from 'app/app.module';

platformBrowserDynamic().bootstrapModule(AppModule);
/**
 * WEB ANGULAR VERSION
 * (based on systemjs.config.js from the angular tutorial - https://angular.io/tutorial)
 * System configuration for Angular samples
 * Adjust as necessary for your application needs.
 */
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;
};