Skip to content

Commit

Permalink
feat: Date editor/filter improvements (#1551)
Browse files Browse the repository at this point in the history
* fix: micro vs macro task for init rendering; properly hide editor

* feat: override default dataItemColumnValueExtractor editor beahvior
  • Loading branch information
zewa666 committed Jun 8, 2024
1 parent 1889702 commit 7c61846
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ <h5 class="title is-5 mb-3">
<p>Grid - using <code>enableExcelCopyBuffer</code> which uses <code>SlickCellSelectionModel</code></p>
<p>The complete first row and the cells C - E of the second row are not allowing to paste values. </p>
<p>Additionally the columns are configured to <code>exportWithFormatter</code> and a custom formatter that renders the cells coordinates or value if available.
When selecting one or more cells and pressing CTRL + C, the ExcelCopyBuffer will be filled with the formatter outputs of the selected cells.</p>
When selecting one or more cells and pressing CTRL + C, the ExcelCopyBuffer will be filled with the formatter outputs of the selected cells. This also applies if the cells editor is already open
due to use of <code>copyActiveEditorCell</code></p>
</h5>
<h6 class="title is-6">
<button class="button is-small is-primary" onclick.delegate="togglePagination()"
Expand Down
20 changes: 17 additions & 3 deletions examples/vite-demo-vanilla-bundle/src/examples/example19.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type Column, type GridOption, SlickEventHandler, Editors } from '@slickgrid-universal/common';
import { type Column, type GridOption, SlickEventHandler, Editors, Formatters } from '@slickgrid-universal/common';
import { Slicker, type SlickVanillaGridBundle } from '@slickgrid-universal/vanilla-bundle';
import { ExampleGridOptions } from './example-grid-options';
import './example19.scss';
Expand Down Expand Up @@ -83,6 +83,16 @@ export default class Example19 {
}
];

this.columnDefinitions.push({
id: 'approvalDate',
name: 'Approval Date',
field: 'approvalDate',
minWidth: 120,
width: 120,
editor: { model: Editors.date, type: 'date'},
formatter: Formatters.dateIso,
exportWithFormatter: true
});
for (let i = 0; i < NB_ITEMS; i++) {
this.columnDefinitions.push({
id: i,
Expand All @@ -100,7 +110,7 @@ export default class Example19 {
return `${row + 1}:${cell + 1}`;
},
width: 60,
editor: { model: Editors.text }
editor: { model: Editors.text },
});
}

Expand Down Expand Up @@ -128,18 +138,22 @@ export default class Example19 {
onBeforePasteCell: (_e, args) => {
// deny the whole first row and the cells C-E of the second row
return !(args.row === 0 || (args.row === 1 && args.cell > 2 && args.cell < 6));
}
},
copyActiveEditorCell: true,
}
};
}

getData(itemCount: number) {
// mock a dataset
const datasetTmp: any[] = [];
const start = new Date(2000,0,1);
const end = new Date();
for (let i = 0; i < itemCount; i++) {
const d: any = (datasetTmp[i] = {});
d['id'] = i;
d['num'] = i;
d['approvalDate'] = new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
}

return datasetTmp;
Expand Down
18 changes: 10 additions & 8 deletions packages/common/src/editors/dateEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ export class DateEditor implements Editor {
});
}

