diff --git a/cypress/e2e/example-checkbox-header-row.cy.ts b/cypress/e2e/example-checkbox-header-row.cy.ts index d961d1ea..ffc22199 100644 --- a/cypress/e2e/example-checkbox-header-row.cy.ts +++ b/cypress/e2e/example-checkbox-header-row.cy.ts @@ -156,15 +156,14 @@ describe('Example - Checkbox Header Row', () => { .click(); cy.get('.slick-cell-checkboxsel input:checked') - .should('have.length', 11); + .should('have.length', 13); }); it('should go to last page and still expect all rows selected in current page', () => { cy.get('.sgi-chevron-end') .click(); - cy.get('.slick-cell-checkboxsel input:checked') - .should('have.length', 11); + cy.get('.slick-cell-checkboxsel input:checked').should('have.length', 13); cy.get('.slick-pager-status') .contains('Showing page 6 of 6'); @@ -187,7 +186,7 @@ describe('Example - Checkbox Header Row', () => { .should('not.be.checked'); cy.get('.slick-cell-checkboxsel input:checked') - .should('have.length', 10); + .should('have.length', 12); cy.get('#selectedRows') .should('contain', '2,4,6,8,10,12,14,16,18,20,22,24'); @@ -204,7 +203,7 @@ describe('Example - Checkbox Header Row', () => { .should('not.be.checked'); cy.get('.slick-cell-checkboxsel input:checked') - .should('have.length', 11); + .should('have.length', 12); cy.get('.slick-pager-status') .contains('Showing page 1 of 6'); @@ -227,7 +226,7 @@ describe('Example - Checkbox Header Row', () => { .should('be.checked'); cy.get('.slick-cell-checkboxsel input:checked') - .should('have.length', 11); + .should('have.length', 13); cy.get('.slick-pager-status') .contains('Showing page 6 of 6'); diff --git a/examples/example-checkbox-header-row.html b/examples/example-checkbox-header-row.html index 57b90120..b617727e 100644 --- a/examples/example-checkbox-header-row.html +++ b/examples/example-checkbox-header-row.html @@ -80,7 +80,7 @@
-
+
diff --git a/src/controls/slick.columnmenu.ts b/src/controls/slick.columnmenu.ts index d3226257..bc444c19 100644 --- a/src/controls/slick.columnmenu.ts +++ b/src/controls/slick.columnmenu.ts @@ -54,7 +54,7 @@ export class SlickColumnMenu { hideSyncResizeButton: false, forceFitTitle: 'Force fit columns', syncResizeTitle: 'Synchronous resize', - headerColumnValueExtractor: (columnDef: Column) => columnDef.name instanceof HTMLElement ? columnDef.name.innerHTML : columnDef.name || '' + headerColumnValueExtractor: (columnDef: Column) => Utils.getHtmlStringOutput(columnDef.name || '', 'innerHTML'), }; constructor(protected columns: Column[], protected readonly grid: SlickGrid, options: GridOption) { diff --git a/src/controls/slick.columnpicker.ts b/src/controls/slick.columnpicker.ts index 4b7c1b42..42da50a8 100644 --- a/src/controls/slick.columnpicker.ts +++ b/src/controls/slick.columnpicker.ts @@ -55,7 +55,7 @@ export class SlickColumnPicker { hideSyncResizeButton: false, forceFitTitle: 'Force fit columns', syncResizeTitle: 'Synchronous resize', - headerColumnValueExtractor: (columnDef: Column) => columnDef.name instanceof HTMLElement ? columnDef.name.innerHTML : columnDef.name || '' + headerColumnValueExtractor: (columnDef: Column) => Utils.getHtmlStringOutput(columnDef.name || '', 'innerHTML'), }; constructor(protected columns: Column[], protected readonly grid: SlickGrid, gridOptions: GridOption) { diff --git a/src/controls/slick.gridmenu.ts b/src/controls/slick.gridmenu.ts index 37661a65..aea0e880 100644 --- a/src/controls/slick.gridmenu.ts +++ b/src/controls/slick.gridmenu.ts @@ -167,7 +167,7 @@ export class SlickGridMenu { subMenuOpenByEvent: 'mouseover', syncResizeTitle: 'Synchronous resize', useClickToRepositionMenu: true, - headerColumnValueExtractor: (columnDef: Column) => columnDef.name instanceof HTMLElement ? columnDef.name.innerHTML : columnDef.name || '', + headerColumnValueExtractor: (columnDef: Column) => Utils.getHtmlStringOutput(columnDef.name || '', 'innerHTML'), }; constructor(protected columns: Column[], protected readonly grid: SlickGrid, gridOptions: GridOption) { @@ -593,7 +593,7 @@ export class SlickGridMenu { const labelElm = document.createElement('label'); labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-${columnId}`; - this.grid.applyHtmlCode(labelElm, this.grid.sanitizeHtmlString((columnLabel instanceof HTMLElement ? columnLabel.innerHTML : columnLabel) || '')); + this.grid.applyHtmlCode(labelElm, this.grid.sanitizeHtmlString(Utils.getHtmlStringOutput(columnLabel || ''))); liElm.appendChild(labelElm); this._listElm.appendChild(liElm); } diff --git a/src/models/column.interface.ts b/src/models/column.interface.ts index 0e136b68..527a09ba 100644 --- a/src/models/column.interface.ts +++ b/src/models/column.interface.ts @@ -144,7 +144,7 @@ export interface Column { minWidth?: number; /** Column Title Name to be displayed in the Grid (UI) */ - name?: string | HTMLElement; + name?: string | HTMLElement | DocumentFragment; /** column offset width */ offsetWidth?: number; diff --git a/src/models/columnPicker.interface.ts b/src/models/columnPicker.interface.ts index ee99fe40..dd0a6fb9 100644 --- a/src/models/columnPicker.interface.ts +++ b/src/models/columnPicker.interface.ts @@ -33,7 +33,7 @@ export interface ColumnPickerOption { syncResizeTitle?: string; /** Callback method to override the column name output used by the ColumnPicker/GridMenu. */ - headerColumnValueExtractor?: (column: Column, gridOptions?: GridOption) => string | HTMLElement; + headerColumnValueExtractor?: (column: Column, gridOptions?: GridOption) => string | HTMLElement | DocumentFragment; } export interface OnColumnsChangedArgs { diff --git a/src/models/excelCopyBufferOption.interface.ts b/src/models/excelCopyBufferOption.interface.ts index 75ebe026..e4a4cbac 100644 --- a/src/models/excelCopyBufferOption.interface.ts +++ b/src/models/excelCopyBufferOption.interface.ts @@ -42,7 +42,7 @@ export interface ExcelCopyBufferOption { readOnlyMode?: boolean; /** option to specify a custom column header value extractor function */ - headerColumnValueExtractor?: (columnDef: Column) => any; + headerColumnValueExtractor?: (columnDef: Column) => string | HTMLElement | DocumentFragment; // -- // Events diff --git a/src/models/gridMenuOption.interface.ts b/src/models/gridMenuOption.interface.ts index 5cc19815..986e9c5c 100644 --- a/src/models/gridMenuOption.interface.ts +++ b/src/models/gridMenuOption.interface.ts @@ -86,7 +86,7 @@ export interface GridMenuOption { // action/override callbacks /** Callback method to override the column name output used by the ColumnPicker/GridMenu. */ - headerColumnValueExtractor?: (column: Column, gridOptions?: GridOption) => string | HTMLElement; + headerColumnValueExtractor?: (column: Column, gridOptions?: GridOption) => string | HTMLElement | DocumentFragment; /** Callback method that user can override the default behavior of enabling/disabling an item from the list. */ menuUsabilityOverride?: (args: MenuCallbackArgs) => boolean; diff --git a/src/plugins/slick.autotooltips.ts b/src/plugins/slick.autotooltips.ts index 74953463..437370da 100644 --- a/src/plugins/slick.autotooltips.ts +++ b/src/plugins/slick.autotooltips.ts @@ -98,7 +98,7 @@ export class SlickAutoTooltips implements SlickPlugin { node = targetElm.closest('.slick-header-column'); if (node && !(column?.toolTip)) { const titleVal = (targetElm.clientWidth < node.clientWidth) ? column?.name ?? '' : ''; - node.title = titleVal instanceof HTMLElement ? titleVal.innerHTML : titleVal; + node.title = Utils.getHtmlStringOutput(titleVal, 'innerHTML'); } } node = null; diff --git a/src/plugins/slick.cellexternalcopymanager.ts b/src/plugins/slick.cellexternalcopymanager.ts index 162e8ddc..33b20303 100644 --- a/src/plugins/slick.cellexternalcopymanager.ts +++ b/src/plugins/slick.cellexternalcopymanager.ts @@ -91,15 +91,15 @@ export class SlickCellExternalCopyManager implements SlickPlugin { this._grid.onKeyDown.unsubscribe(this.handleKeyDown.bind(this)); } - protected getHeaderValueForColumn(columnDef: Column) { + protected getHeaderValueForColumn(columnDef: Column): string { if (this._options.headerColumnValueExtractor) { - const val = this._options.headerColumnValueExtractor(columnDef); + const val = Utils.getHtmlStringOutput(this._options.headerColumnValueExtractor(columnDef)); if (val) { return val; } } - return columnDef.name; + return Utils.getHtmlStringOutput(columnDef.name || ''); } protected getDataItemValueForColumn(item: any, columnDef: Column, event: SlickEventData): string { @@ -393,7 +393,7 @@ export class SlickCellExternalCopyManager implements SlickPlugin { ? (columns[j].name as HTMLElement).innerHTML : columns[j].name as string; if (colName.length > 0 && !columns[j].hidden) { - clipTextHeaders.push(this.getHeaderValueForColumn(columns[j])); + clipTextHeaders.push(this.getHeaderValueForColumn(columns[j]) || ''); } } clipTextRows.push(clipTextHeaders.join('\t')); diff --git a/src/plugins/slick.checkboxselectcolumn.ts b/src/plugins/slick.checkboxselectcolumn.ts index ed2e0393..156458ee 100644 --- a/src/plugins/slick.checkboxselectcolumn.ts +++ b/src/plugins/slick.checkboxselectcolumn.ts @@ -343,12 +343,31 @@ export class SlickCheckboxSelectColumn implements SlickPlugin { return this._checkboxColumnCellIndex; } + /** + * use a DocumentFragment to return a fragment including an then a