Data Filter

In some conditions, users only want to see the data filtered by certain conditions, or they want to combine multiple data tables by primary-foreign keys in one report.

Users can use the data filter in a report template cell to filter data as they want.

Description
app.js
index.html
styles.css
Copy to CodeMine
Open the demo in new window can open the designer

How to open desgnr

There are several uses for the data filter:

  1. Filter data by a static value:

    const spread = new GC.Spread.Sheets.Workbook('ss', { sheetCount: 1 });
    const ordersTable = spread.dataManager().addTable('Orders', {
        remote: {
            read: {
                url: 'https://demodata.mescius.io/northwind/api/v1/orders'
            }
        }
    });
    ordersTable.fetch().then(() => {
        const reportSheet = spread.addSheetTab(0, 'report1', GC.Spread.Sheets.SheetType.reportSheet);
        const templateSheet = reportSheet.getTemplate();
        // set value and binding for the template
        templateSheet.setTemplateCell(1, 0, {
            type: 'List',
            binding: `Orders[customerId]`,
            filter: {
                condition: { // filter value by static value.
                    and: [
                        {
                            column: "orderDate",
                            operator: "GreaterThan",
                            value: new Date("1997/1/1"),
                        },
                        {
                            column: "orderDate",
                            operator: "LessThan",
                            value: new Date("1997/12/31");
                        }
                    ]
                }
            }
        });
        templateSheet.setTemplateCell(1, 1, {
            type: 'List',
            binding: `Orders[freight]`,
        });
        templateSheet.setTemplateCell(1, 2, {
            type: 'List',
            binding: `Orders[shipName]`,
        });
        // refresh the report
        reportSheet.refresh();
    });
    
  2. Filter data using a formula:

    1. The whole condition rule is formula:
    templateSheet.setTemplateCell(1, 0, {
        type: 'List',
        binding: `Orders[customerId]`,
        filter: {
            condition: { // filter value formula.
                formula: "=YEAR([@orderDate])=1997"
            }
        }
    });
    
    1. The condition rule is a formula on the column:
    templateSheet.setTemplateCell(1, 0, {
        type: 'List',
        binding: `Orders[customerId]`,
        filter: {
            condition: { // filter value formula.
                column: "=YEAR([@orderDate])",
                operator: "Equal",
                value: 1997
            }
        }
    });
    
    1. The column value is formula (Can also use the parameter in the formula):
    templateSheet.setTemplateCell(1, 0, {
        type: 'List',
        binding: `Orders[customerId]`,
        filter: {
            condition: { // filter value formula.
                column: "=YEAR([@orderDate])",
                operator: "Equal",
                formula: `=YEAR("1997-01-01")`
            }
        }
    });
    
  3. Filter data using join tables:

    1. Add a table join relationship in the dataManager:
    const dataManager = spread.dataManager();
    const ordersTable = dataManager.addTable('Orders', {
        remote: {
            read: {
                url: 'https://demodata.mescius.io/northwind/api/v1/orders'
            }
        }
    });
    const employeesTable = dataManager.addTable('Employees', {
        remote: {
            read: {
                url: 'https://demodata.mescius.io/northwind/api/v1/employees'
            }
        }
    });
    // add relationship between ordersTable and employeesTable by employeeId.
    dataManager.addRelationship(ordersTable, "employeeId", "employeesTable", employeesTable, "employeeId", "ordersTable");
    templateSheet.setTemplateCell(1, 0, {
        type: 'List',
        binding: `Orders[customerId]`
    });
    templateSheet.setTemplateCell(1, 1, {
        type: 'List',
        binding: `Employees[firstName]`,
    });
    templateSheet.setTemplateCell(1, 2, {
        type: 'List',
        binding: `Orders[freight]`,
    });
    
    1. Add a table join filter in the filter condition:
    const dataManager = spread.dataManager();
    const ordersTable = dataManager.addTable('Orders', {
        remote: {
            read: {
                url: 'https://demodata.mescius.io/northwind/api/v1/orders'
            }
        }
    });
    const employeesTable = dataManager.addTable('Employees', {
        remote: {
            read: {
                url: 'https://demodata.mescius.io/northwind/api/v1/employees'
            }
        }
    });
    templateSheet.setTemplateCell(1, 0, {
        type: 'List',
        binding: `Orders[customerId]`
    });
    templateSheet.setTemplateCell(1, 1, {
        type: 'List',
        binding: `Employees[firstName]`,
        filter: {
            condition: { // add table join filter condition.
                column: "employeeId",
                operator: "equal",
                dataColumn: {
                    tableName: "Orders",
                    columnName: "employeeId"
                }
            }
        }
    });
    templateSheet.setTemplateCell(1, 2, {
        type: 'List',
        binding: `Orders[freight]`,
    });
    
