Item Slicer

SpreadJS also provides an ItemSlicer. ItemSlicer is a filter UI. It provides a convenient way to filter the data.

ItemSlicer is a slicer component and is independent from the sheet. You can add the ItemSlicer anywhere. ItemSlicer should be used with slicer data (such as GeneralSlicerData, TableSlicerData, or slicer data that extends from GeneralSlicerData). If you use ItemSlicer with TableSlicerData, the table can also be synchronized when filtered by ItemSlicer. You can create your own ItemSlicer as follows: Create data source and a new GeneralSlicerData. Get column data and build UI. Get the filtered result and update UI. Create an ItemSlicer, and attach it to GeneralSlicerData then append it to the DOM tree. You can also adjust the size of ItemSlicer. Now you can easily filter data with the ItemSlicer, enjoy it :-)
<template> <div class="sample-tutorial"> <div id="ss" class="sample-spreadsheets"></div> <div class="options-container"> <p class="desc">Click on the items in this slicer to filter by that class. You can Ctrl+Left Click to select multiple items.</p> <div id="nameSlicerHost" class="slicer"></div> <div id="classSlicerHost" class="slicer"></div> </div> </div> </template> <script> import Vue from 'vue'; import '@mescius/spread-sheets-vue' import GC from '@mescius/spread-sheets'; import "@mescius/spread-sheets-slicers"; import './styles.css'; let App = Vue.extend({ name: "app", data() { return { }; }, mounted(){ let columnNames = ["Name", "Class", "Gender", "Math", "English", "Total Score"]; let data = [["Student1", 1, "female", "69", "66", "135"], ["Student2", 1, "female", "99", "85", "184"], ["Student3", 1, "male", "78", "77", "155"], ["Student4", 1, "male", "54", "80", "134"], ["Student7", 2, "male", "87", "98", "185"], ["Student8", 2, "male", "78", "85", "163"], ["Student9", 2, "female", "100", "90", "190"], ["Student10", 2, "female", "68", "54", "122"], ["Student11", 2, "female", "97", "100", "197"], ["Student12", 2, "female", "81", "90", "171"], ["Student15", 2, "female", "90", "68", "158"], ["Student16", 3, "male", "86", "70", "156"], ["Student17", 3, "male", "88", "89", "177"], ["Student18", 3, "male", "54", "80", "134"], ["Student19", 3, "male", "81", "75", "156"], ["Student23", 3, "female", "78", "98", "176"], ["Student24", 3, "female", "90", "98", "188"], ["Student25", 3, "male", "60", "30", "90"], ["Student26", 3, "female", "0", "0", "0"], ["Student27", 3, "female", "100", "100", "200"], ["Student28", 3, "male", "89", "78", "167"] ]; let slicerData = new GC.Spread.Slicers.GeneralSlicerData(data, columnNames); let onFiltered = slicerData.onFiltered; slicerData.onFiltered = function () { onFiltered.call(slicerData); refreshList(slicerData); } let nameSlicer = new GC.Spread.Sheets.Slicers.ItemSlicer("Name", slicerData, "Name"); nameSlicer.height(200); nameSlicer.width(180) nameSlicer.columnCount(2); document.getElementById('nameSlicerHost').appendChild(nameSlicer.getDOMElement()); let classSlicer = new GC.Spread.Sheets.Slicers.ItemSlicer("Class", slicerData, "Class"); classSlicer.height(200); classSlicer.width(180) document.getElementById('classSlicerHost').appendChild(classSlicer.getDOMElement()); initList(data, columnNames); } }); const initList = (data, columnNames) => { let tableStr = '<tr>'; for (let i = 0; i < columnNames.length; i++) { tableStr += "<th>" + columnNames[i] + "</th>"; } tableStr += '</tr>'; for (let i = 0; i < data.length; i++) { tableStr += "<tr>"; for (let j = 0; j < data[i].length; j++) { tableStr += "<td>" + data[i][j] + "</td>"; } tableStr += "</tr>"; } let table = document.createElement('table'); table.innerHTML = tableStr; table.border = 1; table.cellPadding = 0; table.cellSpacing = 0; document.getElementById('ss').appendChild(table); } const refreshList = (slicerData) => { let filteredRowIndexs = slicerData.getFilteredRowIndexes(); let trs = document.getElementsByTagName('tr'); for (let i = 0; i < slicerData.data.length; i++) { if (filteredRowIndexs.indexOf(i) !== -1) { trs[i + 1].style.display = ''; } else { trs[i + 1].style.display = 'none'; } } } new Vue({ render: h => h(App) }).$mount('#app'); </script>
<!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/vue/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <!-- SystemJS --> <script src="$DEMOROOT$/en/vue/node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app.vue'); System.import('$DEMOROOT$/en/lib/vue/license.js'); </script> </head> <body> <div id="app" style="height: 100%;"></div> </body> </html>
.sample-tutorial { position: relative; height: 100%; overflow: hidden; } .sample-spreadsheets { width: calc(100% - 280px); height: 100%; overflow: auto; float: left; } .options-container { float: right; width: 280px; padding: 12px; height: 100%; box-sizing: border-box; background: #fbfbfb; overflow: auto; } .option-row { font-size: 14px; padding: 5px; margin-top: 10px; } .slicer { height: 220px; position: relative; } table th, table td { padding: 4px 8px; } .desc{ padding:2px 10px; background-color:#F4F8EB; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; }
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true }, meta: { '*.css': { loader: 'css' }, '*.vue': { loader: 'vue-loader' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { '@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-shapes': 'npm:@mescius/spread-sheets-shapes/index.js', '@mescius/spread-sheets-slicers': 'npm:@mescius/spread-sheets-slicers/index.js', '@mescius/spread-sheets-vue': 'npm:@mescius/spread-sheets-vue/index.js', '@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js', 'jszip': 'npm:jszip/dist/jszip.js', 'css': 'npm:systemjs-plugin-css/css.js', 'vue': 'npm:vue/dist/vue.min.js', 'vue-loader': 'npm:systemjs-vue-browser/index.js', 'tiny-emitter': 'npm:tiny-emitter/index.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', 'systemjs-babel-build':'npm:systemjs-plugin-babel/systemjs-babel-browser.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'js' }, rxjs: { defaultExtension: 'js' }, "node_modules": { defaultExtension: 'js' } } }); })(this);