Amazon Slicer

Slicers can have many different types of UI.、 For example, there are many slicers on the www.amazon.com web page that let us filter goods that we are interested in.

Here we show you an amazon slicer sample.
import * as React from 'react'; import * as ReactDOM from 'react-dom'; import './styles.css'; import { AppFunc } from './app-func'; // import { App } from './app-class'; // 1. Functional Component sample ReactDOM.render(<AppFunc />, document.getElementById('app')); // 2. Class Component sample // ReactDOM.render(<App />, document.getElementById('app'));
import * as React from 'react'; import GC from '@mescius/spread-sheets'; import { dataNames, datas } from './data'; function _getElementById(id) { return document.getElementById(id); } const srcBase = "$DEMOROOT$/spread/source/"; class AmazonSlicer { constructor(container) { this.container = container; } setData(slicerData, columnName) { this.slicerData = slicerData; this.columnName = columnName; this.data = slicerData.getData(columnName); this.exclusiveDatas = slicerData.getExclusiveData(columnName); this.slicerData.attachListener(this); this.onDataLoaded(); } onDataLoaded() { let slicer = this; let header = '<div class="slicerHeader">' + '<div class="slicerHeaderBorder"></div>' + '<span style="font-size:medium">' + this.columnName + '</span>' + '<div class="slicerHeaderBorder"></div>' + '</div>'; if (slicer.container.className.indexOf('slicer') < 0) { slicer.container.className = slicer.container.className + ' slicer'; } let datas = slicer.exclusiveDatas; let slicerContent = header; if (slicer.columnName === "Avg. Customer Review") { for (let i = 0; i < datas.length; i++) { let count = 0; for (let j = 0; j < datas.length; j++) { if (parseFloat(datas[j]) >= parseFloat(datas[i])) { count += slicer.slicerData.getRowIndexes(slicer.columnName, slicer.slicerData.getExclusiveData(slicer.columnName).indexOf(datas[j])).length; } } let imageSrcPrefix = srcBase ? srcBase : ''; let image = '<img src="' + imageSrcPrefix + 'images\/' + datas[i] + '.png" alt="' + datas[i] + '"style="vertical-align:middle"></img><span>& Up</span>' slicerContent += '<div>' + image + '<span style="color:#A29999">(' + count + ')</span></div>'; } } else { for (let i = 0; i < datas.length; i++) { let count = slicer.slicerData.getRowIndexes(slicer.columnName, slicer.slicerData.getExclusiveData(slicer.columnName).indexOf(datas[i])).length; // todo label include checkbox slicerContent += '<label style="display: block">' + '<input type="checkbox"/><span>' + datas[i] + '</span><span style="color:#A29999">(' + count + ')</span>' + '</label>'; } } slicer.container.innerHTML = slicerContent; let headerEle = slicer.container.firstChild; headerEle.onmousedown = function (e) { slicer.slicerData.doUnfilter(slicer.columnName); if (slicer.columnName !== "Avg. Customer Review") { let childNodes = slicer.container.childNodes; for (let i = 1, length = childNodes.length; i < length; i++) { childNodes[i].childNodes[0].checked = false; } } } let items = []; let children = slicer.container.childNodes children.forEach((item, index) => { if (index === 0) { return; } items.push(item); item.className = item.className + ' slicerItem'; item.onmouseenter = function (e) { e.target.className += ' hover'; } item.onmouseleave = function (e) { e.target.className = e.target.className.replace('hover', '').trim(); } if (slicer.columnName === "Avg. Customer Review") { item.onclick = function (e) { let exclusiveData = slicer.slicerData.getExclusiveData(slicer.columnName), childNodes = this.parentNode.childNodes, indexes = []; let currentAlt = item.childNodes[0].alt; for (let i = 1, length = childNodes.length; i < length; i++) { let tempAlt = childNodes[i].childNodes[0].alt; if (parseFloat(tempAlt) >= parseFloat(currentAlt)) { indexes.push(exclusiveData.indexOf(tempAlt)); } } if (indexes.length === 0) { slicer.slicerData.doUnfilter(slicer.columnName); } else { slicer.slicerData.doFilter(slicer.columnName, { exclusiveRowIndexes: indexes }) } } } else { // label checkbox item.onclick = function (e) { let exclusiveData = slicer.slicerData.getExclusiveData(slicer.columnName), childNodes = item.parentNode.childNodes, indexes = []; for (let i = 1, length = childNodes.length; i < length; i++) { if (childNodes[i].childNodes[0].checked) { indexes.push(exclusiveData.indexOf(childNodes[i].childNodes[1].innerText)) } } if (indexes.length === 0) { slicer.slicerData.doUnfilter(slicer.columnName); } else { slicer.slicerData.doFilter(slicer.columnName, { exclusiveRowIndexes: indexes }) } } } }); slicer.items = items; slicer.onFiltered(); } resetClass() { let items = this.items; let classes = ["filtered", "partial", "filteredOutBySelf", "filteredOutByOther"]; for (let i = 0; i < items.length; i++) { for (let k = 0; k < classes.length; k++) { items[i].className = items[i].className.replace(classes[k], '').trim(); } } } onFiltered() { this.resetClass(); let items = this.items; let filteredItems = this.slicerData.getFilteredIndexes(this.columnName); for (let i = 0; i < filteredItems.length; i++) { if (items[filteredItems[i]].className.indexOf('filtered') < 0) { items[filteredItems[i]].className = items[filteredItems[i]].className + ' filtered'; } } let filteredOutItems = this.slicerData.getFilteredOutIndexes(this.columnName, GC.Spread.Slicers.FilteredOutDataType.byCurrentColumn); for (let i = 0; i < filteredOutItems.length; i++) { if (items[filteredOutItems[i]].className.indexOf('filteredOutBySelf').indexOf < 0) { items[filteredOutItems[i]].className = items[filteredOutItems[i]].className + ' filteredOutBySelf' } } let filteredOutByOtherItems = this.slicerData.getFilteredOutIndexes(this.columnName, GC.Spread.Slicers.FilteredOutDataType.byOtherColumns); for (let i = 0; i < filteredOutByOtherItems.length; i++) { if (items[filteredOutByOtherItems[i]].className.indexOf('filteredOutByOther') < 0) { items[filteredOutByOtherItems[i]].className = items[filteredOutByOtherItems[i]].className + 'filteredOutByOther' } } this.refreshList(); } refreshList() { let list = _getElementById('ss'); let indexes = this.slicerData.getFilteredRowIndexes(); let listItemsHtml = ''; for (let i = 0, rowCount = indexes.length; i < rowCount; i++) { let imageSrcPrefix = srcBase ? srcBase : ''; let image1 = '<div class="p_image"><img src="' + imageSrcPrefix + 'images\/' + datas[indexes[i]][0] + '" style="width:160px;height:160px"></img></div>'; let image2 = '<div class="p_vote"><img src="' + imageSrcPrefix + 'images\/' + datas[indexes[i]][6] + '.png"/></div>'; listItemsHtml += '<div style="width:200px;margin-left:20px;margin-top:10px;display:inline-block" >' + image1 + '<div class="p_description" style="height:86px;font-size:medium;color:#0066C0">' + datas[indexes[i]][1] + '</div>' + '<div class="p_company">by ' + datas[indexes[i]][2] + '</div>' + '<div class="p_price" style="font-weight:bold;color:#B52704">$' + datas[indexes[i]][3] + '</div>' + image2 + '</div>' } list.innerHTML = listItemsHtml; } } export function AppFunc() { React.useEffect(() => { let dataSource = new GC.Spread.Slicers.GeneralSlicerData(datas, dataNames); let brandSlicer = new AmazonSlicer(_getElementById('slicer_Brand')); brandSlicer.setData(dataSource, "Brand"); let memorySlicer = new AmazonSlicer(_getElementById('slicer_Memory')); memorySlicer.setData(dataSource, "Internal Memory"); let netWorkSlicer = new AmazonSlicer(_getElementById('slicer_Network')); netWorkSlicer.setData(dataSource, "Network"); let customerReviewSlicer = new AmazonSlicer(_getElementById('slicer_CustomerReview')); customerReviewSlicer.setData(dataSource, "Avg. Customer Review"); }, []); return ( <div class="sample-tutorial"> <div id="ss" class="sample-spreadsheets"> </div> <div class="options-container"> <p class="desc">Select different options to filter the results in the store.</p> <div id="slicer_Brand" class="slicer"></div> <div id="slicer_Memory" class="slicer"></div> <div id="slicer_Network" class="slicer"></div> <div id="slicer_CustomerReview" class="slicer"></div> </div> </div> ); }
import * as React from 'react'; import GC from '@mescius/spread-sheets'; import { dataNames, datas } from './data'; const Component = React.Component; function _getElementById(id) { return document.getElementById(id); } const srcBase = "$DEMOROOT$/spread/source/"; class AmazonSlicer { constructor (container) { this.container = container; } setData (slicerData, columnName) { this.slicerData = slicerData; this.columnName = columnName; this.data = slicerData.getData(columnName); this.exclusiveDatas = slicerData.getExclusiveData(columnName); this.slicerData.attachListener(this); this.onDataLoaded(); } onDataLoaded () { let slicer = this; let header = '<div class="slicerHeader">' + '<div class="slicerHeaderBorder"></div>' + '<span style="font-size:medium">' + this.columnName + '</span>' + '<div class="slicerHeaderBorder"></div>' + '</div>'; if (slicer.container.className.indexOf('slicer') < 0) { slicer.container.className = slicer.container.className + ' slicer'; } let datas = slicer.exclusiveDatas; let slicerContent = header; if (slicer.columnName === "Avg. Customer Review") { for (let i = 0; i < datas.length; i++) { let count = 0; for (let j = 0; j < datas.length; j++) { if (parseFloat(datas[j]) >= parseFloat(datas[i])) { count += slicer.slicerData.getRowIndexes(slicer.columnName, slicer.slicerData.getExclusiveData(slicer.columnName).indexOf(datas[j])).length; } } let imageSrcPrefix = srcBase ? srcBase : ''; let image = '<img src="' + imageSrcPrefix + 'images\/' + datas[i] + '.png" alt="' + datas[i] + '"style="vertical-align:middle"></img><span>& Up</span>' slicerContent += '<div>' + image + '<span style="color:#A29999">(' + count + ')</span></div>'; } } else { for (let i = 0; i < datas.length; i++) { let count = slicer.slicerData.getRowIndexes(slicer.columnName, slicer.slicerData.getExclusiveData(slicer.columnName).indexOf(datas[i])).length; // todo label include checkbox slicerContent += '<label style="display: block">' + '<input type="checkbox"/><span>' + datas[i] + '</span><span style="color:#A29999">(' + count + ')</span>' + '</label>'; } } slicer.container.innerHTML = slicerContent; let headerEle = slicer.container.firstChild; headerEle.onmousedown = function (e) { slicer.slicerData.doUnfilter(slicer.columnName); if (slicer.columnName !== "Avg. Customer Review") { let childNodes = slicer.container.childNodes; for (let i = 1, length = childNodes.length; i < length; i++) { childNodes[i].childNodes[0].checked = false; } } } let items = []; let children = slicer.container.childNodes children.forEach((item, index) => { if (index === 0) { return; } items.push(item); item.className = item.className + ' slicerItem'; item.onmouseenter = function (e) { e.target.className += ' hover'; } item.onmouseleave = function (e) { e.target.className = e.target.className.replace('hover', '').trim(); } if (slicer.columnName === "Avg. Customer Review") { item.onclick = function (e) { let exclusiveData = slicer.slicerData.getExclusiveData(slicer.columnName), childNodes = this.parentNode.childNodes, indexes = []; let currentAlt = item.childNodes[0].alt; for (let i = 1, length = childNodes.length; i < length; i++) { let tempAlt = childNodes[i].childNodes[0].alt; if (parseFloat(tempAlt) >= parseFloat(currentAlt)) { indexes.push(exclusiveData.indexOf(tempAlt)); } } if (indexes.length === 0) { slicer.slicerData.doUnfilter(slicer.columnName); } else { slicer.slicerData.doFilter(slicer.columnName, {exclusiveRowIndexes: indexes}) } } } else { // label checkbox item.onclick = function (e) { let exclusiveData = slicer.slicerData.getExclusiveData(slicer.columnName), childNodes = item.parentNode.childNodes, indexes = []; for (let i = 1, length = childNodes.length; i < length; i++) { if (childNodes[i].childNodes[0].checked) { indexes.push(exclusiveData.indexOf(childNodes[i].childNodes[1].innerText)) } } if (indexes.length === 0) { slicer.slicerData.doUnfilter(slicer.columnName); } else { slicer.slicerData.doFilter(slicer.columnName, {exclusiveRowIndexes: indexes}) } } } }); slicer.items = items; slicer.onFiltered(); } resetClass () { let items = this.items; let classes = ["filtered", "partial", "filteredOutBySelf", "filteredOutByOther"]; for (let i = 0; i < items.length; i++) { for (let k = 0; k < classes.length; k++) { items[i].className = items[i].className.replace(classes[k], '').trim(); } } } onFiltered () { this.resetClass(); let items = this.items; let filteredItems = this.slicerData.getFilteredIndexes(this.columnName); for (let i = 0; i < filteredItems.length; i++) { if (items[filteredItems[i]].className.indexOf('filtered') < 0) { items[filteredItems[i]].className = items[filteredItems[i]].className + ' filtered'; } } let filteredOutItems = this.slicerData.getFilteredOutIndexes(this.columnName, GC.Spread.Slicers.FilteredOutDataType.byCurrentColumn); for (let i = 0; i < filteredOutItems.length; i++) { if (items[filteredOutItems[i]].className.indexOf('filteredOutBySelf').indexOf < 0) { items[filteredOutItems[i]].className = items[filteredOutItems[i]].className + ' filteredOutBySelf' } } let filteredOutByOtherItems = this.slicerData.getFilteredOutIndexes(this.columnName, GC.Spread.Slicers.FilteredOutDataType.byOtherColumns); for (let i = 0; i < filteredOutByOtherItems.length; i++) { if (items[filteredOutByOtherItems[i]].className.indexOf('filteredOutByOther') < 0) { items[filteredOutByOtherItems[i]].className = items[filteredOutByOtherItems[i]].className + 'filteredOutByOther' } } this.refreshList(); } refreshList () { let list = _getElementById('ss'); let indexes = this.slicerData.getFilteredRowIndexes(); let listItemsHtml = ''; for (let i = 0, rowCount = indexes.length; i < rowCount; i++) { let imageSrcPrefix = srcBase ? srcBase : ''; let image1 = '<div class="p_image"><img src="' + imageSrcPrefix + 'images\/' + datas[indexes[i]][0] + '" style="width:160px;height:160px"></img></div>'; let image2 = '<div class="p_vote"><img src="' + imageSrcPrefix + 'images\/' + datas[indexes[i]][6] + '.png"/></div>'; listItemsHtml += '<div style="width:200px;margin-left:20px;margin-top:10px;display:inline-block" >' + image1 + '<div class="p_description" style="height:86px;font-size:medium;color:#0066C0">' + datas[indexes[i]][1] + '</div>' + '<div class="p_company">by ' + datas[indexes[i]][2] + '</div>' + '<div class="p_price" style="font-weight:bold;color:#B52704">$' + datas[indexes[i]][3] + '</div>' + image2 + '</div>' } list.innerHTML = listItemsHtml; } } export class App extends Component { constructor(props) { super(props); } render() { return ( <div class="sample-tutorial"> <div id="ss" class="sample-spreadsheets"> </div> <div class="options-container"> <p class="desc">Select different options to filter the results in the store.</p> <div id="slicer_Brand" class="slicer"></div> <div id="slicer_Memory" class="slicer"></div> <div id="slicer_Network" class="slicer"></div> <div id="slicer_CustomerReview" class="slicer"></div> </div> </div> ); } componentDidMount () { let dataSource = new GC.Spread.Slicers.GeneralSlicerData(datas, dataNames); let brandSlicer = new AmazonSlicer(_getElementById('slicer_Brand')); brandSlicer.setData(dataSource, "Brand"); let memorySlicer = new AmazonSlicer(_getElementById('slicer_Memory')); memorySlicer.setData(dataSource, "Internal Memory"); let netWorkSlicer = new AmazonSlicer(_getElementById('slicer_Network')); netWorkSlicer.setData(dataSource, "Network"); let customerReviewSlicer = new AmazonSlicer(_getElementById('slicer_CustomerReview')); customerReviewSlicer.setData(dataSource, "Avg. Customer Review"); } }
<!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/react/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <!-- SystemJS --> <script src="$DEMOROOT$/en/react/node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('$DEMOROOT$/en/lib/react/license.js').then(function () { System.import('./src/app'); }); </script> </head> <body> <div id="app"></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 { margin-bottom: 10px; } .slicerHeader { position: relative; padding-top: 1px; font-weight: 600; } .hover { color: #E47911; cursor: default; } .desc { padding: 2px 10px; margin-top: 0; background-color: #F4F8EB; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } #app { height: 100%; }
var dataNames = ["Image", "Description", "Brand", "Price", "Internal Memory", "Network", "Avg. Customer Review", "ShipToChina"]; //"size", var datas = [["NOKIA521.jpg", "Nokia Lumia 521 T-Mobile Cell Phone - White", "Nokia", "49.99", "16", "3G", "4", true], ["LG450.jpg", "LG 450 Black - No Contract (T-Mobile)", "LG", "29.99", "4", "3G", "4", true], ["LGC365.jpg", "LG Xpression C395 Unlocked GSM Slider Cell Phone with Touchscreen + Full QWERTY Keyboard - Red", "LG", "49.99", "32", "3G", "3.5", false], ["BLUPink.jpg", "BLU Dash JR W D141w Unlocked GSM Dual-SIM Android Cell Phone - Pink", "BLU", "18.99", "4", "3G", "4", true], ["BLUWhite.jpg", "BLU Dash JR W D141w Unlocked GSM Dual-SIM Android Cell Phone - White", "BLU", "129.99", "32", "4G", "3.5", false], ["LGA275.jpg", "LG A275 Black Unlocked GSM Dual SIM QuadBand Cell Phone - International Version - No Warranty", "LG", "79.89", "4", "3G", "3.5", false], ["BLUBlue.jpg", "BLU Dash JR W D141w Unlocked GSM Dual-SIM Android Cell Phone - Blue", "BLU", "59.99", "4", "GSM", "4", false], ["LGVN250.jpg", "LG Cosmos VN250 Verizon Phone (POST PAID)", "LG", "449.99", "64", "4G", "3.5", false], ["LGOptimus.jpg", "LG Optimus Dynamic Android Prepaid Phone with Triple Minutes (Tracfone)", "LG", "29.99", "16", "GSM", "4", true], ["LG305c.jpg", "Tracfone LG 305C with Triple Minutes for Life (Tracfone)", "LG", "99.99", "16", "3G", "4", false], ["SamsungC3520.jpg", "Samsung GT-C3520I Unlocked Quad-Band GSM Phone with 1.3 MP Camera, MP3 Player...", "Samsung", "64.99", "8", "3G", "3.5", false], ["LGVN251.jpg", "LG VN251 VN 251 COSMOS 2 Verizon Wireless Slider Keyboard Bluetooth Cell Phone", "LG", "58.69", "16", "4G", "4", false], ["ZTEUSAZ222.jpg", "AT&T Z222 Go Phone (AT&T)", "ZTE USA", "24.85", "4", "4G", "4", false], ["BLUQ170T.jpg", "BLU Q170T Samba TV Unlocked Dual SIM Quad-Band GSM Phone (Black/Red)", "BLU", "26.08", "32", "3G", "3.5", true], ["Apple4SWhite.jpg", "Apple iPhone 4S GSM Unlocked 16GB Smartphone - White", "Apple", "199.99", "16", "GSM", "4", false], ["LG840G.jpg", "LG 840G Prepaid Phone With Triple Minutes (Tracfone)", "LG", "48.95", "32", "4G", "3.5", false], ["SamsungA157V.jpg", "Samsung a157V (AT&T)", "Samsung", "14.99", "8", "3G", "3.5", false], ["LGVN150.jpg", "LG Revere VN150 Bluetooth CDMA Camera Flip Cell Phone Verizon or PagePlus", "LG", "72.50", "2", "GSM", "3.5", false], ["NOKIA106.jpg", "Nokia 106 Unlocked GSM Dual-Band Cell Phone w/ SMS and FM Radio - Black", "Nokia", "17.99", "2", "GSM", "4", false], ["ZTEZ222.jpg", "Unlocked ZTE Z222 Flip Phone With Camera For ATT, T-Mobile and Other Supported GSM Networks...", "ZTE", "27.79", "16", "4G", "3.5", false], ["Apple4SUnlocked.jpg", "Apple iPhone 4S 16GB 3G WiFi Black Smartphone Unlocked", "Apple", "182.99", "16", "3G", "4", false], ["BLUQ170TBlue.jpg", "BLU Q170T Samba TV Unlocked Dual SIM Quad-Band GSM Phone (Black/Blue)", "BLU", "22.99", "2", "GSM", "4", false], ["SamsungC3520Gray.jpg", "Samsung GT-C3520BLK Unlocked GSM Cell Phone,Charcoal Gray", "Samsung", "99.99", "8", "3G", "3.5", false], ["LG306G.jpg", "LG 306G 3G Cell Phone | TracFone", "TracFone", "4.99", "2", "GSM", "3.5", false]]; export { dataNames, datas }
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true, react: true }, meta: { '*.css': { loader: 'css' } }, 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-react': 'npm:@mescius/spread-sheets-react/index.js', '@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js', 'react': 'npm:react/umd/react.production.min.js', 'react-dom': 'npm:react-dom/umd/react-dom.production.min.js', 'css': 'npm:systemjs-plugin-css/css.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: 'jsx' }, "node_modules": { defaultExtension: 'js' }, } }); })(this);