Skip to content

Commit

Permalink
feat(resizer): add resizeByContentOnlyOnFirstLoad grid option
Browse files Browse the repository at this point in the history
- in many cases doing a resize by content only the first time we get data is enough (default is true) and so this flag will handle that scenario or else if the user always want to resize anytime the data changes then the user could disable this new flag
  • Loading branch information
ghiscoding committed May 12, 2021
1 parent f1e06c1 commit ffe7dc4
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,11 @@ <h4 class="title is-4">Container Width (1000px)</h4>
<span>Save All</span>
</button>
</p>
<span class.bind="loadingClass"></span>
</div>
</div>

<div style="width: 1000px" class="grid-container">
<div class="grid1">
</div>
</div>
</div>
11 changes: 11 additions & 0 deletions examples/webpack-demo-vanilla-bundle/src/examples/example14.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export class Example14 {
editedItems = {};
sgb1: SlickVanillaGridBundle;
gridContainerElm: HTMLDivElement;
loadingClass = '';
complexityLevelList = [
{ value: 0, label: 'Very Simple' },
{ value: 1, label: 'Simple' },
Expand Down Expand Up @@ -117,6 +118,8 @@ export class Example14 {
this._bindingEventService.bind(this.gridContainerElm, 'onbeforeeditcell', this.handleOnBeforeEditCell.bind(this));
this._bindingEventService.bind(this.gridContainerElm, 'oncellchange', this.handleOnCellChange.bind(this));
this._bindingEventService.bind(this.gridContainerElm, 'onpaginationchanged', this.handlePaginationChanged.bind(this));
this._bindingEventService.bind(this.gridContainerElm, 'onbeforeresizebycontent', this.showSpinner.bind(this));
this._bindingEventService.bind(this.gridContainerElm, 'onafterresizebycontent', this.hideSpinner.bind(this));
}

dispose() {
Expand Down Expand Up @@ -415,6 +418,14 @@ export class Example14 {
};
}

hideSpinner() {
setTimeout(() => this.loadingClass = '', 200); // delay the hide spinner a bit to avoid show/hide too quickly
}

showSpinner() {
this.loadingClass = 'mdi mdi-load mdi-spin-1s mdi-24px color-alt-success';
}

loadData(count: number) {
// mock data
const tmpArray = [];
Expand Down
1 change: 1 addition & 0 deletions packages/common/src/global-grid-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ export const GlobalGridOptions: GridOption = {
topPanelHeight: 30,
translationNamespaceSeparator: ':',
resizeAlwaysRecalculateColumnWidth: false,
resizeByContentOnlyOnFirstLoad: true,
resizeCellCharWidthInPx: 7.8,
resizeCellPaddingWidthInPx: 14,
resizeFormatterPaddingWidthInPx: 0,
Expand Down
15 changes: 12 additions & 3 deletions packages/common/src/interfaces/gridOption.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -479,24 +479,33 @@ export interface GridOption {
/** defaults to false, if a column `width` is provided (or was previously calculated) should we recalculate it or not when resizing by cell content? */
resizeAlwaysRecalculateColumnWidth?: boolean;

/**
* defaults to true, do we want to resize the grid by content only on the first page or anytime the data changes?
* Requires `enableAutoResizeColumnsByCellContent` to be set.
* Also don't get confused with `autosizeColumnsByCellContentOnFirstLoad` that flag won't block resize by content after the first load while `resizeByContentOnlyOnFirstLoad`
*/
resizeByContentOnlyOnFirstLoad?: boolean;

/**
* Defaults to 7, width in pixels of a string character which is used by the resize columns by its content, this can vary depending on which font family/size is used & cell padding.
* This is only used when resizing the columns width by their content, we need to know the width of a character in pixel to do all calculations.
* Requires `enableAutoResizeColumnsByCellContent` to be set.
*/
resizeCellCharWidthInPx?: number;

/** Defaults to 6, cell padding width to add to the calculation when resizing columns by their cell text content. */
/** Defaults to 6, cell padding width to add to the calculation when resizing columns by their cell text content (requires `enableAutoResizeColumnsByCellContent` to be set) */
resizeCellPaddingWidthInPx?: number;

/** Defaults to around ~0.9, what is the ratio to use (on field `type` "string" only) in the calculation when resizing columns by their cell text content. */
/** Defaults to around ~0.9, what is the ratio to use (on field `type` "string" only) in the calculation when resizing columns by their cell text content (requires `enableAutoResizeColumnsByCellContent` to be set). */
resizeDefaultRatioForStringType?: number;

/** Defaults to 6, padding width to add to the calculation when using a Formatter and resizing columns by their cell text content. */
/** Defaults to 6, padding width to add to the calculation when using a Formatter and resizing columns by their cell text content (requires `enableAutoResizeColumnsByCellContent` to be set). */
resizeFormatterPaddingWidthInPx?: number;

/**
* Defaults to 1000, width in pixels of a string character which is used by the resize columns by its content, this can vary depending on which font family/size is used & cell padding.
* This is only used when resizing the columns width by their content, we need to know the width of a character in pixel to do all calculations.
* Requires `enableAutoResizeColumnsByCellContent` to be set.
*/
resizeMaxItemToInspectCellContentWidth?: number;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1766,7 +1766,7 @@ describe('Slick-Vanilla-Grid-Bundle Component instantiated via Constructor', ()
const resizeContentSpy = jest.spyOn(resizerServiceStub, 'resizeColumnsByCellContent');
jest.spyOn(mockDataView, 'getLength').mockReturnValue(1);

component.gridOptions = { enablePagination: false, showCustomFooter: true, autoFitColumnsOnFirstLoad: false, enableAutoSizeColumns: false, enableAutoResizeColumnsByCellContent: true };
component.gridOptions = { enablePagination: false, resizeByContentOnlyOnFirstLoad: false, showCustomFooter: true, autoFitColumnsOnFirstLoad: false, enableAutoSizeColumns: false, enableAutoResizeColumnsByCellContent: true };
component.initialization(divContainer, slickEventHandler);
mockDataView.onSetItemsCalled.notify({ idProperty: 'id', itemCount: 1 });

Expand All @@ -1775,6 +1775,20 @@ describe('Slick-Vanilla-Grid-Bundle Component instantiated via Constructor', ()
done();
}, 10);
});

it('should call "resizeColumnsByCellContent" when the DataView "onSetItemsCalled" event is triggered and "enableAutoResizeColumnsByCellContent" and "resizeColumnsByCellContent" are both set', (done) => {
const resizeContentSpy = jest.spyOn(resizerServiceStub, 'resizeColumnsByCellContent');
jest.spyOn(mockDataView, 'getLength').mockReturnValue(1);

component.gridOptions = { enablePagination: false, resizeByContentOnlyOnFirstLoad: true, showCustomFooter: true, autoFitColumnsOnFirstLoad: false, enableAutoSizeColumns: false, enableAutoResizeColumnsByCellContent: true };
component.initialization(divContainer, slickEventHandler);
mockDataView.onSetItemsCalled.notify({ idProperty: 'id', itemCount: 1 });

setTimeout(() => {
expect(resizeContentSpy).toHaveBeenCalledWith(false);
done();
}, 10);
});
});

describe('Custom Footer', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,7 @@ export class SlickVanillaGridBundle {
if (args.itemCount > 0 && (this.gridOptions.autosizeColumnsByCellContentOnFirstLoad || this.gridOptions.enableAutoResizeColumnsByCellContent)) {
// add a delay so that if column positions changes by changeColumnsArrangement() when using custom Grid Views
// or presets.columns won't have any impact on the list of visible columns and their positions
setTimeout(() => this.resizerService.resizeColumnsByCellContent(true), 10);
setTimeout(() => this.resizerService.resizeColumnsByCellContent(!this.gridOptions?.resizeByContentOnlyOnFirstLoad), 10);
}
});

Expand Down
5 changes: 4 additions & 1 deletion packages/vanilla-bundle/src/services/resizer.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export class ResizerService {
private _intervalExecutionCounter = 0;
private _intervalRetryDelay = DEFAULT_INTERVAL_RETRY_DELAY;
private _isStopResizeIntervalRequested = false;
private _hasResizedByContentAtLeastOnce = false;
private _lastDimensions?: GridSize;
private _totalColumnsWidthByContent = 0;

Expand Down Expand Up @@ -157,9 +158,10 @@ export class ResizerService {
const columnWidths: { [columnId in string | number]: number; } = {};
let reRender = false;

if (!Array.isArray(dataset) || dataset.length === 0) {
if ((!Array.isArray(dataset) || dataset.length === 0) || (this._hasResizedByContentAtLeastOnce && this.gridOptions?.resizeByContentOnlyOnFirstLoad && !recalculateColumnsTotalWidth)) {
return;
}

this.eventPubSubService.publish('onBeforeResizeByContent');
let readItemCount = 0;

Expand Down Expand Up @@ -255,6 +257,7 @@ export class ResizerService {

// send updated column definitions widths to SlickGrid
this._grid.setColumns(columnDefinitions);
this._hasResizedByContentAtLeastOnce = true;

const calculateColumnWidths: { [columnId in string | number]: number | undefined; } = {};
for (const columnDef of columnDefinitions) {
Expand Down

0 comments on commit ffe7dc4

Please sign in to comment.