setTimeout(() => {
queueMicrotask(() => {
this.calendarInstance = new VanillaCalendar(this._inputElm, this._pickerMergedOptions);
this.calendarInstance.init();
if (!compositeEditorOptions) {
Expand All @@ -222,14 +222,16 @@ export class DateEditor implements Editor {
}

destroy() {
this.hide();
this._bindEventService.unbindAll();
this.calendarInstance?.destroy();
queueMicrotask(() => {
this.hide();
this.calendarInstance?.destroy();
emptyElement(this._editorInputGroupElm);
emptyElement(this._inputElm);
this._editorInputGroupElm?.remove();
this._inputElm?.remove();
});

emptyElement(this._editorInputGroupElm);
emptyElement(this._inputElm);
this._editorInputGroupElm?.remove();
this._inputElm?.remove();
this._bindEventService.unbindAll();
}

clear() {
Expand Down
3 changes: 2 additions & 1 deletion packages/common/src/extensions/slickCellExcelCopyManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,9 @@ export class SlickCellExcelCopyManager {
// to decide if we evaluate the Formatter, we will use the same flag from Export which is "exportWithFormatter"
const activeCell = this._grid.getActiveCell();
const isActiveEditorCurrentCell = this._grid.getCellEditor() && activeCell?.row === row && activeCell?.cell === cell;
const copyActiveEditorCell = this.addonOptions?.copyActiveEditorCell || false;

if (!this.gridOptions.editable || !columnDef.editor || !isActiveEditorCurrentCell) {
if (!this.gridOptions.editable || !columnDef.editor || !isActiveEditorCurrentCell || copyActiveEditorCell) {
const isEvaluatingFormatter = (columnDef.exportWithFormatter !== undefined) ? columnDef.exportWithFormatter : (this.gridOptions.textExportOptions?.exportWithFormatter);
if (columnDef.formatter && isEvaluatingFormatter) {
const formattedOutput = columnDef.formatter(row, cell, item[columnDef.field], columnDef, item, this._grid);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,10 @@ export class SlickCellExternalCopyManager {
setDataItemValueForColumn(item: any, columnDef: Column, value: any): any | void {
if (!columnDef?.denyPaste) {
if (this._addonOptions.dataItemColumnValueSetter) {
return this._addonOptions.dataItemColumnValueSetter(item, columnDef, value);
const setterResult = this._addonOptions.dataItemColumnValueSetter(item, columnDef, value);
if (setterResult !== true) {
return setterResult;
}
}

// if a custom setter is not defined, we call applyValue of the editor to unserialize
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,18 @@ export interface ExcelCopyBufferOption<T = any> {
/** defaults to "copy-manager", sets the layer key for setting css values of copied cells. */
copiedCellStyleLayerKey?: string;

/**
* should copy the cells value on copy shortcut even when the editor is opened
*
* **NOTE**: affects only the default {@link ExcelCopyBufferOption#dataItemColumnValueExtractor}
* */
copyActiveEditorCell?: boolean;

/** option to specify a custom column value extractor function */
dataItemColumnValueExtractor?: (item: any, columnDef: Column<T>, row?: number, cell?: number) => string | HTMLElement | DocumentFragment | FormatterResultWithHtml | FormatterResultWithText | null;

/** option to specify a custom column value setter function */
dataItemColumnValueSetter?: (item: any, columnDef: Column<T>, value: any) => string | FormatterResultWithHtml | FormatterResultWithText | null;
/** option to specify a custom column value setter function. Return true if default logic should continue to evaluate */
dataItemColumnValueSetter?: (item: any, columnDef: Column<T>, value: any) => string | FormatterResultWithHtml | FormatterResultWithText | null | true;

/** option to specify a custom handler for paste actions */
clipboardCommandHandler?: (editCommand: any) => void;
Expand Down
24 changes: 12 additions & 12 deletions test/cypress/e2e/example19.cy.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
describe('Example 19 - ExcelCopyBuffer with Cell Selection', () => {
const titles = [
'', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
'', 'Approval Date', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
'Z', 'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK'
];
Expand All @@ -16,7 +16,7 @@ describe('Example 19 - ExcelCopyBuffer with Cell Selection', () => {
.find('.slick-header-columns')
.children()
.each(($child, index) => {
if (index < titles.length) {
if (index > 0 && index < titles.length) {
expect($child.text()).to.eq(titles[index]);
}
});
Expand All @@ -28,15 +28,15 @@ describe('Example 19 - ExcelCopyBuffer with Cell Selection', () => {

describe('with Pagination of size 20', () => {
it('should click on cell B14 then Ctrl+Shift+End with selection B14-CV19', () => {
cy.getCell(14, 2, '', { parentSelector: '.grid19', rowHeight: GRID_ROW_HEIGHT })
cy.getCell(14, 3, '', { parentSelector: '.grid19', rowHeight: GRID_ROW_HEIGHT })
.as('cell_B14')
.click();

cy.get('@cell_B14')
.type('{ctrl}{shift}{end}');

cy.get('#selectionRange')
.should('have.text', '{"fromRow":14,"fromCell":2,"toRow":19,"toCell":100}');
.should('have.text', '{"fromRow":14,"fromCell":3,"toRow":19,"toCell":101}');
});

it('should click on cell CP3 then Ctrl+Shift+Home with selection A0-CP3', () => {
Expand Down Expand Up @@ -149,39 +149,39 @@ describe('Example 19 - ExcelCopyBuffer with Cell Selection', () => {
});

it('should click on cell E46 then Shift+End key with full row horizontal selection E46-CV46', () => {
cy.getCell(46, 5, '', { parentSelector: '.grid19', rowHeight: GRID_ROW_HEIGHT })
cy.getCell(46, 6, '', { parentSelector: '.grid19', rowHeight: GRID_ROW_HEIGHT })
.as('cell_E46')
.click();

cy.get('@cell_E46')
.type('{shift}{end}');

cy.get('#selectionRange')
.should('have.text', '{"fromRow":46,"fromCell":5,"toRow":46,"toCell":100}');
.should('have.text', '{"fromRow":46,"fromCell":6,"toRow":46,"toCell":101}');
});

it('should click on cell CP54 then Ctrl+Shift+End keys with selection E46-CV99', () => {
cy.getCell(54, 94, '', { parentSelector: '.grid19', rowHeight: GRID_ROW_HEIGHT })
cy.getCell(54, 95, '', { parentSelector: '.grid19', rowHeight: GRID_ROW_HEIGHT })
.as('cell_CP54')
.click();

cy.get('@cell_CP54')
.type('{ctrl}{shift}{end}');

cy.get('#selectionRange')
.should('have.text', '{"fromRow":54,"fromCell":94,"toRow":99,"toCell":100}');
.should('have.text', '{"fromRow":54,"fromCell":95,"toRow":99,"toCell":101}');
});

it('should click on cell CP95 then Ctrl+Shift+Home keys with selection C0-CP95', () => {
cy.getCell(95, 98, '', { parentSelector: '.grid19', rowHeight: GRID_ROW_HEIGHT })
cy.getCell(95, 99, '', { parentSelector: '.grid19', rowHeight: GRID_ROW_HEIGHT })
.as('cell_CP95')
.click();

cy.get('@cell_CP95')
.type('{ctrl}{shift}{home}');

cy.get('#selectionRange')
.should('have.text', '{"fromRow":0,"fromCell":0,"toRow":95,"toCell":98}');
.should('have.text', '{"fromRow":0,"fromCell":0,"toRow":95,"toCell":99}');
});

it('should click on cell CR5 again then Ctrl+Home keys and expect to scroll back to cell A0 without any selection range', () => {
Expand All @@ -204,15 +204,15 @@ describe('Example 19 - ExcelCopyBuffer with Cell Selection', () => {
});

it('should click on cell B14 then Shift+End with selection B14-24', () => {
cy.getCell(14, 2, '', { parentSelector: '.grid19', rowHeight: GRID_ROW_HEIGHT })
cy.getCell(14, 3, '', { parentSelector: '.grid19', rowHeight: GRID_ROW_HEIGHT })
.as('cell_B14')
.click();

cy.get('@cell_B14')
.type('{shift}{end}');

cy.get('#selectionRange')
.should('have.text', '{"fromRow":14,"fromCell":2,"toRow":14,"toCell":100}');
.should('have.text', '{"fromRow":14,"fromCell":3,"toRow":14,"toCell":101}');
});

it('should click on cell CS14 then Shift+Home with selection A14-CS14', () => {
Expand Down

0 comments on commit 7c61846

Please sign in to comment.