Open the demo in new window can open the designer There are several uses for the data filter: Filter data by a static value: Filter data using a formula: The whole condition rule is formula: The condition rule is a formula on the column: The column value is formula (Can also use the parameter in the formula): Filter data using join tables: Add a table join relationship in the dataManager: Add a table join filter in the filter condition:
window.onload = async () => { const loadingTip = addLoadingTip(); const { spread, designer } = createSpreadAndDesigner(); const res = await fetch('$DEMOROOT$/en/sample/features/report-sheet/data-settings/data-filter/spread.json'); await spread.fromJSON(correctTableUrl(await res.json())); loadingTip.remove(); if (designer) { designer.refresh(); } } function createSpreadAndDesigner() { const demoHost = document.getElementById('demo-host'); if (window !== top) { return { spread: new GC.Spread.Sheets.Workbook(demoHost, { sheetCount: 1 }), } } else { const designer = new GC.Spread.Sheets.Designer.Designer(demoHost, undefined, undefined, { sheetCount: 1 }); return { designer, spread: designer.getWorkbook(), } } } function addLoadingTip() { const div = document.createElement('div'); div.style.position = 'absolute'; div.style.inset = '0'; div.style.display = 'flex'; div.style.alignItems = 'center'; div.style.justifyContent = 'center'; div.style.background = 'white'; div.style.zIndex = '100'; div.textContent = 'Loading data from server ...'; document.body.appendChild(div); return div; } function correctTableUrl(json) { const baseUrl = '$DEMOROOT$'; const localUrl = 'http://localhost:8070/spreadjs/demos'; const replaceUrl = (obj) => { if (obj && obj.url && obj.url.startsWith(localUrl)) { obj.url = obj.url.replace(localUrl, baseUrl); } } if (json.dataManager && json.dataManager.tables) { json.dataManager.tables.forEach((table) => { if (table.dataSourceOption && table.dataSourceOption.remote) { Object.values(table.dataSourceOption.remote).forEach(replaceUrl); } }); } return json; }
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-designer/styles/gc.spread.sheets.designer.min.css"> <link rel="stylesheet" type="text/css" href="styles.css"> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-print/dist/gc.spread.sheets.print.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-shapes/dist/gc.spread.sheets.shapes.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-charts/dist/gc.spread.sheets.charts.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-reportsheet-addon/dist/gc.spread.report.reportsheet.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script> <script> const designerDependencyScripts = [ '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-barcode/dist/gc.spread.sheets.barcode.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-pdf/dist/gc.spread.sheets.pdf.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-pivot-addon/dist/gc.spread.pivot.pivottables.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-slicers/dist/gc.spread.sheets.slicers.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-tablesheet/dist/gc.spread.sheets.tablesheet.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-ganttsheet/dist/gc.spread.sheets.ganttsheet.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-formula-panel/dist/gc.spread.sheets.formulapanel.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-io/dist/gc.spread.sheets.io.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-designer-resources-en/dist/gc.spread.sheets.designer.resource.en.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-designer/dist/gc.spread.sheets.designer.all.min.js', '$DEMOROOT$/spread/source/js/designer/license.js', ] function appendScriptNode (src) { const script = document.createElement('script'); script.src = src; script.async = false; script.type = 'text/javascript'; document.head.appendChild(script); } if (top === window) { // not in iframe designerDependencyScripts.forEach(appendScriptNode); } </script> <script src="app.js" type="text/javascript"></script> </head> <body> <div class="sample-tutorial"> <div id="demo-host"></div> </div> </body> </html>
body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .sample-tutorial { position: relative; height: 100%; overflow: hidden; } #demo-host { width: 100%; height: 100%; overflow: hidden; float: left; }