Commit 91d89214ee2c0ea61d3e9af036d07039a30842ad

Authored by Administrator
1 parent ba2867b8

add grid

angular-cli.json
1 1 {
2   - "project": {
3   - "version": "1.0.0-beta.28.3",
4   - "name": "main-maps"
5   - },
6   - "apps": [
7   - {
8   - "root": "src",
9   - "outDir": "dist",
10   - "assets": [
11   - "assets",
12   - "favicon.ico"
13   - ],
14   - "index": "index.html",
15   - "main": "main.ts",
16   - "polyfills": "polyfills.ts",
17   - "test": "test.ts",
18   - "tsconfig": "tsconfig.json",
19   - "prefix": "app",
20   - "styles": [
21   - "styles.css"
22   - ],
23   - "scripts": [],
24   - "environments": {
25   - "source": "environments/environment.ts",
26   - "dev": "environments/environment.ts",
27   - "prod": "environments/environment.prod.ts"
28   - }
29   - }
30   - ],
31   - "e2e": {
32   - "protractor": {
33   - "config": "./protractor.conf.js"
34   - }
35   - },
36   - "lint": [
37   - {
38   - "files": "src/**/*.ts",
39   - "project": "src/tsconfig.json"
  2 + "project": {
  3 + "version": "1.0.0-beta.28.3",
  4 + "name": "main-maps"
40 5 },
41   - {
42   - "files": "e2e/**/*.ts",
43   - "project": "e2e/tsconfig.json"
44   - }
45   - ],
46   - "test": {
47   - "karma": {
48   - "config": "./karma.conf.js"
49   - }
50   - },
51   - "defaults": {
52   - "styleExt": "css",
53   - "prefixInterfaces": false,
54   - "inline": {
55   - "style": false,
56   - "template": false
  6 + "apps": [{
  7 + "root": "src",
  8 + "outDir": "dist",
  9 + "assets": [
  10 + "assets",
  11 + "favicon.ico"
  12 + ],
  13 + "index": "index.html",
  14 + "main": "main.ts",
  15 + "polyfills": "polyfills.ts",
  16 + "test": "test.ts",
  17 + "tsconfig": "tsconfig.json",
  18 + "prefix": "app",
  19 + "styles": [
  20 + "styles.css",
  21 + "../node_modules/ag-grid/dist/styles/ag-grid.css",
  22 + "../node_modules/ag-grid/dist/styles/theme-fresh.css"
  23 + ],
  24 + "scripts": [],
  25 + "environments": {
  26 + "source": "environments/environment.ts",
  27 + "dev": "environments/environment.ts",
  28 + "prod": "environments/environment.prod.ts"
  29 + }
  30 + }],
  31 + "e2e": {
  32 + "protractor": {
  33 + "config": "./protractor.conf.js"
  34 + }
  35 + },
  36 + "lint": [{
  37 + "files": "src/**/*.ts",
  38 + "project": "src/tsconfig.json"
  39 + },
  40 + {
  41 + "files": "e2e/**/*.ts",
  42 + "project": "e2e/tsconfig.json"
  43 + }
  44 + ],
  45 + "test": {
  46 + "karma": {
  47 + "config": "./karma.conf.js"
  48 + }
57 49 },
58   - "spec": {
59   - "class": false,
60   - "component": true,
61   - "directive": true,
62   - "module": false,
63   - "pipe": true,
64   - "service": true
  50 + "defaults": {
  51 + "styleExt": "css",
  52 + "prefixInterfaces": false,
  53 + "inline": {
  54 + "style": false,
  55 + "template": false
  56 + },
  57 + "spec": {
  58 + "class": false,
  59 + "component": true,
  60 + "directive": true,
  61 + "module": false,
  62 + "pipe": true,
  63 + "service": true
  64 + }
65 65 }
66   - }
67   -}
  66 +}
68 67 \ No newline at end of file
... ...
src/app/app.component.html deleted
1   -<md-grid-list cols="4" rowHeight="100px">
2   - <md-grid-tile *ngFor="let tile of tiles" [colspan]="tile.cols" [rowspan]="tile.rows" [style.background]="tile.color">
3   - {{tile.text}}
4   - </md-grid-tile>
5   -</md-grid-list>
6 0 \ No newline at end of file
src/app/app.module.ts
1 1 import { BrowserModule } from '@angular/platform-browser';
  2 +import { RouterModule } from '@angular/router';
2 3 import { NgModule } from '@angular/core';
3 4 import { FormsModule } from '@angular/forms';
4 5 import { HttpModule } from '@angular/http';
5 6 import { MaterialModule } from '@angular/material';
  7 +import { AgGridModule } from 'ag-grid-ng2/main';
  8 +import { RichGridComponent } from "./components/grid/rich-grid.component";
  9 +
6 10 import 'hammerjs';
7 11  
8   -import { AppComponent } from './app.component';
  12 +import { AppComponent } from './components/app/app.component';
9 13  
10 14 @NgModule({
11 15 declarations: [
12   - AppComponent
  16 + AppComponent,
  17 + RichGridComponent
13 18 ],
14 19 imports: [
  20 + RouterModule.forRoot([
  21 + { path: 'grid', component: RichGridComponent }
  22 + ]),
15 23 BrowserModule,
16 24 FormsModule,
17 25 HttpModule,
18   - MaterialModule.forRoot()
  26 + MaterialModule.forRoot(),
  27 + AgGridModule.withComponents([
  28 + RichGridComponent
  29 + ])
19 30 ],
20 31 providers: [],
21 32 bootstrap: [AppComponent]
... ...
src/app/app.component.css renamed to src/app/components/app/app.component.css
src/app/components/app/app.component.html 0 โ†’ 100644
  1 +<router-outlet></router-outlet>
0 2 \ No newline at end of file
... ...
src/app/app.component.ts renamed to src/app/components/app/app.component.ts
src/app/components/grid/polyfills.ts 0 โ†’ 100644
  1 +import "core-js/es6";
  2 +import "core-js/es7/reflect";
  3 +require('zone.js/dist/zone');
  4 +if (process.env.ENV === 'production') {
  5 + // Production
  6 +} else {
  7 + // Development
  8 + Error['stackTraceLimit'] = Infinity;
  9 + require('zone.js/dist/long-stack-trace-zone');
  10 +}
0 11 \ No newline at end of file
... ...
src/app/components/grid/proficiency-renderer.css 0 โ†’ 100644
  1 +.ag-cell {
  2 + padding-top: 2px !important;
  3 + padding-bottom: 2px !important;
  4 +}
  5 +
  6 +label {
  7 + font-weight: normal !important;
  8 +}
  9 +
  10 +.div-percent-bar {
  11 + display: inline-block;
  12 + height: 100%;
  13 + position: relative;
  14 + z-index: 0;
  15 +}
  16 +
  17 +.div-percent-value {
  18 + position: absolute;
  19 + padding-left: 4px;
  20 + font-weight: bold;
  21 + font-size: 13px;
  22 + z-index: 100;
  23 +}
  24 +
  25 +.div-outer-div {
  26 + display: inline-block;
  27 + height: 100%;
  28 + width: 100%;
  29 +}
0 30 \ No newline at end of file
... ...
src/app/components/grid/proficiencyFilter.ts 0 โ†’ 100644
  1 +import {IFilter,IFilterParams} from "ag-grid/main";
  2 +
  3 +var FILTER_TITLE =
  4 + '<div style="text-align: center; background: lightgray; width: 100%; display: block; border-bottom: 1px solid grey;">' +
  5 + '<b>TITLE_NAME</b>' +
  6 + '</div>';
  7 +
  8 +var PROFICIENCY_TEMPLATE =
  9 + '<label style="padding-left: 4px;">' +
  10 + '<input type="radio" name="RANDOM"/>' +
  11 + 'PROFICIENCY_NAME' +
  12 + '</label>';
  13 +
  14 +var PROFICIENCY_NONE = 'none';
  15 +var PROFICIENCY_ABOVE40 = 'above40';
  16 +var PROFICIENCY_ABOVE60 = 'above60';
  17 +var PROFICIENCY_ABOVE80 = 'above80';
  18 +
  19 +var PROFICIENCY_NAMES = ['No Filter', 'Above 40%', 'Above 60%', 'Above 80%'];
  20 +var PROFICIENCY_VALUES = [PROFICIENCY_NONE, PROFICIENCY_ABOVE40, PROFICIENCY_ABOVE60, PROFICIENCY_ABOVE80];
  21 +
  22 +export default class ProficiencyFilter implements IFilter {
  23 + private filterChangedCallback:Function;
  24 + private selected:string;
  25 + private valueGetter:Function;
  26 +
  27 + public init(params: IFilterParams) : void {
  28 + this.filterChangedCallback = params.filterChangedCallback;
  29 + this.selected = PROFICIENCY_NONE;
  30 + this.valueGetter = params.valueGetter;
  31 + }
  32 +
  33 + public getGui() {
  34 + var eGui = document.createElement('div');
  35 + var eInstructions = document.createElement('div');
  36 + eInstructions.innerHTML = FILTER_TITLE.replace('TITLE_NAME', 'Custom Proficiency Filter');
  37 + eGui.appendChild(eInstructions);
  38 +
  39 + var random = '' + Math.random();
  40 +
  41 + var that = this;
  42 + PROFICIENCY_NAMES.forEach(function (name, index) {
  43 + var eFilter = document.createElement('div');
  44 + var html = PROFICIENCY_TEMPLATE.replace('PROFICIENCY_NAME', name).replace('RANDOM', random);
  45 + eFilter.innerHTML = html;
  46 + var eRadio = <HTMLInputElement> eFilter.querySelector('input');
  47 + if (index === 0) {
  48 + eRadio.checked = true;
  49 + }
  50 + eGui.appendChild(eFilter);
  51 +
  52 + eRadio.addEventListener('click', function () {
  53 + that.selected = PROFICIENCY_VALUES[index];
  54 + that.filterChangedCallback();
  55 + });
  56 + });
  57 +
  58 + return eGui;
  59 + }
  60 +
  61 + public doesFilterPass(params) {
  62 +
  63 + var value = this.valueGetter(params);
  64 + var valueAsNumber = parseFloat(value);
  65 +
  66 + switch (this.selected) {
  67 + case PROFICIENCY_ABOVE40 :
  68 + return valueAsNumber >= 40;
  69 + case PROFICIENCY_ABOVE60 :
  70 + return valueAsNumber >= 60;
  71 + case PROFICIENCY_ABOVE80 :
  72 + return valueAsNumber >= 80;
  73 + default :
  74 + return true;
  75 + }
  76 +
  77 + }
  78 +
  79 + public isFilterActive() {
  80 + return this.selected !== PROFICIENCY_NONE;
  81 + }
  82 +
  83 + public getModel():any {
  84 + return undefined;
  85 + }
  86 +
  87 + public setModel(model:any):void {
  88 + }
  89 +}
... ...
src/app/components/grid/refData.ts 0 โ†’ 100644
  1 +export default class RefData {
  2 +
  3 + static IT_SKILLS = ['android', 'css', 'html5', 'mac', 'windows'];
  4 + static IT_SKILLS_NAMES = ['Android', 'CSS', 'HTML 5', 'Mac', 'Windows'];
  5 +
  6 +
  7 + static firstNames = ["Sophie", "Isabelle", "Emily", "Olivia", "Lily", "Chloe", "Isabella",
  8 + "Amelia", "Jessica", "Sophia", "Ava", "Charlotte", "Mia", "Lucy", "Grace", "Ruby",
  9 + "Ella", "Evie", "Freya", "Isla", "Poppy", "Daisy", "Layla"];
  10 + static lastNames = ["Beckham", "Black", "Braxton", "Brennan", "Brock", "Bryson", "Cadwell",
  11 + "Cage", "Carson", "Chandler", "Cohen", "Cole", "Corbin", "Dallas", "Dalton", "Dane",
  12 + "Donovan", "Easton", "Fisher", "Fletcher", "Grady", "Greyson", "Griffin", "Gunner",
  13 + "Hayden", "Hudson", "Hunter", "Jacoby", "Jagger", "Jaxon", "Jett", "Kade", "Kane",
  14 + "Keating", "Keegan", "Kingston", "Kobe"];
  15 +
  16 + static COUNTRY_CODES = {
  17 + Ireland: "ie",
  18 + Spain: "es",
  19 + "United Kingdom": "gb",
  20 + France: "fr",
  21 + Germany: "de",
  22 + Sweden: "se",
  23 + Italy: "it",
  24 + Greece: "gr",
  25 + Iceland: "is",
  26 + Portugal: "pt",
  27 + Malta: "mt",
  28 + Norway: "no",
  29 + Brazil: "br",
  30 + Argentina: "ar",
  31 + Colombia: "co",
  32 + Peru: "pe",
  33 + Venezuela: "ve",
  34 + Uruguay: "uy"
  35 + };
  36 +
  37 + static countries = [
  38 + {country: "Ireland", continent: "Europe", language: "English"},
  39 + {country: "Spain", continent: "Europe", language: "Spanish"},
  40 + {country: "United Kingdom", continent: "Europe", language: "English"},
  41 + {country: "France", continent: "Europe", language: "French"},
  42 + {country: "Germany", continent: "Europe", language: "(other)"},
  43 + {country: "Sweden", continent: "Europe", language: "(other)"},
  44 + {country: "Norway", continent: "Europe", language: "(other)"},
  45 + {country: "Italy", continent: "Europe", language: "(other)"},
  46 + {country: "Greece", continent: "Europe", language: "(other)"},
  47 + {country: "Iceland", continent: "Europe", language: "(other)"},
  48 + {country: "Portugal", continent: "Europe", language: "Portuguese"},
  49 + {country: "Malta", continent: "Europe", language: "(other)"},
  50 + {country: "Brazil", continent: "South America", language: "Portuguese"},
  51 + {country: "Argentina", continent: "South America", language: "Spanish"},
  52 + {country: "Colombia", continent: "South America", language: "Spanish"},
  53 + {country: "Peru", continent: "South America", language: "Spanish"},
  54 + {country: "Venezuela", continent: "South America", language: "Spanish"},
  55 + {country: "Uruguay", continent: "South America", language: "Spanish"}
  56 + ];
  57 +
  58 + static addresses = [
  59 + '1197 Thunder Wagon Common, Cataract, RI, 02987-1016, US, (401) 747-0763',
  60 + '3685 Rocky Glade, Showtucket, NU, X1E-9I0, CA, (867) 371-4215',
  61 + '3235 High Forest, Glen Campbell, MS, 39035-6845, US, (601) 638-8186',
  62 + '2234 Sleepy Pony Mall , Drain, DC, 20078-4243, US, (202) 948-3634',
  63 + '2722 Hazy Turnabout, Burnt Cabins, NY, 14120-5642, US, (917) 604-6597',
  64 + '6686 Lazy Ledge, Two Rock, CA, 92639-3020, US, (619) 901-9911',
  65 + '2000 Dewy Limits, Wacahoota, NF, A4L-2V9, CA, (709) 065-3959',
  66 + '7710 Noble Pond Avenue, Bolivia, RI, 02931-1842, US, (401) 865-2160',
  67 + '3452 Sunny Vale, Pyro, ON, M8V-4Z0, CA, (519) 072-8609',
  68 + '4402 Dusty Cove, Many Farms, UT, 84853-8223, US, (435) 518-0673',
  69 + '5198 Silent Parade, Round Bottom, MD, 21542-9798, US, (301) 060-7245',
  70 + '8550 Shady Moor, Kitty Fork, CO, 80941-6207, US, (303) 502-3767',
  71 + '2131 Old Dell, Merry Midnight, AK, 99906-8842, US, (907) 369-2206',
  72 + '7390 Harvest Crest, Mosquito Crossing, RI, 02957-6116, US, (401) 463-6348',
  73 + '874 Little Point, Hot Coffee, BC, V3U-2P6, CA, (250) 706-9207',
  74 + '8834 Stony Pioneer Heights, Newlove, OR, 97419-8670, US, (541) 408-2213',
  75 + '9829 Grand Beach, Flint, UT, 84965-9900, US, (435) 700-5161',
  76 + '3799 Cozy Blossom Ramp, Ptarmigan, MS, 38715-0313, US, (769) 740-1526',
  77 + '3254 Silver Island Loop, Maunaloa, DE, 19869-3169, US, (302) 667-7671',
  78 + '1081 Middle Wood, Taylors Gut Landing, OR, 97266-2873, US, (541) 357-6310',
  79 + '1137 Umber Trail, Shacktown, NW, X3U-5Y8, CA, (867) 702-6883',
  80 + '9914 Hidden Bank, Wyoming, MO, 64635-9665, US, (636) 280-4192',
  81 + '7080 Misty Nectar Townline, Coward, AB, T9U-3N4, CA, (403) 623-2838',
  82 + '1184 Wishing Grounds, Vibank, NW, X7D-0V9, CA, (867) 531-2730',
  83 + '126 Easy Pointe, Grandview Beach, KY, 40928-9539, US, (502) 548-0956',
  84 + '6683 Colonial Street, Swan River, BC, V1A-9I8, CA, (778) 014-4257',
  85 + '960 Gentle Oak Lane, Shakopee, ND, 58618-6277, US, (701) 327-1219',
  86 + '6918 Cotton Pine Corner, Kenaston, IA, 52165-3975, US, (515) 906-7427',
  87 + '2368 Burning Woods, Ernfold, NY, 11879-9186, US, (646) 819-0355',
  88 + '5646 Quiet Shadow Chase, Tiger Tail, IA, 52283-5537, US, (712) 375-9225',
  89 + '5466 Foggy Mountain Dale, Sweet Home, MT, 59738-0251, US, (406) 881-1706',
  90 + '5313 Clear Willow Route, Amazon, BC, V0S-2S6, CA, (604) 340-7596',
  91 + '7000 Pleasant Autoroute, Spaceport City, UT, 84749-2448, US, (435) 154-3360',
  92 + '8359 Quaking Anchor Road, Gross, BC, V9O-0H5, CA, (250) 985-3859',
  93 + '5143 Amber Deer Hollow, New Deal, ND, 58446-0853, US, (701) 927-0322',
  94 + '6230 Jagged Bear Key, Young, AR, 72337-3811, US, (501) 805-7239',
  95 + '7207 Heather Vista, Devon, WY, 82520-1771, US, (307) 358-7092',
  96 + '9416 Red Rise Place, Spraytown, OK, 73809-4766, US, (580) 867-1973',
  97 + '3770 Golden Horse Diversion, Yelland, IL, 60471-1487, US, (224) 717-9349',
  98 + '4819 Honey Treasure Park, Alaska, NB, E1U-3I0, CA, (506) 656-9138',
  99 + '6187 Round Front, Land O Lakes, AK, 99873-6403, US, (907) 853-9063',
  100 + '9218 Crystal Highway, Pickelville, MT, 59847-9299, US, (406) 076-0024',
  101 + '6737 Bright Quay, Lazy Mountain, KY, 42390-4772, US, (606) 256-7288',
  102 + '237 Merry Campus, Twentysix, SC, 29330-4909, US, (864) 945-0157',
  103 + '446 Fallen Gate Rise, Petrolia, SC, 29959-9527, US, (864) 826-0553',
  104 + '2347 Indian Boulevard, Frisbee, VA, 23797-6458, US, (703) 656-8445',
  105 + '365 Emerald Grove Line, Level, NC, 28381-1514, US, (919) 976-7958',
  106 + '1207 Iron Extension, Klickitat, SC, 29197-8571, US, (803) 535-7888',
  107 + '6770 Cinder Glen, Caronport, OH, 45053-5002, US, (440) 369-4018',
  108 + '7619 Tawny Carrefour, Senlac, NV, 89529-9876, US, (775) 901-6433'];
  109 +}
0 110 \ No newline at end of file
... ...
src/app/components/grid/rich-grid.component.html 0 โ†’ 100644
  1 +<div style="width: 800px;">
  2 + <h1>Rich Grid with Pure JavaScript</h1>
  3 + <div style="padding: 4px;">
  4 + <div style="float: right;">
  5 + <input (keyup)="onQuickFilterChanged($event)" type="text" id="quickFilterInput" placeholder="Type text to filter..." />
  6 + <button [disabled]="!showGrid" (click)="showGrid=false">Destroy Grid</button>
  7 + <button [disabled]="showGrid" (click)="showGrid=true">Create Grid</button>
  8 + </div>
  9 + <div>
  10 + <b>Employees Skills and Contact Details</b> {{rowCount}}
  11 + </div>
  12 + </div>
  13 + <div style="clear: both;"></div>
  14 +
  15 + <div *ngIf="showGrid">
  16 +
  17 + <!-- Because we are using the Angular ID (ie #ag-grid marker), we have to have all the items that use
  18 + that marker inside the same ng-if as the grid -->
  19 +
  20 + <div style="padding: 4px;" class="toolbar">
  21 + <span>
  22 + Grid API:
  23 + <button (click)="agGrid.api.selectAll()">Select All</button>
  24 + <button (click)="agGrid.api.deselectAll()">Clear Selection</button>
  25 + </span>
  26 + <span style="margin-left: 20px;">
  27 + Column API:
  28 + <button (click)="agGrid.columnApi.setColumnVisible('country', false)">Hide Country Column</button>
  29 + <button (click)="agGrid.columnApi.setColumnVisible('country', true)">Show Country Column</button>
  30 + </span>
  31 + </div>
  32 + <div style="clear: both;"></div>
  33 + <div style="padding: 4px;" class="toolbar">
  34 + <label>
  35 + <input type="checkbox" (change)="showToolPanel=$event.target.checked"/>
  36 + Show Tool Panel
  37 + </label>
  38 + <button (click)="createRowData()">Refresh Data</button>
  39 + </div>
  40 + <div style="clear: both;"></div>
  41 +
  42 + <ag-grid-ng2 #agGrid style="width: 100%; height: 350px;" class="ag-fresh" [gridOptions]="gridOptions" [columnDefs]="columnDefs" [showToolPanel]="showToolPanel" [rowData]="rowData" enableColResize enableSorting enableFilter groupHeaders suppressRowClickSelection
  43 + toolPanelSuppressGroups toolPanelSuppressValues debug rowHeight="22" rowSelection="multiple" (modelUpdated)="onModelUpdated()" (cellClicked)="onCellClicked($event)" (cellDoubleClicked)="onCellDoubleClicked($event)" (cellContextMenu)="onCellContextMenu($event)"
  44 + (cellValueChanged)="onCellValueChanged($event)" (cellFocused)="onCellFocused($event)" (rowSelected)="onRowSelected($event)" (selectionChanged)="onSelectionChanged()" (beforeFilterChanged)="onBeforeFilterChanged()" (afterFilterChanged)="onAfterFilterChanged()"
  45 + (filterModified)="onFilterModified()" (beforeSortChanged)="onBeforeSortChanged()" (afterSortChanged)="onAfterSortChanged()" (virtualRowRemoved)="onVirtualRowRemoved($event)" (rowClicked)="onRowClicked($event)" (gridReady)="onReady($event)" (columnEverythingChanged)="onColumnEvent($event)"
  46 + (columnRowGroupChanged)="onColumnEvent($event)" (columnValueChanged)="onColumnEvent($event)" (columnMoved)="onColumnEvent($event)" (columnVisible)="onColumnEvent($event)" (columnGroupOpened)="onColumnEvent($event)" (columnResized)="onColumnEvent($event)"
  47 + (columnPinnedCountChanged)="onColumnEvent($event)">
  48 + </ag-grid-ng2>
  49 + </div>
  50 +
  51 +</div>
0 52 \ No newline at end of file
... ...
src/app/components/grid/rich-grid.component.ts 0 โ†’ 100644
  1 +import {Component, ViewEncapsulation} from "@angular/core";
  2 +import {GridOptions} from "ag-grid/main";
  3 +import ProficiencyFilter from "./proficiencyFilter";
  4 +import SkillFilter from "./skillFilter";
  5 +import RefData from "./refData";
  6 +
  7 +// only import this if you are using the ag-Grid-Enterprise
  8 +
  9 +@Component({
  10 + selector: 'rich-grid',
  11 + templateUrl: 'rich-grid.component.html',
  12 + styleUrls: ['rich-grid.css', 'proficiency-renderer.css'],
  13 + encapsulation: ViewEncapsulation.None
  14 +})
  15 +export class RichGridComponent {
  16 +
  17 + private gridOptions: GridOptions;
  18 + public showGrid: boolean;
  19 + public rowData: any[];
  20 + private columnDefs: any[];
  21 + public rowCount: string;
  22 +
  23 + constructor() {
  24 + // we pass an empty gridOptions in, so we can grab the api out
  25 + this.gridOptions = <GridOptions>{};
  26 + this.createRowData();
  27 + this.createColumnDefs();
  28 + this.showGrid = true;
  29 + }
  30 +
  31 + private createRowData() {
  32 + var rowData: any[] = [];
  33 +
  34 + for (var i = 0; i < 100; i++) {
  35 + var countryData = RefData.countries[i % RefData.countries.length];
  36 + rowData.push({
  37 + name: RefData.firstNames[i % RefData.firstNames.length] + ' ' + RefData.lastNames[i % RefData.lastNames.length],
  38 + skills: {
  39 + android: Math.random() < 0.4,
  40 + html5: Math.random() < 0.4,
  41 + mac: Math.random() < 0.4,
  42 + windows: Math.random() < 0.4,
  43 + css: Math.random() < 0.4
  44 + },
  45 + address: RefData.addresses[i % RefData.addresses.length],
  46 + years: Math.round(Math.random() * 100),
  47 + proficiency: Math.round(Math.random() * 100),
  48 + country: countryData.country,
  49 + continent: countryData.continent,
  50 + language: countryData.language,
  51 + mobile: createRandomPhoneNumber(),
  52 + landline: createRandomPhoneNumber()
  53 + });
  54 + }
  55 +
  56 + this.rowData = rowData;
  57 + }
  58 +
  59 + private createColumnDefs() {
  60 + this.columnDefs = [
  61 + {
  62 + headerName: '#', width: 30, checkboxSelection: true, suppressSorting: true,
  63 + suppressMenu: true, pinned: true
  64 + }
  65 + ];
  66 + }
  67 +
  68 + private calculateRowCount() {
  69 + if (this.gridOptions.api && this.rowData) {
  70 + var model = this.gridOptions.api.getModel();
  71 + var totalRows = this.rowData.length;
  72 + var processedRows = model.getRowCount();
  73 + this.rowCount = processedRows.toLocaleString() + ' / ' + totalRows.toLocaleString();
  74 + }
  75 + }
  76 +
  77 + private onModelUpdated() {
  78 + console.log('onModelUpdated');
  79 + this.calculateRowCount();
  80 + }
  81 +
  82 + private onReady() {
  83 + console.log('onReady');
  84 + this.calculateRowCount();
  85 + }
  86 +
  87 + private onCellClicked($event) {
  88 + console.log('onCellClicked: ' + $event.rowIndex + ' ' + $event.colDef.field);
  89 + }
  90 +
  91 + private onCellValueChanged($event) {
  92 + console.log('onCellValueChanged: ' + $event.oldValue + ' to ' + $event.newValue);
  93 + }
  94 +
  95 + private onCellDoubleClicked($event) {
  96 + console.log('onCellDoubleClicked: ' + $event.rowIndex + ' ' + $event.colDef.field);
  97 + }
  98 +
  99 + private onCellContextMenu($event) {
  100 + console.log('onCellContextMenu: ' + $event.rowIndex + ' ' + $event.colDef.field);
  101 + }
  102 +
  103 + private onCellFocused($event) {
  104 + console.log('onCellFocused: (' + $event.rowIndex + ',' + $event.colIndex + ')');
  105 + }
  106 +
  107 + private onRowSelected($event) {
  108 + // taking out, as when we 'select all', it prints to much to the console!!
  109 + // console.log('onRowSelected: ' + $event.node.data.name);
  110 + }
  111 +
  112 + private onSelectionChanged() {
  113 + console.log('selectionChanged');
  114 + }
  115 +
  116 + private onBeforeFilterChanged() {
  117 + console.log('beforeFilterChanged');
  118 + }
  119 +
  120 + private onAfterFilterChanged() {
  121 + console.log('afterFilterChanged');
  122 + }
  123 +
  124 + private onFilterModified() {
  125 + console.log('onFilterModified');
  126 + }
  127 +
  128 + private onBeforeSortChanged() {
  129 + console.log('onBeforeSortChanged');
  130 + }
  131 +
  132 + private onAfterSortChanged() {
  133 + console.log('onAfterSortChanged');
  134 + }
  135 +
  136 + private onVirtualRowRemoved($event) {
  137 + // because this event gets fired LOTS of times, we don't print it to the
  138 + // console. if you want to see it, just uncomment out this line
  139 + // console.log('onVirtualRowRemoved: ' + $event.rowIndex);
  140 + }
  141 +
  142 + private onRowClicked($event) {
  143 + console.log('onRowClicked: ' + $event.node.data.name);
  144 + }
  145 +
  146 + public onQuickFilterChanged($event) {
  147 + this.gridOptions.api.setQuickFilter($event.target.value);
  148 + }
  149 +
  150 + // here we use one generic event to handle all the column type events.
  151 + // the method just prints the event name
  152 + private onColumnEvent($event) {
  153 + console.log('onColumnEvent: ' + $event);
  154 + }
  155 +
  156 +}
  157 +
  158 +function skillsCellRenderer(params) {
  159 + var data = params.data;
  160 + var skills = [];
  161 + RefData.IT_SKILLS.forEach(function (skill) {
  162 + if (data && data.skills && data.skills[skill]) {
  163 + skills.push('<img src="images/skills/' + skill + '.png" width="16px" title="' + skill + '" />');
  164 + }
  165 + });
  166 + return skills.join(' ');
  167 +}
  168 +
  169 +function countryCellRenderer(params) {
  170 + var flag = "<img border='0' width='15' height='10' style='margin-bottom: 2px' src='images/flags/" + RefData.COUNTRY_CODES[params.value] + ".png'>";
  171 + return flag + " " + params.value;
  172 +}
  173 +
  174 +function createRandomPhoneNumber() {
  175 + var result = '+';
  176 + for (var i = 0; i < 12; i++) {
  177 + result += Math.round(Math.random() * 10);
  178 + if (i === 2 || i === 5 || i === 8) {
  179 + result += ' ';
  180 + }
  181 + }
  182 + return result;
  183 +}
  184 +
  185 +function percentCellRenderer(params) {
  186 + var value = params.value;
  187 +
  188 + var eDivPercentBar = document.createElement('div');
  189 + eDivPercentBar.className = 'div-percent-bar';
  190 + eDivPercentBar.style.width = value + '%';
  191 + if (value < 20) {
  192 + eDivPercentBar.style.backgroundColor = 'red';
  193 + } else if (value < 60) {
  194 + eDivPercentBar.style.backgroundColor = '#ff9900';
  195 + } else {
  196 + eDivPercentBar.style.backgroundColor = '#00A000';
  197 + }
  198 +
  199 + var eValue = document.createElement('div');
  200 + eValue.className = 'div-percent-value';
  201 + eValue.innerHTML = value + '%';
  202 +
  203 + var eOuterDiv = document.createElement('div');
  204 + eOuterDiv.className = 'div-outer-div';
  205 + eOuterDiv.appendChild(eValue);
  206 + eOuterDiv.appendChild(eDivPercentBar);
  207 +
  208 + return eOuterDiv;
  209 +}
... ...
src/app/components/grid/rich-grid.css 0 โ†’ 100644
  1 +.toolbar button {
  2 + margin: 2px;
  3 + padding: 0;
  4 +}
0 5 \ No newline at end of file
... ...
src/app/components/grid/skillFilter.ts 0 โ†’ 100644
  1 +import RefData from './refData';
  2 +import {IFilter,IFilterParams} from "ag-grid/main";
  3 +
  4 +var SKILL_TEMPLATE =
  5 + '<label style="border: 1px solid lightgrey; margin: 4px; padding: 4px; display: inline-block;">' +
  6 + ' <span>' +
  7 + ' <div style="text-align: center;">SKILL_NAME</div>' +
  8 + ' <div>' +
  9 + ' <input type="checkbox"/>' +
  10 + ' <img src="images/skills/SKILL.png" width="30px"/>' +
  11 + ' </div>' +
  12 + ' </span>' +
  13 + '</label>';
  14 +
  15 +var FILTER_TITLE =
  16 + '<div style="text-align: center; background: lightgray; width: 100%; display: block; border-bottom: 1px solid grey;">' +
  17 + '<b>TITLE_NAME</b>' +
  18 + '</div>';
  19 +
  20 +export default class SkillFilter implements IFilter {
  21 + private filterChangedCallback:Function;
  22 + private model:any;
  23 +
  24 + public init(params: IFilterParams) : void {
  25 + this.filterChangedCallback = params.filterChangedCallback;
  26 + this.model = {
  27 + android: false,
  28 + css: false,
  29 + html5: false,
  30 + mac: false,
  31 + windows: false
  32 + };
  33 + };
  34 +
  35 + public getGui() {
  36 + var eGui = document.createElement('div');
  37 + eGui.style.width = '380px';
  38 + var eInstructions = document.createElement('div');
  39 + eInstructions.innerHTML = FILTER_TITLE.replace('TITLE_NAME', 'Custom Skills Filter');
  40 + eGui.appendChild(eInstructions);
  41 +
  42 + var that = this;
  43 +
  44 + RefData.IT_SKILLS.forEach(function (skill, index) {
  45 + var skillName = RefData.IT_SKILLS_NAMES[index];
  46 + var eSpan = document.createElement('span');
  47 + var html = SKILL_TEMPLATE.replace("SKILL_NAME", skillName).replace("SKILL", skill);
  48 + eSpan.innerHTML = html;
  49 +
  50 + var eCheckbox = <HTMLInputElement> eSpan.querySelector('input');
  51 + eCheckbox.addEventListener('click', function () {
  52 + that.model[skill] = eCheckbox.checked;
  53 + that.filterChangedCallback();
  54 + });
  55 +
  56 + eGui.appendChild(eSpan);
  57 + });
  58 +
  59 + return eGui;
  60 + };
  61 +
  62 + public doesFilterPass(params) {
  63 +
  64 + var rowSkills = params.data.skills;
  65 + var model = this.model;
  66 + var passed = true;
  67 +
  68 + RefData.IT_SKILLS.forEach(function (skill) {
  69 + if (model[skill]) {
  70 + if (!rowSkills[skill]) {
  71 + passed = false;
  72 + }
  73 + }
  74 + });
  75 +
  76 + return passed;
  77 + };
  78 +
  79 + public isFilterActive() {
  80 + var model = this.model;
  81 + var somethingSelected = model.android || model.css || model.html5 || model.mac || model.windows;
  82 + return somethingSelected;
  83 + };
  84 +
  85 + public getModel():any {
  86 + return undefined;
  87 + }
  88 +
  89 + public setModel(model:any):void {
  90 + }
  91 +}
  92 +
... ...