Skip to content

Commit

Permalink
feat: add onPreHeaderContextMenu for Column Picker usage (#1030)
Browse files Browse the repository at this point in the history
* feat: add onPreHeaderContextMenu for Column Picker usage
- adding new events `onPreHeaderContextMenu` and `onPreHeaderClick` which is mostly to be able to open the Column Picker from either the regular column headers OR the Column Group from the Pre-Header when defined
  • Loading branch information
ghiscoding authored Jun 19, 2024
1 parent cec789c commit ea2c175
Show file tree
Hide file tree
Showing 10 changed files with 368 additions and 218 deletions.
37 changes: 37 additions & 0 deletions cypress/e2e/example-draggable-header-grouping.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,5 +214,42 @@ describe('Example - Draggable Grouping', { retries: 1 }, () => {
// cy.get(`#myGrid [style="top: ${GRID_ROW_HEIGHT * 49999}px;"] > .slick-cell:nth(1)`).should('have.text', 'Task 49999');
cy.get(`#myGrid [style="top: 1.24998e+06px;"] > .slick-cell:nth(1)`).should('have.text', 'Task 49999');
});

it('should be able to call column picker from the pre-header', () => {
const preHeadersWithoutId = ['Common Factor', 'Period', 'Analysis', ''];
const titlesWithoutId = ['Title', 'Duration', 'Start', 'Finish', 'Cost', 'Effort-Driven'];

cy.get('#myGrid')
.find('.slick-preheader-panel .slick-header-column:nth(1)')
.trigger('mouseover')
.trigger('contextmenu')
.invoke('show');

cy.get('.slick-columnpicker')
.find('.slick-columnpicker-list')
.children()
.each(($child, index) => {
if (index <= 5) {
expect($child.text()).to.eq(fullTitles[index]);
}
});

cy.get('.slick-columnpicker')
.find('.slick-columnpicker-list')
.children('li:nth-child(1)')
.children('label')
.should('contain', '#')
.click();

cy.get('#myGrid')
.find('.slick-preheader-panel .slick-header-columns')
.children()
.each(($child, index) => expect($child.text()).to.eq(preHeadersWithoutId[index]));

cy.get('#myGrid')
.find('.slick-header:not(.slick-preheader-panel) .slick-header-columns')
.children()
.each(($child, index) => expect($child.text()).to.eq(titlesWithoutId[index]));
});
});
});
238 changes: 139 additions & 99 deletions cypress/e2e/example-frozen-columns-and-column-group.cy.ts
Original file line number Diff line number Diff line change
@@ -1,101 +1,141 @@
describe('Example - Row Grouping Titles', () => {
const fullPreTitles = ['', 'Common Factor', 'Period', 'Analysis'];
const fullTitles = ['#', 'Title', 'Duration', 'Start', 'Finish', '% Complete', 'Effort Driven'];

it('should display Example Frozen Columns & Column Group', () => {
cy.visit(`${Cypress.config('baseUrl')}/examples/example-frozen-columns-and-column-group.html`);
cy.get('h2').should('contain', 'Demonstrates:');
cy.contains('Frozen columns with extra header row grouping columns into categories');
});

it('should have exact Column Pre-Header & Column Header Titles in the grid', () => {
cy.get('#myGrid')
.find('.slick-header-columns:nth(0)')
.children()
.each(($child, index) => expect($child.text()).to.eq(fullPreTitles[index]));

cy.get('#myGrid')
.find('.slick-header-columns:nth(1)')
.children()
.each(($child, index) => expect($child.text()).to.eq(fullTitles[index]));
});

it('should have a frozen grid on page load with 3 columns on the left and 4 columns on the right', () => {
cy.get('[style="top: 0px;"]').should('have.length', 2);
cy.get('.grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 3);
cy.get('.grid-canvas-right > [style="top: 0px;"]').children().should('have.length', 4);

cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', '0');
cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 0');
cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days');

cy.get('.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', '01/01/2009');
cy.get('.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', '01/05/2009');
});

it('should have exact Column Pre-Header & Column Header Titles in the grid', () => {
cy.get('#myGrid')
.find('.slick-header-columns:nth(0)')
.children()
.each(($child, index) => expect($child.text()).to.eq(fullPreTitles[index]));

cy.get('#myGrid')
.find('.slick-header-columns:nth(1)')
.children()
.each(($child, index) => expect($child.text()).to.eq(fullTitles[index]));
});

it('should click on the "Remove Frozen Columns" button to switch to a regular grid without frozen columns and expect 7 columns on the left container', () => {
cy.contains('Remove Frozen Columns')
.click({ force: true });

cy.get('[style="top: 0px;"]').should('have.length', 1);
cy.get('.grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 7);

cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', '0');
cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 0');
cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days');
cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(3)').should('contain', '01/01/2009');
cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(4)').should('contain', '01/05/2009');
});

it('should have exact Column Pre-Header & Column Header Titles in the grid', () => {
cy.get('#myGrid')
.find('.slick-header-columns:nth(0)')
.children()
.each(($child, index) => expect($child.text()).to.eq(fullPreTitles[index]));

cy.get('#myGrid')
.find('.slick-header-columns:nth(1)')
.children()
.each(($child, index) => expect($child.text()).to.eq(fullTitles[index]));
});

it('should click on the "Set 3 Frozen Columns" button to switch frozen columns grid and expect 3 frozen columns on the left and 4 columns on the right', () => {
cy.contains('Set 3 Frozen Columns')
.click({ force: true });

cy.get('[style="top: 0px;"]').should('have.length', 2);
cy.get('.grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 3);
cy.get('.grid-canvas-right > [style="top: 0px;"]').children().should('have.length', 4);

cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', '0');
cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 0');
cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days');

cy.get('.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', '01/01/2009');
cy.get('.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', '01/05/2009');
});

it('should have exact Column Pre-Header & Column Header Titles in the grid', () => {
cy.get('#myGrid')
.find('.slick-header-columns:nth(0)')
.children()
.each(($child, index) => expect($child.text()).to.eq(fullPreTitles[index]));

cy.get('#myGrid')
.find('.slick-header-columns:nth(1)')
.children()
.each(($child, index) => expect($child.text()).to.eq(fullTitles[index]));
});
const fullPreTitles = ['', 'Common Factor', 'Period', 'Analysis'];
const fullTitles = ['#', 'Title', 'Duration', 'Start', 'Finish', '% Complete', 'Effort Driven'];

it('should display Example Frozen Columns & Column Group', () => {
cy.visit(`${Cypress.config('baseUrl')}/examples/example-frozen-columns-and-column-group.html`);
cy.get('h2').should('contain', 'Demonstrates:');
cy.contains('Frozen columns with extra header row grouping columns into categories');
});

it('should have exact Column Pre-Header & Column Header Titles in the grid', () => {
cy.get('#myGrid')
.find('.slick-header-columns:nth(0)')
.children()
.each(($child, index) => expect($child.text()).to.eq(fullPreTitles[index]));

cy.get('#myGrid')
.find('.slick-header-columns:nth(1)')
.children()
.each(($child, index) => expect($child.text()).to.eq(fullTitles[index]));
});

it('should have a frozen grid on page load with 3 columns on the left and 4 columns on the right', () => {
cy.get('[style="top: 0px;"]').should('have.length', 2);
cy.get('.grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 3);
cy.get('.grid-canvas-right > [style="top: 0px;"]').children().should('have.length', 4);

cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', '0');
cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 0');
cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days');

cy.get('.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', '01/01/2009');
cy.get('.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', '01/05/2009');
});

it('should have exact Column Pre-Header & Column Header Titles in the grid', () => {
cy.get('#myGrid')
.find('.slick-header-columns:nth(0)')
.children()
.each(($child, index) => expect($child.text()).to.eq(fullPreTitles[index]));

cy.get('#myGrid')
.find('.slick-header-columns:nth(1)')
.children()
.each(($child, index) => expect($child.text()).to.eq(fullTitles[index]));
});

it('should click on the "Remove Frozen Columns" button to switch to a regular grid without frozen columns and expect 7 columns on the left container', () => {
cy.contains('Remove Frozen Columns')
.click({ force: true });

cy.get('[style="top: 0px;"]').should('have.length', 1);
cy.get('.grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 7);

cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', '0');
cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 0');
cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days');
cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(3)').should('contain', '01/01/2009');
cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(4)').should('contain', '01/05/2009');
});

it('should have exact Column Pre-Header & Column Header Titles in the grid', () => {
cy.get('#myGrid')
.find('.slick-header-columns:nth(0)')
.children()
.each(($child, index) => expect($child.text()).to.eq(fullPreTitles[index]));

cy.get('#myGrid')
.find('.slick-header-columns:nth(1)')
.children()
.each(($child, index) => expect($child.text()).to.eq(fullTitles[index]));
});

it('should click on the "Set 3 Frozen Columns" button to switch frozen columns grid and expect 3 frozen columns on the left and 4 columns on the right', () => {
cy.contains('Set 3 Frozen Columns')
.click({ force: true });

cy.get('[style="top: 0px;"]').should('have.length', 2);
cy.get('.grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 3);
cy.get('.grid-canvas-right > [style="top: 0px;"]').children().should('have.length', 4);

cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', '0');
cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 0');
cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days');

cy.get('.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', '01/01/2009');
cy.get('.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', '01/05/2009');
});

it('should have exact Column Pre-Header & Column Header Titles in the grid', () => {
cy.get('#myGrid')
.find('.slick-header-columns:nth(0)')
.children()
.each(($child, index) => expect($child.text()).to.eq(fullPreTitles[index]));

cy.get('#myGrid')
.find('.slick-header-columns:nth(1)')
.children()
.each(($child, index) => expect($child.text()).to.eq(fullTitles[index]));
});

it('should be able to call column picker from the pre-header', () => {
const fullPreTitlesWithoutId = ['Common Factor', 'Period', 'Period', 'Analysis'];
const fullTitlesWithoutId = ['Title', 'Duration', 'Start', 'Finish', '% Complete', 'Effort Driven'];
const fullTitlesWithGroup = ['#', 'Common Factor - Title', 'Common Factor - Duration', 'Period - Start', 'Period - Finish', 'Analysis - % Complete', 'Analysis - Effort Driven'];

cy.get('#myGrid')
.find('.slick-preheader-panel .slick-header-column:nth(1)')
.trigger('mouseover')
.trigger('contextmenu')
.invoke('show');

cy.get('.slick-columnpicker')
.find('.slick-columnpicker-list')
.children()
.each(($child, index) => {
if (index <= 6) {
expect($child.text()).to.eq(fullTitlesWithGroup[index]);
}
});

cy.get('.slick-columnpicker')
.find('.slick-columnpicker-list')
.children('li:nth-child(1)')
.children('label')
.should('contain', '#')
.click();

cy.get('.slick-columnpicker > button.close > .close').click();

cy.get('#myGrid')
.find('.slick-preheader-panel .slick-header-columns')
.children()
.each(($child, index) => expect($child.text()).to.eq(fullPreTitlesWithoutId[index]));

cy.get('#myGrid')
.find('.slick-header:not(.slick-preheader-panel) .slick-header-columns')
.children()
.each(($child, index) => expect($child.text()).to.eq(fullTitlesWithoutId[index]));
});
});
72 changes: 40 additions & 32 deletions examples/example-column-group.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,60 +49,64 @@ <h2>View Source:</h2>

<script>
function CreateAddlHeaderRow() {
var preHeaderPanelElm = grid.getPreHeaderPanel();
let preHeaderPanelElm = grid.getPreHeaderPanel();
preHeaderPanelElm.innerHTML = '';
preHeaderPanelElm.className = "slick-header-columns";
preHeaderPanelElm.style.left = '-1000px';
preHeaderPanelElm.style.width = `${grid.getHeadersWidth()}px`;
preHeaderPanelElm.parentElement.classList.add("slick-header");

var headerColumnWidthDiff = grid.getHeaderColumnWidthDiff();
var m, headerElm, lastColumnGroup = '', widthTotal = 0;
let headerColumnWidthDiff = grid.getHeaderColumnWidthDiff();
let m, headerElm, lastColumnGroup = '', widthTotal = 0;
const columns = grid.getColumns();

for (var i = 0; i < columns.length; i++) {
for (let i = 0; i < columns.length; i++) {
m = columns[i];
if (lastColumnGroup === m.columnGroup && i>0) {
widthTotal += m.width;
headerElm.style.width = `${widthTotal - headerColumnWidthDiff}px`;
} else {
widthTotal = m.width;
headerElm = document.createElement('div');
headerElm.className = 'ui-state-default slick-header-column';
headerElm.style.width = `${(m.width || 0) - headerColumnWidthDiff}px`;

const spanElm = document.createElement('span');
spanElm.className='slick-column-name';
spanElm.textContent = m.columnGroup || '';
headerElm.appendChild(spanElm);
preHeaderPanelElm.appendChild(headerElm);
if (m) {
if (lastColumnGroup === m.columnGroup && i>0) {
widthTotal += m.width;
headerElm.style.width = `${widthTotal - headerColumnWidthDiff}px`;
} else {
widthTotal = m.width;
headerElm = document.createElement('div');
headerElm.className = 'ui-state-default slick-header-column';
headerElm.style.width = `${(m.width || 0) - headerColumnWidthDiff}px`;
headerElm.dataset.group = m.columnGroup || '';

const spanElm = document.createElement('span');
spanElm.className = 'slick-column-name';
spanElm.textContent = m.columnGroup || '';
headerElm.appendChild(spanElm);
preHeaderPanelElm.appendChild(headerElm);
}
lastColumnGroup = m.columnGroup;
}
lastColumnGroup = m.columnGroup;
}
}

var dataView;
var grid;
var data = [];
var options = {
let dataView;
let grid;
let data = [];
let options = {
enableCellNavigation: true,
enableColumnReorder: false,
createPreHeaderPanel: true,
showPreHeaderPanel: true,
preHeaderPanelHeight: 23,
explicitInitialization: true
};
var columns = [
let columns = [
{id: "sel", name: "#", field: "num", behavior: "select", cssClass: "cell-selection", width: 40, resizable: false, selectable: false },
{id: "title", name: "Title", field: "title", width: 120, minWidth: 120, cssClass: "cell-title", columnGroup:"Common Factor"},
{id: "duration", name: "Duration", field: "duration", columnGroup:"Common Factor"},
{id: "start", name: "Start", field: "start", minWidth: 60, columnGroup:"Period"},
{id: "finish", name: "Finish", field: "finish", minWidth: 60, columnGroup:"Period"},
{id: "%", defaultSortAsc: false, name: "% Complete", field: "percentComplete", width: 95, resizable: false, columnGroup:"Analysis"},
{id: "effort-driven", name: "Effort Driven", width: 90, minWidth: 20, maxWidth: 90, field: "effortDriven", columnGroup:"Analysis"}
{id: "title", name: "Title", field: "title", width: 120, minWidth: 120, cssClass: "cell-title", columnGroup: "Common Factor"},
{id: "duration", name: "Duration", field: "duration", columnGroup: "Common Factor"},
{id: "start", name: "Start", field: "start", minWidth: 60, columnGroup: "Period"},
{id: "finish", name: "Finish", field: "finish", minWidth: 60, columnGroup: "Period"},
{id: "%", defaultSortAsc: false, name: "% Complete", field: "percentComplete", width: 95, resizable: false, columnGroup: "Analysis"},
{id: "effort-driven", name: "Effort Driven", width: 90, minWidth: 20, maxWidth: 90, field: "effortDriven", columnGroup: "Analysis"}
];

for (var i = 0; i < 50000; i++) {
var d = (data[i] = {});
for (let i = 0; i < 50000; i++) {
let d = (data[i] = {});

d["id"] = "id_" + i;
d["num"] = i;
Expand Down Expand Up @@ -133,6 +137,10 @@ <h2>View Source:</h2>
CreateAddlHeaderRow();
});

grid.onColumnsReordered.subscribe(function (e, args) {
CreateAddlHeaderRow();
});

CreateAddlHeaderRow();

// Initialise data
Expand Down
Loading

0 comments on commit ea2c175

Please sign in to comment.