Skip to content
This repository was archived by the owner on Jun 1, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/examples/slickgrid/Example45.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default class Example45 extends React.Component<Props, State> {
// return this.extensions.rowDetailView.instance || {};

// OR option 2
return this.reactGrid?.extensionService.getExtensionInstanceByName(ExtensionName.rowDetailView);
return this.reactGrid?.extensionService.getExtensionInstanceByName(ExtensionName.rowDetailView) as SlickRowDetailView;
}

componentDidMount() {
Expand Down Expand Up @@ -253,6 +253,10 @@ export default class Example45 extends React.Component<Props, State> {
this.rowDetailInstance.collapseAll();
}

redrawAllRowDetail() {
this.rowDetailInstance.redrawAllViewComponents(true);
}

detailViewRowCountChanged(val: number | string) {
this.setState((state: State) => ({ ...state, detailViewRowCount: +val }));
}
Expand Down Expand Up @@ -315,7 +319,9 @@ export default class Example45 extends React.Component<Props, State> {
<button className="btn btn-outline-secondary btn-sm btn-icon ms-1" data-test="collapse-all-btn" onClick={() => this.closeAllRowDetail()}>
Close all Row Details
</button>
&nbsp;&nbsp;
<button className="btn btn-outline-secondary btn-sm btn-icon mx-1" data-test="redraw-all-btn" onClick={() => this.redrawAllRowDetail()}>
Force redraw all Row Details
</button>

<span className="d-inline-flex gap-4px">
<label htmlFor="detailViewRowCount">Detail View Rows Shown: </label>
Expand Down
18 changes: 6 additions & 12 deletions src/slickgrid-react/extensions/slickRowDetailView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,19 +198,19 @@ export class SlickRowDetailView extends UniversalSlickRowDetailView {
// hook some events needed by the Plugin itself

// we need to redraw the open detail views if we change column position (column reorder)
this.eventHandler.subscribe(this._grid.onColumnsReordered, this.redrawAllViewComponents.bind(this));
this.eventHandler.subscribe(this._grid.onColumnsReordered, this.redrawAllViewComponents.bind(this, false));

// on row selection changed, we also need to redraw
if (this.gridOptions.enableRowSelection || this.gridOptions.enableCheckboxSelector) {
this._eventHandler.subscribe(this._grid.onSelectedRowsChanged, this.redrawAllViewComponents.bind(this));
this._eventHandler.subscribe(this._grid.onSelectedRowsChanged, this.redrawAllViewComponents.bind(this, false));
}

// on column sort/reorder, all row detail are collapsed so we can dispose of all the Views as well
this._eventHandler.subscribe(this._grid.onSort, this.disposeAllViewComponents.bind(this));

// on filter changed, we need to re-render all Views
this._subscriptions.push(
this.eventPubSubService?.subscribe(['onFilterChanged', 'onGridMenuColumnsChanged', 'onColumnPickerColumnsChanged'], this.redrawAllViewComponents.bind(this)),
this.eventPubSubService?.subscribe(['onFilterChanged', 'onGridMenuColumnsChanged', 'onColumnPickerColumnsChanged'], this.redrawAllViewComponents.bind(this, false)),
this.eventPubSubService?.subscribe(['onGridMenuClearAllFilters', 'onGridMenuClearAllSorting'], () => window.setTimeout(() => this.redrawAllViewComponents())),
);
}
Expand All @@ -221,11 +221,12 @@ export class SlickRowDetailView extends UniversalSlickRowDetailView {
}

/** Redraw (re-render) all the expanded row detail View Components */
async redrawAllViewComponents() {
async redrawAllViewComponents(forceRedraw = false) {
this.resetRenderedRows();
const promises: Promise<void>[] = [];
this._views.forEach((view) => {
if (!view.rendered) {
if (!view.rendered || forceRedraw) {
forceRedraw && this.disposeViewComponent(view);
promises.push(this.redrawViewComponent(view))
}
});
Expand Down Expand Up @@ -283,13 +284,6 @@ export class SlickRowDetailView extends UniversalSlickRowDetailView {
} as ViewModelBindableInputData;
const viewObj = this._views.find(obj => obj.id === item[this.datasetIdPropName]);

// remove any previous mounted views, if found then unmount them and delete them from our references array
// const viewIdx = this._views.findIndex((obj) => obj.id === item[this.datasetIdPropName]);
// if (this._views[viewIdx]?.root) {
// this._views[viewIdx].root.unmount();
// this._views.splice(viewIdx, 1);
// }

// load our Row Detail React Component dynamically, typically we would want to use `root.render()` after the preload component (last argument below)
// BUT the root render doesn't seem to work and shows a blank element, so we'll use `createRoot()` every time even though it shows a console log in Dev
// that is the only way I got it working so let's use it anyway and console warnings are removed in production anyway
Expand Down
20 changes: 20 additions & 0 deletions test/cypress/e2e/example45.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,26 @@ describe('Example 45 - Row Detail with inner Grid', () => {
cy.get(`#innergrid-2 [style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', 'München');
});

it('should force redraw of all Row Details and expect same row details to be opened and opened', () => {
cy.get('[data-test="redraw-all-btn"]').click();
cy.wait(10);

// 2nd row detail
cy.get(`#innergrid-1 [style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0)`).should('contain', '10261');
cy.get(`#innergrid-1 [style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('contain', 'Rio de Janeiro');
cy.get(`#innergrid-1 [style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(0)`).should('contain', '10267');
cy.get(`#innergrid-1 [style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', 'München');

// 3rd row detail
cy.get('#innergrid-2 .search-filter.filter-orderId').should('have.value', '');
cy.get('#innergrid-2 .search-filter.filter-shipCity').should('have.value', '');
cy.get('#innergrid-2 .slick-sort-indicator-asc').should('not.exist');
cy.get(`#innergrid-2 [style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0)`).should('contain', '10261');
cy.get(`#innergrid-2 [style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('contain', 'Rio de Janeiro');
cy.get(`#innergrid-2 [style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(0)`).should('contain', '10267');
cy.get(`#innergrid-2 [style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', 'München');
});

it('should close all rows', () => {
cy.get('[data-test="collapse-all-btn"]').click();
});
Expand Down