Skip to content
This repository was archived by the owner on Jun 1, 2025. It is now read-only.

Commit cc386d2

Browse files
Ghislain BeaulacGhislain Beaulac
authored andcommitted
Add GridExtraService with Highlight and RowSelection, replaced mouse hover highlight with pure CSS.
1 parent c72cdb5 commit cc386d2

18 files changed

+257
-126
lines changed

.editorconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ indent_size = 4
99
insert_final_newline = true
1010
trim_trailing_whitespace = true
1111

12-
[*.{js,json,ts}]
12+
[*.{js,json,ts,css,scss}]
1313
indent_style = space
1414
indent_size = 2
1515

src/app/examples/grid-editor.component.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Component, OnInit } from '@angular/core';
2-
import { Column, Editors, FieldType, Formatter, Formatters, GridExtraUtils, GridOption, OnEventArgs, ResizerService } from './../modules/angular-slickgrid';
2+
import { Column, Editors, FieldType, Formatter, Formatters, GridExtraService, GridExtraUtils, GridOption, OnEventArgs, ResizerService } from './../modules/angular-slickgrid';
33

44
@Component({
55
templateUrl: './grid-editor.component.html'
@@ -18,7 +18,7 @@ export class GridEditorComponent implements OnInit {
1818
gridObj: any;
1919
dataviewObj: any;
2020

21-
constructor(private resizer: ResizerService) {}
21+
constructor(private gridExtraService: GridExtraService, private resizer: ResizerService) {}
2222

2323
ngOnInit(): void {
2424
this.columnDefinitions = [
@@ -27,18 +27,25 @@ export class GridEditorComponent implements OnInit {
2727
formatter: Formatters.editIcon,
2828
minWidth: 30,
2929
maxWidth: 30,
30+
/*
31+
// use onCellClick OR grid.onClick.subscribe which you can see down below
3032
onCellClick: (args: OnEventArgs) => {
3133
console.log(args);
32-
}
34+
alert(`Editing: ${args.dataContext.title}`);
35+
}*/
3336
},
3437
{
3538
id: 'delete', field: 'id',
3639
formatter: Formatters.deleteIcon,
3740
minWidth: 30,
3841
maxWidth: 30,
42+
/*
43+
// use onCellClick OR grid.onClick.subscribe which you can see down below
3944
onCellClick: (args: OnEventArgs) => {
4045
console.log(args);
46+
alert(`Deleting: ${args.dataContext.title}`);
4147
}
48+
*/
4249
},
4350
{ id: 'title', name: 'Title', field: 'title', sortable: true, type: FieldType.string, editor: Editors.longText },
4451
{ id: 'duration', name: 'Duration (days)', field: 'duration', sortable: true, type: FieldType.number, editor: Editors.text,
@@ -54,15 +61,15 @@ export class GridEditorComponent implements OnInit {
5461
];
5562

5663
this.gridOptions = {
64+
asyncEditorLoading: false,
65+
autoEdit: this.isAutoEdit,
5766
autoResize: {
5867
containerId: 'demo-container',
5968
sidePadding: 15
6069
},
6170
editable: true,
6271
enableColumnPicker: true,
63-
enableCellNavigation: true,
64-
asyncEditorLoading: false,
65-
autoEdit: this.isAutoEdit
72+
enableCellNavigation: true
6673
};
6774

6875
// mock a dataset
@@ -100,6 +107,12 @@ export class GridEditorComponent implements OnInit {
100107
console.log('onClick', args, column);
101108
if (column.columnDef.id === 'edit') {
102109
alert('open a modal window to edit: ' + column.dataContext.title);
110+
111+
// highlight the row, to customize the color, you can change the SASS variable $row-highlight-background-color
112+
this.gridExtraService.highlightRow(args.row, 1500);
113+
114+
// you could also select the row, when using "enableCellNavigation: true", it automatically selects the row
115+
// this.gridExtraService.setSelectedRow(args.row);
103116
} else if (column.columnDef.id === 'delete') {
104117
if (confirm('Are you sure?')) {
105118
this.dataviewObj.deleteItem(column.dataContext.id);

src/app/examples/grid-headerbutton.component.ts

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,23 +47,25 @@ export class GridHeaderButtonComponent implements OnInit {
4747
},
4848
enableFiltering: false,
4949
enableCellNavigation: true,
50-
onHeaderButtonCommand: (e, args) => {
51-
const column = args.column;
52-
const button = args.button;
53-
const command = args.command;
50+
headerButtonOptions: {
51+
onCommand: (e, args) => {
52+
const column = args.column;
53+
const button = args.button;
54+
const command = args.command;
5455

55-
if (command === 'toggle-highlight') {
56-
if (button.cssClass === 'fa fa-circle red') {
57-
delete columnsWithHighlightingById[column.id];
58-
button.cssClass = 'fa fa-circle-o red faded';
59-
button.tooltip = 'Highlight negative numbers.';
60-
} else {
61-
columnsWithHighlightingById[column.id] = true;
62-
button.cssClass = 'fa fa-circle red';
63-
button.tooltip = 'Remove highlight.';
64-
}
56+
if (command === 'toggle-highlight') {
57+
if (button.cssClass === 'fa fa-circle red') {
58+
delete columnsWithHighlightingById[column.id];
59+
button.cssClass = 'fa fa-circle-o red faded';
60+
button.tooltip = 'Highlight negative numbers.';
61+
} else {
62+
columnsWithHighlightingById[column.id] = true;
63+
button.cssClass = 'fa fa-circle red';
64+
button.tooltip = 'Remove highlight.';
65+
}
6566

66-
this.gridObj.invalidate();
67+
this.gridObj.invalidate();
68+
}
6769
}
6870
}
6971
};

src/app/examples/grid-headermenu.component.ts

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -87,31 +87,33 @@ export class GridHeaderMenuComponent implements OnInit {
8787
},
8888
enableFiltering: false,
8989
enableCellNavigation: true,
90-
onHeaderMenuCommand: (e, args) => {
91-
if (args.command === 'hide') {
92-
this.controlService.hideColumn(args.column);
93-
this.controlService.autoResizeColumns();
94-
} else if (args.command === 'sort-asc' || args.command === 'sort-desc') {
95-
// get previously sorted columns
96-
// getSortColumns() only returns sortAsc & columnId, we want the entire column definition
97-
const oldSortColumns = this.gridObj.getSortColumns();
98-
const cols = $.map(oldSortColumns, (col) => {
99-
// get the column definition but only keep column which are not equal to our current column
100-
if (col.columnId !== args.column.id) {
101-
return { sortCol: this.columnDefinitions[this.gridObj.getColumnIndex(col.columnId)], sortAsc: col.sortAsc };
102-
}
103-
});
104-
// add to the column array, the column sorted by the header menu
105-
const isSortedAsc = (args.command === 'sort-asc');
106-
cols.push({ sortAsc: isSortedAsc, sortCol: args.column });
107-
// update the this.gridObj sortColumns array which will at the same add the visual sort icon(s) on the UI
108-
const newSortColumns = $.map(cols, (col) => {
109-
return { columnId: col.sortCol.id, sortAsc: col.sortAsc };
110-
});
111-
this.gridObj.setSortColumns(newSortColumns);
112-
this.executeSort(cols);
113-
} else {
114-
alert('Command: ' + args.command);
90+
headerMenuOptions: {
91+
onCommand: (e, args) => {
92+
if (args.command === 'hide') {
93+
this.controlService.hideColumn(args.column);
94+
this.controlService.autoResizeColumns();
95+
} else if (args.command === 'sort-asc' || args.command === 'sort-desc') {
96+
// get previously sorted columns
97+
// getSortColumns() only returns sortAsc & columnId, we want the entire column definition
98+
const oldSortColumns = this.gridObj.getSortColumns();
99+
const cols = $.map(oldSortColumns, (col) => {
100+
// get the column definition but only keep column which are not equal to our current column
101+
if (col.columnId !== args.column.id) {
102+
return { sortCol: this.columnDefinitions[this.gridObj.getColumnIndex(col.columnId)], sortAsc: col.sortAsc };
103+
}
104+
});
105+
// add to the column array, the column sorted by the header menu
106+
const isSortedAsc = (args.command === 'sort-asc');
107+
cols.push({ sortAsc: isSortedAsc, sortCol: args.column });
108+
// update the this.gridObj sortColumns array which will at the same add the visual sort icon(s) on the UI
109+
const newSortColumns = $.map(cols, (col) => {
110+
return { columnId: col.sortCol.id, sortAsc: col.sortAsc };
111+
});
112+
this.gridObj.setSortColumns(newSortColumns);
113+
this.executeSort(cols);
114+
} else {
115+
alert('Command: ' + args.command);
116+
}
115117
}
116118
}
117119
};

src/app/examples/grid-menu.component.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -108,20 +108,20 @@ export class GridMenuComponent implements OnInit {
108108
disabled: true,
109109
command: 'disabled-command'
110110
}
111-
]
112-
},
113-
onGridMenuCommand: (e, args) => {
114-
if (args.command === 'toggle-filter') {
115-
this.gridObj.setHeaderRowVisibility(!this.gridObj.getOptions().showHeaderRow);
116-
} else if (args.command === 'toggle-toppanel') {
117-
this.gridObj.setTopPanelVisibility(!this.gridObj.getOptions().showTopPanel);
118-
} else if (args.command === 'clear-filter') {
119-
this.filterService.clearFilters();
120-
this.dataviewObj.refresh();
121-
} else {
122-
alert('Command: ' + args.command);
111+
],
112+
onCommand: (e, args) => {
113+
if (args.command === 'toggle-filter') {
114+
this.gridObj.setHeaderRowVisibility(!this.gridObj.getOptions().showHeaderRow);
115+
} else if (args.command === 'toggle-toppanel') {
116+
this.gridObj.setTopPanelVisibility(!this.gridObj.getOptions().showTopPanel);
117+
} else if (args.command === 'clear-filter') {
118+
this.filterService.clearFilters();
119+
this.dataviewObj.refresh();
120+
} else {
121+
alert('Command: ' + args.command);
122+
}
123123
}
124-
}
124+
},
125125
};
126126

127127
this.getData();

src/app/modules/angular-slickgrid/components/angular-slickgrid.component.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ import 'slickgrid/plugins/slick.headermenu';
2020
import 'slickgrid/plugins/slick.rowmovemanager';
2121
import 'slickgrid/plugins/slick.rowselectionmodel';
2222
import { AfterViewInit, Component, EventEmitter , Injectable, Input, Output, OnInit } from '@angular/core';
23-
import { castToPromise, immutableMerge } from './../services/utilities';
23+
import { castToPromise } from './../services/utilities';
2424
import { GlobalGridOptions } from './../global-grid-options';
2525
import { CellArgs, Column, FormElementType, GridOption } from './../models';
26-
import { ControlAndPluginService, FilterService, GridEventService, SortService, ResizerService } from './../services';
26+
import { ControlAndPluginService, FilterService, GridEventService, GridExtraService, SortService, ResizerService } from './../services';
27+
import $ from 'jquery';
2728

2829
// using external js modules in Angular
2930
declare var Slick: any;
@@ -72,6 +73,7 @@ export class AngularSlickgridComponent implements AfterViewInit, OnInit {
7273
constructor(
7374
private controlAndPluginService: ControlAndPluginService,
7475
private gridEventService: GridEventService,
76+
private gridExtraService: GridExtraService,
7577
private filterService: FilterService,
7678
private resizer: ResizerService,
7779
private sortService: SortService
@@ -105,6 +107,9 @@ export class AngularSlickgridComponent implements AfterViewInit, OnInit {
105107

106108
// attach resize ONLY after the dataView is ready
107109
this.attachResizeHook(this.grid, this._gridOptions);
110+
111+
// attach grid extra service
112+
const gridExtraService = this.gridExtraService.init(this.grid, this._dataView);
108113
}
109114

110115
attachDifferentHooks(grid: any, options: GridOption, dataView: any) {
@@ -141,11 +146,6 @@ export class AngularSlickgridComponent implements AfterViewInit, OnInit {
141146
this.gridEventService.attachOnCellChange(grid, this._gridOptions, dataView);
142147
this.gridEventService.attachOnClick(grid, this._gridOptions, dataView);
143148

144-
// if enable, change background color on mouse over
145-
if (options.enableMouseHoverHighlightRow) {
146-
this.gridEventService.attachOnMouseHover(grid);
147-
}
148-
149149
dataView.onRowCountChanged.subscribe((e: any, args: any) => {
150150
grid.updateRowCount();
151151
grid.render();
@@ -179,9 +179,8 @@ export class AngularSlickgridComponent implements AfterViewInit, OnInit {
179179
if (this.gridOptions.enableFiltering) {
180180
this.gridOptions.showHeaderRow = true;
181181
}
182-
// use an immutable merge to avoid changing properties in GlobalGridOptions when changing route
183-
const options = immutableMerge(GlobalGridOptions, this.gridOptions);
184-
return options;
182+
// use jquery extend to deep merge and avoid immutable properties changed in GlobalGridOptions after route change
183+
return $.extend(true, {}, GlobalGridOptions, this.gridOptions);
185184
}
186185

187186
/** Toggle the filter row displayed on first row */

src/app/modules/angular-slickgrid/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export { ControlAndPluginService } from './services/controlAndPlugin.service';
4545
export { FilterService } from './services/filter.service';
4646
export { GridEventService } from './services/gridEvent.service';
4747
export { GraphqlService } from './services/graphql.service';
48+
export { GridExtraService } from './services/gridExtra.service';
4849
export { GridExtraUtils } from './services/gridExtraUtils';
4950
export { GridOdataService } from './services/grid-odata.service';
5051
export { ResizerService } from './services/resizer.service';

src/app/modules/angular-slickgrid/models/gridMenu.interface.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,8 @@ export interface GridMenu {
99
menuWidth?: number;
1010
resizeOnShowHeaderRow?: boolean;
1111
customItems?: CustomGridMenu[];
12+
13+
onBeforeMenuShow?: (e: Event, args: any) => void;
14+
onMenuClose?: (e: Event, args: any) => void;
15+
onCommand?: (e: Event, args: any) => void;
1216
}

src/app/modules/angular-slickgrid/models/gridOption.interface.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,15 @@ export interface GridOption {
4040
headerRowHeight?: number;
4141
headerButtonOptions?: {
4242
buttonCssClass?: string;
43+
onCommand?: (e: Event, args: any) => void;
4344
};
4445
headerMenuOptions?: {
4546
buttonCssClass?: string;
4647
buttonImage?: string;
48+
onCommand?: (e: Event, args: any) => void;
4749
};
4850
multiColumnSort?: boolean;
4951
onBackendEventApi?: BackendEventChanged;
50-
onGridMenuCommand?: (e: Event, args: any) => void;
51-
onHeaderButtonCommand?: (e: Event, args: any) => void;
52-
onHeaderMenuCommand?: (e: Event, args: any) => void;
5352
pagination?: Pagination;
5453
registerPlugins?: any | any[]; // e.g.: Slick.CheckboxSelectColumn
5554
rowHeight?: number;

src/app/modules/angular-slickgrid/modules/angular-slickgrid.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ControlAndPluginService } from '../services/controlAndPlugin.service';
55
import { Formatters } from './../formatters';
66
import { FilterService } from './../services/filter.service';
77
import { GridEventService } from './../services/gridEvent.service';
8+
import { GridExtraService } from '../services/gridExtra.service';
89
import { GraphqlService } from './../services/graphql.service';
910
import { OdataService } from './../services/odata.service';
1011
import { ResizerService } from './../services/resizer.service';
@@ -27,6 +28,7 @@ import { SortService } from './../services/sort.service';
2728
ControlAndPluginService,
2829
GraphqlService,
2930
GridEventService,
31+
GridExtraService,
3032
OdataService,
3133
FilterService,
3234
SortService,

0 commit comments

Comments
 (0)