Skip to content

add optional custom auto-filter to table #1670

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions lib/xlsx/xform/table/custom-filter-xform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const BaseXform = require('../base-xform');

class CustomFilterXform extends BaseXform {
get tag() {
return 'customFilter';
}

render(xmlStream, model) {
xmlStream.leafNode(this.tag, {
val: model.val,
operator: model.operator,
});
}

parseOpen(node) {
if (node.name === this.tag) {
this.model = {
val: node.attributes.val,
operator: node.attributes.operator,
};
return true;
}
return false;
}

parseText() {}

parseClose() {
return false;
}
}

module.exports = CustomFilterXform;
74 changes: 66 additions & 8 deletions lib/xlsx/xform/table/filter-column-xform.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
const BaseXform = require('../base-xform');
const ListXform = require('../list-xform');

const CustomFilterXform = require('./custom-filter-xform');
const FilterXform = require('./filter-xform');

class FilterColumnXform extends BaseXform {
constructor() {
super();

this.map = {
customFilters: new ListXform({
tag: 'customFilters',
count: false,
empty: true,
childXform: new CustomFilterXform(),
}),
filters: new ListXform({
tag: 'filters',
count: false,
empty: true,
childXform: new FilterXform(),
}),
};
}

get tag() {
return 'filterColumn';
}
Expand All @@ -10,6 +33,17 @@ class FilterColumnXform extends BaseXform {
}

render(xmlStream, model) {
if (model.customFilters) {
xmlStream.openNode(this.tag, {
colId: model.colId,
hiddenButton: model.filterButton ? '0' : '1',
});

this.map.customFilters.render(xmlStream, model.customFilters);

xmlStream.closeNode();
return true;
}
xmlStream.leafNode(this.tag, {
colId: model.colId,
hiddenButton: model.filterButton ? '0' : '1',
Expand All @@ -18,20 +52,44 @@ class FilterColumnXform extends BaseXform {
}

parseOpen(node) {
if (node.name === this.tag) {
const {attributes} = node;
this.model = {
filterButton: attributes.hiddenButton === '0',
};
if (this.parser) {
this.parser.parseOpen(node);
return true;
}
return false;
const {attributes} = node;
switch (node.name) {
case this.tag:
this.model = {
filterButton: attributes.hiddenButton === '0',
};
return true;
default:
this.parser = this.map[node.name];
if (this.parser) {
this.parseOpen(node);
return true;
}
throw new Error(`Unexpected xml node in parseOpen: ${JSON.stringify(node)}`);
}
}

parseText() {}

parseClose() {
return false;
parseClose(name) {
if (this.parser) {
if (!this.parser.parseClose(name)) {
this.parser = undefined;
}
return true;
}
switch (name) {
case this.tag:
this.model.customFilters = this.map.customFilters.model;
return false;
default:
// could be some unrecognised tags
return true;
}
}
}

Expand Down
31 changes: 31 additions & 0 deletions lib/xlsx/xform/table/filter-xform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const BaseXform = require('../base-xform');

class FilterXform extends BaseXform {
get tag() {
return 'filter';
}

render(xmlStream, model) {
xmlStream.leafNode(this.tag, {
val: model.val,
});
}

parseOpen(node) {
if (node.name === this.tag) {
this.model = {
val: node.attributes.val,
};
return true;
}
return false;
}

parseText() {}

parseClose() {
return false;
}
}

module.exports = FilterXform;
Binary file added spec/integration/data/test-issue-1669.xlsx
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const ExcelJS = verquire('exceljs');

describe('github issues', () => {
it('issue 1669 - optional autofilter and custom autofilter on tables', () => {
const wb = new ExcelJS.Workbook();
return wb.xlsx.readFile('./spec/integration/data/test-issue-1669.xlsx');
}).timeout(6000);
});
30 changes: 30 additions & 0 deletions spec/unit/xlsx/xform/table/custom-filter-xform.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const testXformHelper = require('../test-xform-helper');

const CustomFilterXform = verquire('xlsx/xform/table/custom-filter-xform');

const expectations = [
{
title: 'custom filter',
create() {
return new CustomFilterXform();
},
preparedModel: {val: '*brandywine*'},
xml: '<customFilter val="*brandywine*"/>',
parsedModel: {val: '*brandywine*'},
tests: ['render', 'renderIn', 'parse'],
},
{
title: 'custom filter with operator',
create() {
return new CustomFilterXform();
},
preparedModel: {operator: 'notEqual', val: '4'},
xml: '<customFilter operator="notEqual" val="4"/>',
parsedModel: {operator: 'notEqual', val: '4'},
tests: ['render', 'renderIn', 'parse'],
},
];

describe('CustomFilterXform', () => {
testXformHelper(expectations);
});
19 changes: 19 additions & 0 deletions spec/unit/xlsx/xform/table/filter-column-xform.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,25 @@ const expectations = [
tests: ['prepare', 'render', 'renderIn', 'parse'],
options: {index: 1},
},
{
title: 'with custom filter',
create() {
return new FilterColumnXform();
},
initialModel: {filterButton: false, customFilters: [{val: '*brandywine*'}]},
preparedModel: {
colId: '0',
filterButton: false,
customFilters: [{val: '*brandywine*'}],
},
xml:
'<filterColumn colId="0" hiddenButton="1"><customFilters><customFilter val="*brandywine*"/></customFilters></filterColumn>',
get parsedModel() {
return this.initialModel;
},
tests: ['prepare', 'render', 'renderIn', 'parse'],
options: {index: 0},
},
];

describe('FilterColumnXform', () => {
Expand Down