Skip to content

Commit

Permalink
chore(demo): improve SQL LIKE filter predicate example (#1529)
Browse files Browse the repository at this point in the history
* chore(demo): improve SQL LIKE filter predicate to be more accurate
  • Loading branch information
ghiscoding authored May 16, 2024
1 parent f796f12 commit 828eb8a
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 24 deletions.
32 changes: 22 additions & 10 deletions examples/vite-demo-vanilla-bundle/src/examples/example14.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,19 +159,31 @@ export default class Example14 {
if (searchVals?.length) {
const columnId = searchFilterArgs.columnId;
const searchVal = searchVals[0] as string;
const likeMatches = searchVal.split('%');
if (likeMatches.length > 3) {
// for matches like "%Ta%10%" will return text that starts with "Ta" and ends with "10" (e.g. "Task 10", "Task 110", "Task 210")
const [_, start, end] = likeMatches;
return dataContext[columnId].startsWith(start) && dataContext[columnId].endsWith(end);
} else if (likeMatches.length > 2) {
// for matches like "%Ta%10" will return text that starts with "Ta" and contains "10" (e.g. "Task 10", "Task 100", "Task 101")
const [_, start, contain] = likeMatches;
return dataContext[columnId].startsWith(start) && dataContext[columnId].includes(contain);
const results = searchVal.matchAll(/^%([^%\r\n]+)[^%\r\n]*$|%(.+)%(.*)|(.+)%(.+)|([^%\r\n]+)%$/gi);
const arrayOfMatches = Array.from(results);
const matches = arrayOfMatches.length ? arrayOfMatches[0] : [];
const [_, endW, contain, containEndW, comboSW, comboEW, startW] = matches;

if (endW) {
// example: "%001" ends with A
return dataContext[columnId].endsWith(endW);
} else if (contain && containEndW) {
// example: "%Ti%001", contains A + ends with B
return dataContext[columnId].includes(contain) && dataContext[columnId].endsWith(containEndW);
} else if (contain && !containEndW) {
// example: "%Ti%", contains A anywhere
return dataContext[columnId].includes(contain);
} else if (comboSW && comboEW) {
// example: "Ti%001", combo starts with A + ends with B
return dataContext[columnId].startsWith(comboSW) && dataContext[columnId].endsWith(comboEW);
} else if (startW) {
// example: "Ti%", starts with A
return dataContext[columnId].startsWith(startW);
}
// for anything else we'll simply expect a Contains
// anything else
return dataContext[columnId].includes(searchVal);
}

// if we fall here then the value is not filtered out
return true;
},
Expand Down
111 changes: 97 additions & 14 deletions test/cypress/e2e/example14.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,20 +185,6 @@ describe('Example 14 - Columns Resize by Content', () => {
.should('have.length', 0);
});

it('should be able to use custom filter predicate on Title column and act similarly to an SQL LIKE matcher', () => {
cy.get('.search-filter.filter-title')
.clear()
.type('%Ta%10%');

cy.get('.slick-row')
.should('have.length', 4);

cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 10');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 110');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 210');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 310');
});

describe('Custom Header Menu & sub-menus tests', () => {
it('should open Hello sub-menu with 2 options expect it to be aligned to right then trigger alert when command is clicked', () => {
const subCommands = ['Hello World', 'Hello SlickGrid', `Let's play`];
Expand Down Expand Up @@ -291,4 +277,101 @@ describe('Example 14 - Columns Resize by Content', () => {
cy.get('.slick-submenu').should('have.length', 0);
});
});

describe('Filter Predicate on "Title" column that act similarly to an SQL LIKE matcher', () => {
it('should return 4 rows using "%10" (ends with 10)', () => {
cy.get('.search-filter.filter-title')
.clear()
.type('%10');

cy.get('[data-test="total-items"]')
.should('contain', 4);

cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 10');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 110');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 210');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 310');
});

it('should return 4 rows using "%ask%20" (contains "ask" + ends with 20)', () => {
cy.get('.search-filter.filter-title')
.clear()
.type('%ask%20');

cy.get('[data-test="total-items"]')
.should('contain', 4);

cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 20');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 120');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 220');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 320');
});

it('should return all 400 rows using "%ask%" (contains "ask")', () => {
cy.get('.search-filter.filter-title')
.clear()
.type('%ask%');

cy.get('[data-test="total-items"]')
.should('contain', 400);

cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 0');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 1');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 2');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 3');
});

it('should return 4 rows using "Ta%30" (starts with "Ta" + ends with 30)', () => {
cy.get('.search-filter.filter-title')
.clear()
.type('Ta%30');

cy.get('[data-test="total-items"]')
.should('contain', 4);

cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 30');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 130');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 230');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 330');
});

it('should return all 400 rows using "Ta%" (starts with "Ta")', () => {
cy.get('.search-filter.filter-title')
.clear()
.type('Ta%');

cy.get('[data-test="total-items"]')
.should('contain', 400);

cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 0');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 1');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 2');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 3');
});

it('should return 14 rows using "25" (contains 25)', () => {
cy.get('.search-filter.filter-title')
.clear()
.type('25');

cy.get('[data-test="total-items"]')
.should('contain', 14);

cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 25');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 125');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 225');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 250');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 4}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 251');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 5}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 252');
});

it('should not return any row when filtering Title with "%%"', () => {
cy.get('.search-filter.filter-title')
.clear()
.type('%%');

cy.get('[data-test="total-items"]')
.should('contain', 0);
});
});
});

0 comments on commit 828eb8a

Please sign in to comment.