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

Commit ba6082c

Browse files
committed
feat(example): add Bootstrap Dropdown Action demo, closes #304
1 parent de52614 commit ba6082c

File tree

4 files changed

+73
-2
lines changed

4 files changed

+73
-2
lines changed

src/app/app.module.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { TranslateModule, TranslateLoader, TranslateService } from '@ngx-transla
1010
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
1111

1212
import { AppComponent } from './app.component';
13+
import { CustomActionFormatterComponent } from './examples/custom-actionFormatter.component';
1314
import { CustomTitleFormatterComponent } from './examples/custom-titleFormatter.component';
1415
import { EditorNgSelectComponent } from './examples/editor-ng-select.component';
1516
import { FilterNgSelectComponent } from './examples/filter-ng-select.component';
@@ -77,6 +78,7 @@ export function appInitializerFactory(translate: TranslateService, injector: Inj
7778
@NgModule({
7879
declarations: [
7980
AppComponent,
81+
CustomActionFormatterComponent,
8082
CustomTitleFormatterComponent,
8183
EditorNgSelectComponent,
8284
FilterNgSelectComponent,
@@ -137,6 +139,7 @@ export function appInitializerFactory(translate: TranslateService, injector: Inj
137139
],
138140
entryComponents: [
139141
// dynamically created components
142+
CustomActionFormatterComponent,
140143
CustomTitleFormatterComponent,
141144
EditorNgSelectComponent,
142145
FilterNgSelectComponent,
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Component } from '@angular/core';
2+
3+
@Component({
4+
template: `<div id="myDrop" class="dropdown" style="position:absolute; z-index:12000;">
5+
<button class="btn btn-default btn-xs dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
6+
Action
7+
<span class="caret"></span>
8+
</button>
9+
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
10+
<li><a class="pointer" (click)="parent.deleteCell(row)">Delete Row</a></li>
11+
</ul></div>`
12+
})
13+
export class CustomActionFormatterComponent {
14+
parent: any;
15+
}

src/app/examples/grid-angular.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ <h2>{{title}}</h2>
4848
(sgOnCellChange)="onCellChanged($event.detail.eventData, $event.detail.args)"
4949
(sgOnClick)="onCellClicked($event.detail.eventData, $event.detail.args)"
5050
(sgOnValidationError)="onCellValidation($event.detail.eventData, $event.detail.args)"
51+
(sgOnActiveCellChanged)="onActiveCellChanged($event.detail.eventData, $event.detail.args)"
5152
[columnDefinitions]="columnDefinitions" [gridOptions]="gridOptions" [dataset]="dataset">
5253
</angular-slickgrid>
5354
</div>

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

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ import {
77
Editors,
88
FieldType,
99
Filters,
10+
Formatter,
1011
Formatters,
1112
GridOption,
1213
OnEventArgs,
1314
} from './../modules/angular-slickgrid';
1415
import { EditorNgSelectComponent } from './editor-ng-select.component';
16+
import { CustomActionFormatterComponent } from './custom-actionFormatter.component';
1517
import { CustomAngularComponentEditor } from './custom-angularComponentEditor';
1618
import { CustomAngularComponentFilter } from './custom-angularComponentFilter';
1719
import { CustomTitleFormatterComponent } from './custom-titleFormatter.component';
@@ -23,6 +25,17 @@ declare var $: any;
2325

2426
const NB_ITEMS = 100;
2527

28+
const customActionFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any, grid: any) => {
29+
// use the same button text "Action" as the "CustomActionFormatterComponent" button text
30+
// we basically recreate a dropdown on top of this one here which is just an empty one to show something in the grid
31+
return `<div id="myDrop-r${row}-c${cell}" class="dropdown">
32+
<button class="btn btn-default btn-xs dropdown-toggle" type="button">
33+
Action
34+
<span class="caret"></span>
35+
</button>
36+
</div>`;
37+
};
38+
2639
@Component({
2740
templateUrl: './grid-angular.component.html',
2841
styleUrls: ['./grid-angular.component.scss'],
@@ -218,7 +231,8 @@ export class GridAngularComponent implements OnInit {
218231
editor: {
219232
model: Editors.date
220233
},
221-
}
234+
},
235+
{ id: 'action', name: 'Action', field: 'id', formatter: customActionFormatter, width: 70 }
222236
];
223237

224238
this.gridOptions = {
@@ -329,8 +343,46 @@ export class GridAngularComponent implements OnInit {
329343
const componentOutput = this.angularUtilService.createAngularComponent(colDef.params.component);
330344
Object.assign(componentOutput.componentRef.instance, { item: dataContext });
331345

332-
// use a delay to make sure Angular ran at least a full cycle and it finished rendering the Component
346+
// use a delay to make sure Angular ran at least a full cycle and make sure it finished rendering the Component
333347
setTimeout(() => $(cellNode).empty().html(componentOutput.domElement));
334348
}
335349
}
350+
351+
/* Create an Action Dropdown Menu */
352+
deleteCell(rowNumber: number) {
353+
const item = this.angularGrid.dataView.getItem(rowNumber);
354+
this.angularGrid.gridService.deleteItemById(item.id);
355+
}
356+
357+
onActiveCellChanged(event, args) {
358+
if (args.cell !== 6) {
359+
return; // don't do anything unless it's the Action column which is at position 6 in this grid
360+
}
361+
362+
$('#myDrop').remove(); // make sure to remove previous Action dropdown, you don't want to have 100 after a 100 clicks...
363+
const cell = args.cell;
364+
const row = args.row;
365+
366+
// hide the dropdown we created as a Formatter, we'll redisplay it later
367+
const cellPos = $(`#myDrop-r${row}-c${cell}`).offset();
368+
369+
const componentOutput = this.angularUtilService.createAngularComponent(CustomActionFormatterComponent);
370+
371+
// pass "this" and the row number to the Component instance (CustomActionFormatter) so that we can call "parent.deleteCell(row)" with (click)
372+
Object.assign(componentOutput.componentRef.instance, { parent: this, row: args.row });
373+
374+
// use a delay to make sure Angular ran at least a full cycle and make sure it finished rendering the Component before using it
375+
setTimeout(() => {
376+
const elm = $(componentOutput.domElement);
377+
elm.appendTo('body');
378+
elm.css('position', 'absolute');
379+
elm.css('top', cellPos.top + 5);
380+
elm.css('left', cellPos.left);
381+
$('#myDrop').addClass('open');
382+
383+
$('#myDrop').on('hidden.bs.dropdown', () => {
384+
$(`#myDrop-r${row}-c${cell}`).show();
385+
});
386+
});
387+
}
336388
}

0 commit comments

Comments
 (0)