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

Commit d38e8b3

Browse files
committed
feat(filter): add collectionLazy callback to Column Filter
1 parent 6f6b134 commit d38e8b3

File tree

9 files changed

+151
-99
lines changed

9 files changed

+151
-99
lines changed

docs/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Documentation
22

3-
The [`docs`](https://github.com/ghiscoding/Angular-Slickgrid/tree/master/docs) folder of Angular-Slickgrid is the one-stop-shop for all project related documentation.
3+
The [`docs`](https://github.com/ghiscoding/Angular-Slickgrid/tree/master/docs) folder of Angular-Slickgrid is the one-stop-shop for all project related documentation.
44

5-
Feel free to contribution documentation fixes by editing any of the markdown files in the [`docs`](https://github.com/ghiscoding/Angular-Slickgrid/tree/master/docs) folder.
5+
Feel free to contribute documentation fixes by editing any of the markdown files in the [`docs`](https://github.com/ghiscoding/Angular-Slickgrid/tree/master/docs) folder.

docs/column-functionalities/editors/select-dropdown-editor.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ this.columnDefinitions = [
173173
```
174174
175175
### Collection Watch
176-
Sometime you wish that whenever you change your filter collection, you'd like the filter to be updated, it won't do that by default but you could use `enableCollectionWatch` for that purpose to add collection observers and re-render the Filter DOM element whenever the collection changes. Also note that using `collectionAsync` will automatically watch for changes, so there's no need to enable this flag for that particular use case.
176+
Sometime you wish that whenever you make a change in your filter collection, you'd like the filter to be updated but it won't do that by default. You could use `enableCollectionWatch` for that purpose which will add a collection observers and re-render the Filter DOM element whenever the collection changes. Also note that using `collectionAsync` will automatically watch for changes, so there's no need to enable this flag for that particular use case.
177177
178178
```typescript
179179
this.columnDefinitions = [

docs/column-functionalities/filters/select-filter.md

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,16 @@
66
- [How to add Translation](#how-to-add-translation)
77
- [How to filter empty values](#how-to-filter-empty-values)
88
- Collection Options
9-
- [Add Blank Entry](#collection-add-blank-entry)
10-
- [Add Custom Entry at Beginning/End of Collection](#collection-add-custom-entry-at-the-beginningend-of-the-collection)
11-
- [Custom Structure](#custom-structure-keylabel-pair)
12-
- [Custom Structure with Translation](#custom-structure-with-translation)
13-
- [Collection filterBy/sortBy](#collection-filterbysortby)
14-
- [Collection Label Prefix/Suffix](#collection-label-prefixsuffix)
15-
- [Collection Label Render HTML](#collection-label-render-html)
16-
- [Collection Async Load](#collection-async-load)
17-
- [Collection Watch](#collection-watch)
9+
- [Add Blank Entry](#collection-add-blank-entry)
10+
- [Add Custom Entry at Beginning/End of Collection](#collection-add-custom-entry-at-the-beginningend-of-the-collection)
11+
- [Custom Structure](#custom-structure-keylabel-pair)
12+
- [Custom Structure with Translation](#custom-structure-with-translation)
13+
- [Collection filterBy/sortBy](#collection-filterbysortby)
14+
- [Collection Label Prefix/Suffix](#collection-label-prefixsuffix)
15+
- [Collection Label Render HTML](#collection-label-render-html)
16+
- [Collection Async Load](#collection-async-load)
17+
- [Collection Lazy Load](#collection-lazy-load)
18+
- [Collection Watch](#collection-watch)
1819
- [`multiple-select.js` Options](#multiple-selectjs-options)
1920
- [Filter Options (`MultipleSelectOption` interface)](#filter-options-multipleselectoption-interface)
2021
- [Display shorter selected label text](#display-shorter-selected-label-text)
@@ -536,6 +537,24 @@ For example
536537
}
537538
```
538539

540+
### Collection Lazy Load
541+
In some cases, you might have a grid with a lot of columns and loading the collection only after opening the select dropdown (or never in some cases) might help speeding up the initial grid loading. So for that use case, defining a `collectionLazy` callback can help.
542+
543+
#### Load the collection through an Http callback
544+
545+
```ts
546+
this.columnDefinitions = [
547+
{
548+
id: 'prerequisites', name: 'Prerequisites', field: 'prerequisites',
549+
filterable: true,
550+
filter: {
551+
collectionLazy: (col: Column) => this.http.fetch('api/data/pre-requisites'),
552+
model: Filters.multipleSelect,
553+
}
554+
}
555+
];
556+
```
557+
539558
### Collection Watch
540559
We can enable the collection watch via the column filter `enableCollectionWatch` flag, or if you use a `collectionAsync` then this will be enabled by default. The collection watch will basically watch for any changes applied to the collection (any mutation changes like `push`, `pop`, `unshift`, ...) and will also watch for the `filter.collection` array replace, when any changes happens then it will re-render the Select Filter with the updated collection list.
541560

package.json

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,13 @@
5252
},
5353
"dependencies": {
5454
"@ngx-translate/core": "^15.0.0",
55-
"@slickgrid-universal/common": "~5.13.4",
56-
"@slickgrid-universal/custom-footer-component": "~5.13.4",
57-
"@slickgrid-universal/empty-warning-component": "~5.13.4",
55+
"@slickgrid-universal/common": "5.14.0",
56+
"@slickgrid-universal/custom-footer-component": "5.14.0",
57+
"@slickgrid-universal/empty-warning-component": "5.14.0",
5858
"@slickgrid-universal/event-pub-sub": "~5.13.0",
59-
"@slickgrid-universal/pagination-component": "~5.13.4",
60-
"@slickgrid-universal/row-detail-view-plugin": "~5.13.4",
61-
"@slickgrid-universal/rxjs-observable": "~5.13.4",
59+
"@slickgrid-universal/pagination-component": "5.14.0",
60+
"@slickgrid-universal/row-detail-view-plugin": "5.14.0",
61+
"@slickgrid-universal/rxjs-observable": "5.14.0",
6262
"dequal": "^2.0.3",
6363
"rxjs": "^7.8.2"
6464
},
@@ -98,12 +98,12 @@
9898
"@nx/vite": "^20.7.2",
9999
"@popperjs/core": "^2.11.8",
100100
"@release-it/conventional-changelog": "^10.0.0",
101-
"@slickgrid-universal/composite-editor-component": "~5.13.4",
102-
"@slickgrid-universal/custom-tooltip-plugin": "~5.13.4",
103-
"@slickgrid-universal/excel-export": "~5.13.4",
104-
"@slickgrid-universal/graphql": "~5.13.4",
105-
"@slickgrid-universal/odata": "~5.13.4",
106-
"@slickgrid-universal/text-export": "~5.13.4",
101+
"@slickgrid-universal/composite-editor-component": "5.14.0",
102+
"@slickgrid-universal/custom-tooltip-plugin": "5.14.0",
103+
"@slickgrid-universal/excel-export": "5.14.0",
104+
"@slickgrid-universal/graphql": "5.14.0",
105+
"@slickgrid-universal/odata": "5.14.0",
106+
"@slickgrid-universal/text-export": "5.14.0",
107107
"@types/fnando__sparkline": "^0.3.7",
108108
"@types/node": "^22.14.0",
109109
"@types/sortablejs": "^1.15.8",

src/app/examples/grid-custom-tooltip.component.html

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,14 @@ <h2>
2121
</h2>
2222
<div class="subtitle" [innerHTML]="subTitle"></div>
2323

24-
<div style="margin-bottom: 20px">
25-
<label for="pinned-rows">Simulated Server Delay (ms): </label>
26-
<input type="number" id="server-delay" data-test="server-delay" style="width: 60px" [(ngModel)]="serverApiDelay" />
24+
<div class="row">
25+
<div class="col" style="margin-bottom: 20px">
26+
<label for="pinned-rows">Simulated Server Delay (ms): </label>
27+
<input type="number" id="server-delay" data-test="server-delay" style="width: 60px" [(ngModel)]="serverApiDelay" />
28+
</div>
29+
<div class="alert alert-info is-narrow col" [ngClass]="!showLazyLoading ? 'invisible' : ''" data-test="alert-lazy">
30+
Lazy loading collection...
31+
</div>
2732
</div>
2833

2934
<angular-slickgrid

src/app/examples/grid-custom-tooltip.component.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
SlickGrid,
1717
} from '../modules/angular-slickgrid';
1818

19-
const NB_ITEMS = 500;
19+
const NB_ITEMS = 1000;
2020

2121
@Component({
2222
templateUrl: './grid-custom-tooltip.component.html',
@@ -41,6 +41,7 @@ export class GridCustomTooltipComponent implements OnInit {
4141
gridOptions!: GridOption;
4242
dataset!: any[];
4343
serverApiDelay = 500;
44+
showLazyLoading = false;
4445
hideSubTitle = false;
4546

4647
ngOnInit(): void {
@@ -309,12 +310,23 @@ export class GridCustomTooltipComponent implements OnInit {
309310
model: Editors.multipleSelect,
310311
},
311312
filter: {
312-
// collectionAsync: fetch(URL_SAMPLE_COLLECTION_DATA),
313-
collectionAsync: new Promise((resolve) => {
314-
window.setTimeout(() => {
315-
resolve(Array.from(Array(this.dataset.length).keys()).map((k) => ({ value: k, label: `Task ${k}` })));
313+
// collectionAsync: fetch(SAMPLE_COLLECTION_DATA_URL),
314+
// collectionAsync: new Promise((resolve) => {
315+
// window.setTimeout(() => {
316+
// resolve(Array.from(Array(dataset.value?.length).keys()).map((k) => ({ value: k, label: `Task ${k}` })));
317+
// });
318+
// }),
319+
collectionLazy: () => {
320+
this.showLazyLoading = true;
321+
322+
return new Promise((resolve) => {
323+
window.setTimeout(() => {
324+
this.showLazyLoading = false;
325+
resolve(Array.from(Array((this.dataset || []).length).keys()).map((k) => ({ value: k, label: `Task ${k}` })));
326+
}, this.serverApiDelay);
316327
});
317-
}),
328+
},
329+
// onInstantiated: (msSelect) => console.log('ms-select instance', msSelect),
318330
customStructure: {
319331
label: 'label',
320332
value: 'value',
@@ -323,6 +335,9 @@ export class GridCustomTooltipComponent implements OnInit {
323335
collectionOptions: {
324336
separatorBetweenTextLabels: ' ',
325337
},
338+
filterOptions: {
339+
minHeight: 70,
340+
},
326341
model: Filters.multipleSelect,
327342
operator: OperatorType.inContains,
328343
},

src/styles.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ $button-style-bg-color: #fff;
3434
display: none;
3535
}
3636

37+
.invisible {
38+
opacity: 0;
39+
}
40+
3741
.btn-group-xs > .btn,
3842
.btn-xs {
3943
padding: 1px 5px;

test/cypress/e2e/example32.cy.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ describe('Example 32 - Regular & Custom Tooltips', () => {
2828
});
2929

3030
it('should change server delay to 10ms for faster testing', () => {
31-
cy.get('[data-test="server-delay"]').type('{backspace}{backspace}{backspace}10');
31+
cy.get('[data-test="server-delay"]').clear().type('50');
3232
});
3333

3434
it('should mouse over 1st row checkbox column and NOT expect any tooltip to show since it is disabled on that column', () => {
@@ -83,7 +83,7 @@ describe('Example 32 - Regular & Custom Tooltips', () => {
8383
it('should mouse over Task 6 cell on "Start" column and expect a delayed tooltip opening via async process', () => {
8484
cy.get('.slick-custom-tooltip').should('not.exist');
8585
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(7)`).as('start6-cell');
86-
cy.get('@start6-cell').contains(/\d{4}-\d{1,2}-\d{1,2}$/); // use regexp to make sure it's a number
86+
cy.get('@start6-cell').contains(/\d{4}-\d{2}-\d{2}$/); // use regexp to make sure it's a number
8787
cy.get('@start6-cell').trigger('mouseover');
8888

8989
cy.wait(10);
@@ -211,11 +211,20 @@ describe('Example 32 - Regular & Custom Tooltips', () => {
211211
cy.get('@finish-filter').trigger('mouseout');
212212
});
213213

214+
it('should open PreRequisite dropdown and expect it be lazily loaded', () => {
215+
cy.get('.slick-headerrow-columns .slick-headerrow-column:nth(10)').as('checkbox10-header');
216+
cy.get('@checkbox10-header').click();
217+
cy.get('[data-test="alert-lazy"]').should('be.visible');
218+
cy.wait(50);
219+
cy.get('@checkbox10-header').click();
220+
cy.get('[data-test="alert-lazy"]').should('not.be.visible');
221+
});
222+
214223
it('should mouse over header-row (filter) Prerequisite column and expect to see tooltip of selected filter options', () => {
215-
cy.get(`.slick-headerrow-columns .slick-headerrow-column:nth(10)`).as('checkbox10-header');
224+
cy.get('.slick-headerrow-columns .slick-headerrow-column:nth(10)').as('checkbox10-header');
216225
cy.get('@checkbox10-header').trigger('mouseover');
217226

218-
cy.get('.filter-prerequisites .ms-choice span').contains('15 of 500 selected');
227+
cy.get('.filter-prerequisites .ms-choice span').contains('15 of 1000 selected');
219228
cy.get('.slick-custom-tooltip').should('be.visible');
220229
cy.get('.slick-custom-tooltip').contains(
221230
'Task 1, Task 3, Task 5, Task 7, Task 9, Task 12, Task 15, Task 18, Task 21, Task 25, Task 28, Task 29, Task 30, Task 32, Task 34'
@@ -225,15 +234,15 @@ describe('Example 32 - Regular & Custom Tooltips', () => {
225234
});
226235

227236
it('should mouse over header title on 1st column with checkbox and NOT expect any tooltip to show since it is disabled on that column', () => {
228-
cy.get(`.slick-header-columns .slick-header-column:nth(0)`).as('checkbox-header');
237+
cy.get('.slick-header-columns .slick-header-column:nth(0)').as('checkbox-header');
229238
cy.get('@checkbox-header').trigger('mouseover');
230239

231240
cy.get('.slick-custom-tooltip').should('not.exist');
232241
cy.get('@checkbox-header').trigger('mouseout');
233242
});
234243

235244
it('should mouse over header title on 2nd column with Title name and expect a tooltip to show rendered from an headerFormatter', () => {
236-
cy.get(`.slick-header-columns .slick-header-column:nth(1)`).as('checkbox0-header');
245+
cy.get('.slick-header-columns .slick-header-column:nth(1)').as('checkbox0-header');
237246
cy.get('@checkbox0-header').trigger('mouseover');
238247

239248
cy.get('.slick-custom-tooltip').should('be.visible');
@@ -246,7 +255,7 @@ describe('Example 32 - Regular & Custom Tooltips', () => {
246255
});
247256

248257
it('should mouse over header title on 2nd column with Finish name and NOT expect any tooltip to show since it is disabled on that column', () => {
249-
cy.get(`.slick-header-columns .slick-header-column:nth(8)`).as('finish-header');
258+
cy.get('.slick-header-columns .slick-header-column:nth(8)').as('finish-header');
250259
cy.get('@finish-header').trigger('mouseover');
251260

252261
cy.get('.slick-custom-tooltip').should('not.exist');

0 commit comments

Comments
 (0)