Product Catalog

This example uses a common control slicer to filter in DataViews.

This example uses a common control slicer to filter in DataViews. This demo implements an Amazon-like filter panel with the Card Layout Engine to present a product catalog. The slicer allows the user to filter the data in the grid using multiple options. This demo filters TVs by size, resolution, and customer reviews. Try using the filters in the filter panel to pick the type of items that are shown in the grid.
<!DOCTYPE html> <html lang="en"> <head> <base href="/dataviewsjs/demos/en/sample/Showcase/ProductCatalog/purejs/" /> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="keywords" content="filtering" /> <meta name="description" content="This example uses a common control slicer to filter in DataViews." /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Product Catalog | Showcase | GrapeCity DataViewsJS JavaScript Demos</title> <link href="/dataviewsjs/demos/node_modules/normalize.css/normalize.css" rel="stylesheet" type="text/css" /> <link href="/dataviewsjs/demos/static/css/base.css" rel="stylesheet" type="text/css" /> <link href="/dataviewsjs/demos/static/css/bootstrap-snippet.min.css" rel="stylesheet" type="text/css" /> <link href="/dataviewsjs/demos/node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css" /> <link href="/dataviewsjs/demos/static/dataviews/gc.dataviews.core.min.css" rel="stylesheet" type="text/css" /> <link href="/dataviewsjs/demos/static/dataviews/gc.dataviews.cardlayout.min.css" rel="stylesheet" type="text/css" /> <link href="styles.css" rel="stylesheet" type="text/css" /> <!-- Google Tag Manager --> <script> (function (w, d, s, l, i) { w[l] = w[l] || []; w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' }); var f = d.getElementsByTagName(s)[0], j = d.createElement(s), dl = l != 'dataLayer' ? '&l=' + l : ''; j.async = true; j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl; f.parentNode.insertBefore(j, f); })(window, document, 'script', 'dataLayer', 'GTM-WT462SJ'); </script> <!-- End Google Tag Manager --> <script src="/dataviewsjs/demos/static/js/app-polyfills.min.js" type="text/javascript"></script> <script type="text/javascript"> window.process = { env: { NODE_ENV: 'production', USE_NPM: false, USE_CDN: false, SITE_ROOT: '/dataviewsjs/demos', FRAMEWORK: 'purejs', DVJS_LICENSE_KEY: 'GrapeCity-Internal-Use-Only,GrapeCity,E195393772372914#B0KV4Ny56Vr5Wb7w6buJWeGRWb4NXUnNXRlFWWXl6SoN5VzVkYslmQ95WTENkTllVQzd4QhpEejdDNJZlWOp6M7oERQNnWspkaaB5QMhnR7dmUkRnVJR4L5cHTKNkZZdDbRBzZIxmSSR6NrpVQaVUQrBlc6ImYysSd4UlUEZGbw2kMl9UOzQVMId6ZXtUN83CO5RzaZt4VY5kM5pkUGpUUUV7UExUeGpUdTV5dFJ4bPhTc8pGeXJHWrkzNlFzdUtWTr5UQDdVckdGbSVUWr2yMPNzctZVRxEEW9lEbsZHUKJnVaRXT5p6Z0tWMqJGVrtSTIZnaopGSWZXbVNjY0hzQB5We4dnUr3ER8MkI0IyUiwiIGZUNwEkN5MjI0ICSiwSM9ETO6czNygTM0IicfJye#4Xfd5nIZRVV9IiOiMkIsISM6ByUKN7dllmVhRXYEJiOi8kI1tlOiQmcQJCLiEDMzATOwAyMwgDMwIDMyIiOiQncDJCLiI7au26YukHdpNWZwFmcn9iKsAnau26YukHdpNWZwFmcn9iKs86Yu46bj9Se4l6YlBXYydmLqwSbvNmL6VGZ9RXajVGchJ7ZuoCLt36YukHdpNWZwFmcn9iKiojIz5GRiwiI9RXaDVGchJ7RiojIh94QiwSZ5JHd0ICb6VkIsICNxkjM7MjM7czM9MTN9EjI0ICZJJye0ICRiwiI34zZN3yZGNlUnJDe5wkQPVlcBh7SppmUNBlU9dWS7J4ZMRES4MTZkRXTxM7Uq5GeQdHcyFHVup6dQd6ZDpEVrNDSh9kbNdzZrl4dwdPQ', SJS_LICENSE_KEY: '*.grapecity.com,E613631884219496#B0qRgJHWSJ7NyBlc8BjNMRHW7g7YldTZXFTQuFnW4hVOCplVSlVV09ERlhEZuVTVKlTazE4Q6VGSw2CdWZUWSVmbjVXbrxmWFVWR8ZzQro7U84WMGdlbuVHb73kS5kjUTN4NvFVdLdXWVR4Nox6Z7UUSysEcXJEMsN6bDN4TxMDVwVmWBRzKxhkTzAXTaJmdD3CRFJTd8R4R6M5RklWa6oUaLlXMwR4R8ZUdtRWVxUUaQh6VXNDdEhlZ7FHR6QXTPJTVvkWcyZnbSdHRtZHcYF6TKN4axYGcZNjTDF7TvFTTr24VqZjVHVjcLd7QkRmdNxkI0IyUiwiI5gDOEF4QGVjI0ICSiwiMzkTO9kTOyMTM0IicfJye35XX3JSSGljQiojIDJCLiITMuYHITpEIkFWZyB7UiojIOJyebpjIkJHUiwiI4MDMyEDMgkDM8ATOxAjMiojI4J7QiwiIt36YukHdpNWZwFmcn9iKiojIz5GRiwiIj9WagkHdpNUZwFmcHJiOiEmTDJCLlVnc4pjIsZXRiwiI6kDN9EjM4gDOxMjNzEjNiojIklkIs4XZzxWYmpjIyNHZisnOiwmbBJye0ICRiwiI34TQ72kNBV6YXpXdGxGWxdHcol4MyUGUHJVbQVHRx44Sw84YxRkS4QnZadDNmhWWxV5QxFlTlZEbBJ5N8gUNQlDb7J6Kl36YHVnb4NGN92UMFdlNORFU8VDSaFlQSVlS4EHTrA5Ohh', }, }; </script> <script src="/dataviewsjs/demos/node_modules/lodash/lodash.min.js" type="text/javascript"></script> <script src="//cdn.grapecity.com/spreadjs/hosted/scripts/gc.spread.common.12.0.0.min.js" type="text/javascript" ></script> <script src="/dataviewsjs/demos/node_modules/jquery/dist/jquery.min.js" type="text/javascript"></script> <script src="/dataviewsjs/demos/static/dataviews/gc.dataviews.common.min.js" type="text/javascript"></script> <script src="/dataviewsjs/demos/static/dataviews/gc.dataviews.core.min.js" type="text/javascript"></script> <script src="/dataviewsjs/demos/static/dataviews/gc.dataviews.cardlayout.min.js" type="text/javascript"></script> <script src="/dataviewsjs/demos/static/js/license.js" type="text/javascript"></script> </head> <body class="theme-default"> <!-- Google Tag Manager (noscript) --> <noscript ><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-WT462SJ" height="0" width="0" style="display: none; visibility: hidden;" ></iframe ></noscript> <!-- End Google Tag Manager (noscript) --> <noscript>You need to enable JavaScript to run this app.</noscript> <div class="demo-container"> <div class="mobile-filter-entry"> <div class="filter-condition"> <span class="filter-label">Filter</span> <span class="fa fa-angle-down"></span> </div> </div> <div class="filter-panel"> <div class="filter-header">Refine by</div> <div id="tv_display_size" class="slicer"></div> <div id="tv_resolution" class="slicer"></div> <div id="customer_review_star" class="slicer"></div> </div> <div id="grid"></div> </div> <script src="data.js" type="text/javascript"></script> <script src="app.js" type="text/javascript"></script> </body> </html>
var rowTemplate = '<div>\n <div data-column="image"></div>\n <div data-column="description"></div>\n <div data-column="brand"></div>\n <div data-column="price"></div>\n <div data-column="starsIcon"></div>\n</div>'; var imagePresenter = '<img class="tv-image" src={{=it.image}} />'; var descriptionPresenter = '<a><b>{{=it.description}}</b></a>'; var brandPresenter = '<div class="tv-brand"><label>by {{=it.brand}}</label></div>'; var pricePresenter = '<div>${{=it.price}}</div>'; var startPresenter = '<div class="stars-box {{=it.starsIcon}}"></div>'; var cols = [ { id: 'image', caption: 'Image', dataField: 'image', presenter: imagePresenter, }, { id: 'description', caption: 'Description', dataField: 'description', presenter: descriptionPresenter, }, { id: 'brand', caption: 'Brand', dataField: 'brand', presenter: brandPresenter, }, { id: 'price', caption: 'Price', dataField: 'price', presenter: pricePresenter, }, { id: 'starsIcon', caption: 'StarsIcon', dataField: 'starsIcon', presenter: startPresenter, }, { id: 'size', caption: 'TV Display Size', dataField: 'size', }, { id: 'refreshRate', caption: 'RefreshRate', dataField: 'refreshRate', }, { id: 'resolution', caption: 'Television Resolution', dataField: 'resolution', }, { id: 'starsValue', caption: 'Avg. Customer Review', dataField: 'starsValue', }, ]; var getCaption = function getCaption(id) { return _.find(cols, function (col) { return col.id === id; }).caption; }; var layout = new GC.DataViews.CardLayout({ cardHeight: 300, cardWidth: 210, rowTemplate: rowTemplate, }); var dataView = new GC.DataViews.DataView(document.getElementById('grid'), data, cols, layout); function Filter(container, columnName, rangeInfo) { this.container = container; this.columnName = columnName; this.rangeInfo = rangeInfo; dataSource.attachListener(this); this.onDataLoaded(); } Object.assign(Filter.prototype, { onDataLoaded: function onDataLoaded() { var _this = this; var container = this.container; var html = this.render(); container.append(html); container.find('.slicer-item input[type=checkbox]').on('click', function (e) { e.preventDefault(); }); container.find('.slicer-item').on('mousedown', function (e) { var slicerItem = $(e.currentTarget); var targetInput = slicerItem.find('input[type=checkbox]'); if (!targetInput.prop('disabled')) { if (targetInput) { targetInput.prop('checked', !targetInput.prop('checked')); } var condition = _this.getFilterCondition(); if (!condition) { dataSource.doUnfilter(_this.columnName); } else { dataSource.doFilter(_this.columnName, condition); } } }); }, onFiltered: function onFiltered(args) { this.clearSlicerItemClass(); this.updateSlicerItem(); var newData = _.map(args.rowIndexes, function (index) { return data[index]; }); dataView.data.setSource_(newData); // Need to be replaced dataView.invalidate(); }, clearSlicerItemClass: function clearSlicerItemClass() { var items = this.container.find('.slicer-item'); var classes = ['filtered', 'filteredOutByOther']; _.each(items, function (item) { _.each(classes, function (itemClass) { $(item).removeClass(itemClass); }); $(item).find('input[type=checkbox]').prop('disabled', false); }); }, render: function render() { var _this2 = this; var columnName = this.columnName; var data = this.rangeInfo || dataSource.getExclusiveData(columnName); var header = '<div class="filter-details">'.concat(getCaption(columnName), '</div>'); var body = _.map(data, function (it, idx) { if (_this2.rangeInfo) { var count = dataSource.getData(columnName, it.range).length; return _this2.renderItem(it.label, count); } else { var _count = dataSource.getRowIndexes(columnName, idx).length; return _this2.renderItem(it, _count); } }).join(''); return header + body; }, renderItem: function renderItem(label, count) { var span = '<span>'.concat(label, '</span>'); var badge = '<span class="count-badge">('.concat(count, ')</span>'); return '<div class="slicer-item"><input type="checkbox" />'.concat(span).concat(badge, '</div>'); }, getFilterCondition: function getFilterCondition() { var _this3 = this; var container = this.container; var inputs = container.find('input[type=checkbox]'); if (this.rangeInfo) { var ranges = []; _.each(inputs, function (item, i) { if (item.checked) { ranges.push(_this3.rangeInfo[i].range); } }); return ranges.length ? { ranges: ranges, } : null; } else { var indexes = []; _.each(inputs, function (item, i) { if (item.checked) { indexes.push(i); } }); return indexes.length ? { exclusiveRowIndexes: indexes, } : null; } }, updateSlicerItem: function updateSlicerItem() { var _getItemStates = getItemStates(dataSource, this.rangeInfo, this.columnName), filtered = _getItemStates.filtered, filteredOut = _getItemStates.filteredOut; var items = this.container.find('.slicer-item'); for (var k = 0; k < items.length; k++) { if (filtered.has(k)) { $(items[k]).addClass('filtered'); } if (filteredOut.has(k)) { this.filterOut(items[k]); } } }, filterOut: function filterOut(item) { $(item).addClass('filteredOutByOther').find('input[type=checkbox]').prop('disabled', true); }, }); var sizeRanges = [ { range: { min: -Infinity, max: 32, }, label: '32 Inches & Under', }, { range: { min: 33, max: 43, }, label: '33 to 43 Inches', }, { range: { min: 44, max: 49, }, label: '44 to 49 Inches', }, { range: { min: 50, max: 59, }, label: '50 to 59 Inches', }, { range: { min: 60, max: 69, }, label: '60 to 69 Inches', }, { range: { min: 70, max: Infinity, }, label: '70 Inches & Up', }, ]; var reviewRanges = _.rangeRight(1, 5).map(function (min) { return { range: { min: min, max: Infinity, }, label: '<span><span class="stars-box stars-'.concat(min, '"></span><span class="label">&Up</span></span>'), }; }); new Filter($('#tv_display_size'), 'size', sizeRanges); new Filter($('#tv_resolution'), 'resolution'); new Filter($('#customer_review_star'), 'starsValue', reviewRanges); $('.filter-condition').click(function () { $('.filter-panel').toggle(); }); window.addEventListener('resize', function () { var isMobile = $('.mobile-filter-entry').is(':visible'); $('.filter-panel').toggle(!isMobile); });
var SITE_ROOT = window.process.env.SITE_ROOT; var data = [ { size: 42, refreshRate: 60, resolution: '1080p', price: 399.49, brand: 'LG', starsIcon: 'stars-4-5', starsValue: 4.5, image: SITE_ROOT + '/images/51RgQIPeyfL._AA160_.jpg', shipToChina: true, description: 'LG Electronics 42LF5600 42-Inch 1080p 60Hz LED TV', }, { size: 105, refreshRate: 120, resolution: '4K', price: 119999.99, brand: 'Samsung', starsIcon: 'stars-4', starsValue: 4, image: SITE_ROOT + '/images/411r27g4Y4L._AA160_.jpg', shipToChina: true, description: 'Samsung UN105S9 Curved 105-Inch 4K Ultra HD 120Hz 3D Smart LED TV', }, { size: 32, refreshRate: 60, resolution: '720p', price: 237.99, brand: 'Samsung', starsIcon: 'stars-5', starsValue: 5, image: SITE_ROOT + '/images/510PicygL._AA160_.jpg', shipToChina: false, description: 'Samsung UN32J4000 32-Inch 720p LED TV', }, { size: 22, refreshRate: 60, resolution: '1080p', price: 167.99, brand: 'Samsung', starsIcon: 'stars-4-5', starsValue: 4.5, image: SITE_ROOT + '/images/41yd3HTcniL._AA160_.jpg', shipToChina: false, description: 'Samsung UN22F5000 22-Inch 1080p 60Hz LED HDTV (2013 Model)', }, { size: 42, refreshRate: 60, resolution: '1080p', price: 499.99, brand: 'LG', starsIcon: 'stars-3', starsValue: 3, image: SITE_ROOT + '/images/517B8PMhPNL._AA160_.jpg', shipToChina: false, description: 'LG 42LB5600 42-Inch TV (2014 Model)', }, { size: 45, refreshRate: 60, resolution: '1080p', price: 259.99, brand: 'Samsung', starsIcon: 'stars-4', starsValue: 4, image: SITE_ROOT + '/images/516z8QST2CL._AA160_.jpg', shipToChina: true, description: 'Samsung UN32H5203 45-Inch 1080p 60Hz Smart LED TV', }, { size: 46, refreshRate: 60, resolution: '1080p', price: 497.99, brand: 'Samsung', starsIcon: 'stars-3', starsValue: 3, image: SITE_ROOT + '/images/41H0LXbYcXL._AA160_.jpg', shipToChina: true, description: 'Samsung UN32J6300 46-Inch 1080p Smart LED TV', }, { size: 32, refreshRate: 60, resolution: '720p', price: 179.99, brand: 'Upstar', starsIcon: 'stars-4-5', starsValue: 4.5, image: SITE_ROOT + '/images/41JXS3PTiJL._AA160_.jpg', shipToChina: false, description: 'Upstar P32ES8 32-Inch 720p 60Hz LED TV', }, { size: 40, refreshRate: 60, resolution: '480p', price: 327.99, brand: 'Samsung', starsIcon: 'stars-4-5', starsValue: 4.5, image: SITE_ROOT + '/images/51JegzA81lL._AA160_.jpg', shipToChina: false, description: 'Samsung UN40H5003 40-Inch 480p 60Hz LED TV', }, { size: 55, refreshRate: 120, resolution: '1080p', price: 727.25, brand: 'LG', starsIcon: 'stars-4-5', starsValue: 4.5, image: SITE_ROOT + '/images/51yUo1AhEdL._AA160_.jpg', shipToChina: false, description: 'LG Electronics 55LB5900 55-Inch 1080p 120Hz LED TV (2014 Model)', }, { size: 55, refreshRate: 120, resolution: '1080p', price: 679.99, brand: 'LG', starsIcon: 'stars-4', starsValue: 4, image: SITE_ROOT + '/images/4112L6fBNLL._AA160_.jpg', shipToChina: false, description: 'LG Electronics 55LF6000 55-Inch 1080p 120Hz LED TV', }, { size: 24, refreshRate: 60, resolution: '1080p', price: 178.99, brand: 'VIZIO', starsIcon: 'stars-4', starsValue: 4, image: SITE_ROOT + '/images/51tJrIAnF0L._AA160_.jpg', shipToChina: true, description: 'VIZIO E241i-B1 24-Inch 1080p 60Hz Smart LED HDTV (Black)', }, { size: 40, refreshRate: 60, resolution: '1080p', price: 353.7, brand: 'TCL', starsIcon: 'stars-5', starsValue: 5, image: SITE_ROOT + '/images/41iZ3NkxiL._AA160_.jpg', shipToChina: true, description: 'TCL 40FS4610R 40-Inch 1080p Smart LED TV (Roku TV)', }, { size: 55, refreshRate: 60, resolution: '1080p', price: 1000.42, brand: 'Samsung', starsIcon: 'stars-3', starsValue: 3, image: SITE_ROOT + '/images/41H0LXbYcXL._AA160_.jpg', shipToChina: false, description: 'Samsung UN55J6300 55-Inch 1080p Smart LED TV', }, { size: 39, refreshRate: 60, resolution: '1080p', price: 279.99, brand: 'VIZIO', starsIcon: 'stars-5', starsValue: 5, image: SITE_ROOT + '/images/41Voh4kl2hL._AA160_.jpg', shipToChina: false, description: 'VIZIO E390-A1 39-Inch 1080p 60Hz LED TV (Refurbished)', }, { size: 60, refreshRate: 120, resolution: '1080p', price: 899.99, brand: 'LG', starsIcon: 'stars-4', starsValue: 4, image: SITE_ROOT + '/images/51Gx1C4mEFL._AA160_.jpg', shipToChina: false, description: 'LG Electronics 60LB5900 60-Inch 1080p 120Hz LED TV (2014 Model)', }, { size: 32, refreshRate: 60, resolution: '1080p', price: 299.99, brand: 'LG', starsIcon: 'stars-4-5', starsValue: 4.5, image: SITE_ROOT + '/images/51RgQIPeyfL._AA160_.jpg', shipToChina: false, description: 'LG Electronics 32LF5600 32-Inch 1080p 60Hz LED TV', }, { size: 40, refreshRate: 60, resolution: '1080p', price: 307.99, brand: 'TCL', starsIcon: 'stars-4-5', starsValue: 4.5, image: SITE_ROOT + '/images/416bLnX49L._AA160_.jpg', shipToChina: false, description: 'TCL LE40FHDE3010 40-Inch 1080p 60Hz LED TV', }, { size: 28, refreshRate: 60, resolution: '720p', price: 165.99, brand: 'Samsung', starsIcon: 'stars-4-5', starsValue: 4.5, image: SITE_ROOT + '/images/51y45mtIPgL._AA160_.jpg', shipToChina: false, description: 'Samsung UN28H4000 28-Inch 720p 60Hz LED TV', }, { size: 43, refreshRate: 60, resolution: '1080p', price: 445.49, brand: 'VIZIO', starsIcon: 'stars-4-5', starsValue: 4.5, image: SITE_ROOT + '/images/51OEEpDqNHL._AA160_.jpg', shipToChina: false, description: 'VIZIO E43-C2 43-Inch 1080p Smart LED HDTV', }, ]; var dataNames = _.keys(data[0]); var dataValues = _.map(data, function (item) { return _.values(item); }); var dataSource = new GC.Spread.Slicers.GeneralSlicerData(dataValues, dataNames); var getItemStates = function getItemStates(dataSource, rangeState, columnName) { var byOtherColumns = GC.Spread.Slicers.FilteredOutDataType.byOtherColumns; var filteredIndexes = dataSource.getFilteredIndexes(columnName); var filteredOutIndexes = dataSource.getFilteredOutIndexes(columnName, byOtherColumns); var filtered = new Set(); var filteredOut = new Set(); if (rangeState) { var exclusiveData = dataSource.getExclusiveData(columnName); var filteredValues = filteredIndexes.map(function (i) { return exclusiveData[i]; }); var filteredOutValues = filteredOutIndexes.map(function (i) { return exclusiveData[i]; }); var _loop = function _loop(k) { var range = rangeState[k].range; var inrange = function inrange(val) { return val >= range.min && val <= range.max; }; if (filteredValues.some(inrange)) { filtered.add(k); } if (filteredOutValues.some(inrange)) { filteredOut.add(k); } }; for (var k = 0; k < rangeState.length; k++) { _loop(k); } } else { filteredIndexes.forEach(function (k) { filtered.add(k); }); filteredOutIndexes.forEach(function (k) { filteredOut.add(k); }); } return { filtered: filtered, filteredOut: filteredOut, }; };
label { font-weight: normal; margin: 0; } .card-layout.gc-grid { border: 0; } .card-layout .gc-row { padding: 3px; text-align: center; } .card-layout .gc-row .gc-cell { justify-content: center; } #grid { height: 100%; left: 220px; position: absolute; right: 0; } .demo-container { height: 100%; position: relative; -webkit-user-select: none; -ms-user-select: none; user-select: none; width: 100%; } .filter-panel { border: 0; display: block; float: left; height: 100%; overflow: auto; padding-left: 8px; position: static; width: 219px; z-index: auto; } .filter-header { color: #999; font-size: 17px; padding-bottom: 10px; padding-top: 6px; } .filter-details { font-size: 14px; font-weight: 700; padding-bottom: 3px; } .stars-box { background-image: url("/dataviewsjs/demos/images/star-ratings.png"); display: inline-block; height: 13px; overflow: hidden; vertical-align: middle; width: 65px; margin-right: 4px; } .stars-0 { background-position: -65px 0; } .stars-0-5 { background-position: -52px -19px; } .stars-1 { background-position: -52px 0; } .stars-1-5 { background-position: -39px -19px; } .stars-2 { background-position: -39px 0; } .stars-2-5 { background-position: -26px -19px; } .stars-3 { background-position: -26px 0; } .stars-3-5 { background-position: -13px -19px; } .stars-4 { background-position: -13px 0; } .stars-4-5 { background-position: 0 -18px; } .stars-5 { background-position: 0 0; } .tv-image { margin-left: 10px; } .tv-brand { color: #d3d3d3; font-size: 13px; } .tv-price { color: #b12704; } .mobile-filter-entry { display: none; } .filter-condition { border: 1px solid #d3d3d3; cursor: pointer; display: inline-block; font-size: 16px; height: 25px; text-align: center; width: 100px; } .filter-condition .filter-label { margin-right: 5px; } .slicer { margin: 10px 0; } .slicer-item { align-items: center; cursor: pointer; display: flex; margin: 2px 0; } .slicer-item.selected { color: #337ab7; } .slicer-item.selected .label { font-weight: bold; } .slicer-item:hover { color: #e47911; } .slicer-item.filtered { background-color: #fff; } .slicer-item.filteredOutByOther { color: #a6a8b1; } .slicer-item.filteredOutBySelf { background-color: #fff; } .slicer-item input { margin-right: 4px; } .slicer-item .count-badge { margin-left: 4px; color: #a29999; } @media only screen and (max-width: 768px) { #grid { height: 90%; position: static; } .filter-panel { background: #fff; border: 1px solid #d3d3d3; display: none; height: calc(100% - 25px); margin-top: -1px; overflow: auto; padding: 5px 0 0 10px; position: absolute; width: 100%; z-index: 1; } .mobile-filter-entry { display: block; height: 25px; } } /*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIlNob3djYXNlL1Byb2R1Y3RDYXRhbG9nL3B1cmVqcy9zdHlsZXMuc2NzcyIsIlNob3djYXNlL1Byb2R1Y3RDYXRhbG9nL3B1cmVqcy9zdHlsZXMuY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0VBQ0UsbUJBQUE7RUFDQSxTQUFBO0FDQ0Y7O0FERUE7RUFDRSxTQUFBO0FDQ0Y7O0FERUE7RUFDRSxZQUFBO0VBQ0Esa0JBQUE7QUNDRjtBRENFO0VBQ0UsdUJBQUE7QUNDSjs7QURHQTtFQUNFLFlBQUE7RUFDQSxXQUFBO0VBQ0Esa0JBQUE7RUFDQSxRQUFBO0FDQUY7O0FER0E7RUFDRSxZQUFBO0VBQ0Esa0JBQUE7RUFDQSx5QkFBQTtNQUFBLHFCQUFBO1VBQUEsaUJBQUE7RUFDQSxXQUFBO0FDQUY7O0FER0E7RUFDRSxTQUFBO0VBQ0EsY0FBQTtFQUNBLFdBQUE7RUFDQSxZQUFBO0VBQ0EsY0FBQTtFQUNBLGlCQUFBO0VBQ0EsZ0JBQUE7RUFDQSxZQUFBO0VBQ0EsYUFBQTtBQ0FGOztBREdBO0VBQ0UsV0FBQTtFQUNBLGVBQUE7RUFDQSxvQkFBQTtFQUNBLGdCQUFBO0FDQUY7O0FER0E7RUFDRSxlQUFBO0VBQ0EsZ0JBQUE7RUFDQSxtQkFBQTtBQ0FGOztBREdBO0VBQ0UsbUVBQUE7RUFDQSxxQkFBQTtFQUNBLFlBQUE7RUFDQSxnQkFBQTtFQUNBLHNCQUFBO0VBQ0EsV0FBQTtFQUNBLGlCQUFBO0FDQUY7O0FER0E7RUFDRSw0QkFBQTtBQ0FGOztBREdBO0VBQ0UsZ0NBQUE7QUNBRjs7QURHQTtFQUNFLDRCQUFBO0FDQUY7O0FER0E7RUFDRSxnQ0FBQTtBQ0FGOztBREdBO0VBQ0UsNEJBQUE7QUNBRjs7QURHQTtFQUNFLGdDQUFBO0FDQUY7O0FER0E7RUFDRSw0QkFBQTtBQ0FGOztBREdBO0VBQ0UsZ0NBQUE7QUNBRjs7QURHQTtFQUNFLDRCQUFBO0FDQUY7O0FER0E7RUFDRSw0QkFBQTtBQ0FGOztBREdBO0VBQ0Usd0JBQUE7QUNBRjs7QURHQTtFQUNFLGlCQUFBO0FDQUY7O0FER0E7RUFDRSxjQUFBO0VBQ0EsZUFBQTtBQ0FGOztBREdBO0VBQ0UsY0FBQTtBQ0FGOztBREdBO0VBQ0UsYUFBQTtBQ0FGOztBREdBO0VBQ0UseUJBQUE7RUFDQSxlQUFBO0VBQ0EscUJBQUE7RUFDQSxlQUFBO0VBQ0EsWUFBQTtFQUNBLGtCQUFBO0VBQ0EsWUFBQTtBQ0FGO0FERUU7RUFDRSxpQkFBQTtBQ0FKOztBRElBO0VBQ0UsY0FBQTtBQ0RGOztBRElBO0VBQ0UsbUJBQUE7RUFDQSxlQUFBO0VBR0EsYUFBQTtFQUNBLGFBQUE7QUNERjtBREdFO0VBQ0UsY0FBQTtBQ0RKO0FER0k7RUFDRSxpQkFBQTtBQ0ROO0FES0U7RUFDRSxjQUFBO0FDSEo7QURNRTtFQUNFLHNCQUFBO0FDSko7QURPRTtFQUNFLGNBQUE7QUNMSjtBRFFFO0VBQ0Usc0JBQUE7QUNOSjtBRFNFO0VBQ0UsaUJBQUE7QUNQSjtBRFVFO0VBQ0UsZ0JBQUE7RUFDQSxjQUFBO0FDUko7O0FEWUE7RUFDRTtJQUNFLFdBQUE7SUFDQSxnQkFBQTtFQ1RGOztFRFlBO0lBQ0UsZ0JBQUE7SUFDQSx5QkFBQTtJQUNBLGFBQUE7SUFDQSx5QkFBQTtJQUNBLGdCQUFBO0lBQ0EsY0FBQTtJQUNBLHFCQUFBO0lBQ0Esa0JBQUE7SUFDQSxXQUFBO0lBQ0EsVUFBQTtFQ1RGOztFRFlBO0lBQ0UsY0FBQTtJQUNBLFlBQUE7RUNURjtBQUNGIiwiZmlsZSI6IlNob3djYXNlL1Byb2R1Y3RDYXRhbG9nL3B1cmVqcy9zdHlsZXMuY3NzIiwic291cmNlc0NvbnRlbnQiOlsibGFiZWwge1xuICBmb250LXdlaWdodDogbm9ybWFsO1xuICBtYXJnaW46IDA7XG59XG5cbi5jYXJkLWxheW91dC5nYy1ncmlkIHtcbiAgYm9yZGVyOiAwO1xufVxuXG4uY2FyZC1sYXlvdXQgLmdjLXJvdyB7XG4gIHBhZGRpbmc6IDNweDtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuXG4gIC5nYy1jZWxsIHtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgfVxufVxuXG4jZ3JpZCB7XG4gIGhlaWdodDogMTAwJTtcbiAgbGVmdDogMjIwcHg7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgcmlnaHQ6IDA7XG59XG5cbi5kZW1vLWNvbnRhaW5lciB7XG4gIGhlaWdodDogMTAwJTtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICB1c2VyLXNlbGVjdDogbm9uZTtcbiAgd2lkdGg6IDEwMCU7XG59XG5cbi5maWx0ZXItcGFuZWwge1xuICBib3JkZXI6IDA7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICBmbG9hdDogbGVmdDtcbiAgaGVpZ2h0OiAxMDAlO1xuICBvdmVyZmxvdzogYXV0bztcbiAgcGFkZGluZy1sZWZ0OiA4cHg7XG4gIHBvc2l0aW9uOiBzdGF0aWM7XG4gIHdpZHRoOiAyMTlweDtcbiAgei1pbmRleDogYXV0bztcbn1cblxuLmZpbHRlci1oZWFkZXIge1xuICBjb2xvcjogIzk5OTtcbiAgZm9udC1zaXplOiAxN3B4O1xuICBwYWRkaW5nLWJvdHRvbTogMTBweDtcbiAgcGFkZGluZy10b3A6IDZweDtcbn1cblxuLmZpbHRlci1kZXRhaWxzIHtcbiAgZm9udC1zaXplOiAxNHB4O1xuICBmb250LXdlaWdodDogNzAwO1xuICBwYWRkaW5nLWJvdHRvbTogM3B4O1xufVxuXG4uc3RhcnMtYm94IHtcbiAgYmFja2dyb3VuZC1pbWFnZTogdXJsKCcvZGF0YXZpZXdzanMvZGVtb3MvaW1hZ2VzL3N0YXItcmF0aW5ncy5wbmcnKTtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICBoZWlnaHQ6IDEzcHg7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG4gIHdpZHRoOiA2NXB4O1xuICBtYXJnaW4tcmlnaHQ6IDRweDtcbn1cblxuLnN0YXJzLTAge1xuICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAtNjVweCAwO1xufVxuXG4uc3RhcnMtMC01IHtcbiAgYmFja2dyb3VuZC1wb3NpdGlvbjogLTUycHggLTE5cHg7XG59XG5cbi5zdGFycy0xIHtcbiAgYmFja2dyb3VuZC1wb3NpdGlvbjogLTUycHggMDtcbn1cblxuLnN0YXJzLTEtNSB7XG4gIGJhY2tncm91bmQtcG9zaXRpb246IC0zOXB4IC0xOXB4O1xufVxuXG4uc3RhcnMtMiB7XG4gIGJhY2tncm91bmQtcG9zaXRpb246IC0zOXB4IDA7XG59XG5cbi5zdGFycy0yLTUge1xuICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAtMjZweCAtMTlweDtcbn1cblxuLnN0YXJzLTMge1xuICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAtMjZweCAwO1xufVxuXG4uc3RhcnMtMy01IHtcbiAgYmFja2dyb3VuZC1wb3NpdGlvbjogLTEzcHggLTE5cHg7XG59XG5cbi5zdGFycy00IHtcbiAgYmFja2dyb3VuZC1wb3NpdGlvbjogLTEzcHggMDtcbn1cblxuLnN0YXJzLTQtNSB7XG4gIGJhY2tncm91bmQtcG9zaXRpb246IDAgLTE4cHg7XG59XG5cbi5zdGFycy01IHtcbiAgYmFja2dyb3VuZC1wb3NpdGlvbjogMCAwO1xufVxuXG4udHYtaW1hZ2Uge1xuICBtYXJnaW4tbGVmdDogMTBweDtcbn1cblxuLnR2LWJyYW5kIHtcbiAgY29sb3I6ICNkM2QzZDM7XG4gIGZvbnQtc2l6ZTogMTNweDtcbn1cblxuLnR2LXByaWNlIHtcbiAgY29sb3I6ICNiMTI3MDQ7XG59XG5cbi5tb2JpbGUtZmlsdGVyLWVudHJ5IHtcbiAgZGlzcGxheTogbm9uZTtcbn1cblxuLmZpbHRlci1jb25kaXRpb24ge1xuICBib3JkZXI6IDFweCBzb2xpZCAjZDNkM2QzO1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgZm9udC1zaXplOiAxNnB4O1xuICBoZWlnaHQ6IDI1cHg7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgd2lkdGg6IDEwMHB4O1xuXG4gIC5maWx0ZXItbGFiZWwge1xuICAgIG1hcmdpbi1yaWdodDogNXB4O1xuICB9XG59XG5cbi5zbGljZXIge1xuICBtYXJnaW46IDEwcHggMDtcbn1cblxuLnNsaWNlci1pdGVtIHtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgY3Vyc29yOiBwb2ludGVyO1xuICBkaXNwbGF5OiAtd2Via2l0LWJveDtcbiAgZGlzcGxheTogLW1zLWZsZXhib3g7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIG1hcmdpbjogMnB4IDA7XG5cbiAgJi5zZWxlY3RlZCB7XG4gICAgY29sb3I6ICMzMzdhYjc7XG5cbiAgICAubGFiZWwge1xuICAgICAgZm9udC13ZWlnaHQ6IGJvbGQ7XG4gICAgfVxuICB9XG5cbiAgJjpob3ZlciB7XG4gICAgY29sb3I6ICNlNDc5MTE7XG4gIH1cblxuICAmLmZpbHRlcmVkIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xuICB9XG5cbiAgJi5maWx0ZXJlZE91dEJ5T3RoZXIge1xuICAgIGNvbG9yOiAjYTZhOGIxO1xuICB9XG5cbiAgJi5maWx0ZXJlZE91dEJ5U2VsZiB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjtcbiAgfVxuXG4gIGlucHV0IHtcbiAgICBtYXJnaW4tcmlnaHQ6IDRweDtcbiAgfVxuXG4gIC5jb3VudC1iYWRnZSB7XG4gICAgbWFyZ2luLWxlZnQ6IDRweDtcbiAgICBjb2xvcjogI2EyOTk5OTtcbiAgfVxufVxuXG5AbWVkaWEgb25seSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDc2OHB4KSB7XG4gICNncmlkIHtcbiAgICBoZWlnaHQ6IDkwJTtcbiAgICBwb3NpdGlvbjogc3RhdGljO1xuICB9XG5cbiAgLmZpbHRlci1wYW5lbCB7XG4gICAgYmFja2dyb3VuZDogI2ZmZjtcbiAgICBib3JkZXI6IDFweCBzb2xpZCAjZDNkM2QzO1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgaGVpZ2h0OiBjYWxjKDEwMCUgLSAyNXB4KTtcbiAgICBtYXJnaW4tdG9wOiAtMXB4O1xuICAgIG92ZXJmbG93OiBhdXRvO1xuICAgIHBhZGRpbmc6IDVweCAwIDAgMTBweDtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgei1pbmRleDogMTtcbiAgfVxuXG4gIC5tb2JpbGUtZmlsdGVyLWVudHJ5IHtcbiAgICBkaXNwbGF5OiBibG9jaztcbiAgICBoZWlnaHQ6IDI1cHg7XG4gIH1cbn1cbiIsImxhYmVsIHtcbiAgZm9udC13ZWlnaHQ6IG5vcm1hbDtcbiAgbWFyZ2luOiAwO1xufVxuXG4uY2FyZC1sYXlvdXQuZ2MtZ3JpZCB7XG4gIGJvcmRlcjogMDtcbn1cblxuLmNhcmQtbGF5b3V0IC5nYy1yb3cge1xuICBwYWRkaW5nOiAzcHg7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbn1cbi5jYXJkLWxheW91dCAuZ2Mtcm93IC5nYy1jZWxsIHtcbiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG59XG5cbiNncmlkIHtcbiAgaGVpZ2h0OiAxMDAlO1xuICBsZWZ0OiAyMjBweDtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICByaWdodDogMDtcbn1cblxuLmRlbW8tY29udGFpbmVyIHtcbiAgaGVpZ2h0OiAxMDAlO1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIHVzZXItc2VsZWN0OiBub25lO1xuICB3aWR0aDogMTAwJTtcbn1cblxuLmZpbHRlci1wYW5lbCB7XG4gIGJvcmRlcjogMDtcbiAgZGlzcGxheTogYmxvY2s7XG4gIGZsb2F0OiBsZWZ0O1xuICBoZWlnaHQ6IDEwMCU7XG4gIG92ZXJmbG93OiBhdXRvO1xuICBwYWRkaW5nLWxlZnQ6IDhweDtcbiAgcG9zaXRpb246IHN0YXRpYztcbiAgd2lkdGg6IDIxOXB4O1xuICB6LWluZGV4OiBhdXRvO1xufVxuXG4uZmlsdGVyLWhlYWRlciB7XG4gIGNvbG9yOiAjOTk5O1xuICBmb250LXNpemU6IDE3cHg7XG4gIHBhZGRpbmctYm90dG9tOiAxMHB4O1xuICBwYWRkaW5nLXRvcDogNnB4O1xufVxuXG4uZmlsdGVyLWRldGFpbHMge1xuICBmb250LXNpemU6IDE0cHg7XG4gIGZvbnQtd2VpZ2h0OiA3MDA7XG4gIHBhZGRpbmctYm90dG9tOiAzcHg7XG59XG5cbi5zdGFycy1ib3gge1xuICBiYWNrZ3JvdW5kLWltYWdlOiB1cmwoXCIvZGF0YXZpZXdzanMvZGVtb3MvaW1hZ2VzL3N0YXItcmF0aW5ncy5wbmdcIik7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgaGVpZ2h0OiAxM3B4O1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xuICB3aWR0aDogNjVweDtcbiAgbWFyZ2luLXJpZ2h0OiA0cHg7XG59XG5cbi5zdGFycy0wIHtcbiAgYmFja2dyb3VuZC1wb3NpdGlvbjogLTY1cHggMDtcbn1cblxuLnN0YXJzLTAtNSB7XG4gIGJhY2tncm91bmQtcG9zaXRpb246IC01MnB4IC0xOXB4O1xufVxuXG4uc3RhcnMtMSB7XG4gIGJhY2tncm91bmQtcG9zaXRpb246IC01MnB4IDA7XG59XG5cbi5zdGFycy0xLTUge1xuICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAtMzlweCAtMTlweDtcbn1cblxuLnN0YXJzLTIge1xuICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAtMzlweCAwO1xufVxuXG4uc3RhcnMtMi01IHtcbiAgYmFja2dyb3VuZC1wb3NpdGlvbjogLTI2cHggLTE5cHg7XG59XG5cbi5zdGFycy0zIHtcbiAgYmFja2dyb3VuZC1wb3NpdGlvbjogLTI2cHggMDtcbn1cblxuLnN0YXJzLTMtNSB7XG4gIGJhY2tncm91bmQtcG9zaXRpb246IC0xM3B4IC0xOXB4O1xufVxuXG4uc3RhcnMtNCB7XG4gIGJhY2tncm91bmQtcG9zaXRpb246IC0xM3B4IDA7XG59XG5cbi5zdGFycy00LTUge1xuICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAwIC0xOHB4O1xufVxuXG4uc3RhcnMtNSB7XG4gIGJhY2tncm91bmQtcG9zaXRpb246IDAgMDtcbn1cblxuLnR2LWltYWdlIHtcbiAgbWFyZ2luLWxlZnQ6IDEwcHg7XG59XG5cbi50di1icmFuZCB7XG4gIGNvbG9yOiAjZDNkM2QzO1xuICBmb250LXNpemU6IDEzcHg7XG59XG5cbi50di1wcmljZSB7XG4gIGNvbG9yOiAjYjEyNzA0O1xufVxuXG4ubW9iaWxlLWZpbHRlci1lbnRyeSB7XG4gIGRpc3BsYXk6IG5vbmU7XG59XG5cbi5maWx0ZXItY29uZGl0aW9uIHtcbiAgYm9yZGVyOiAxcHggc29saWQgI2QzZDNkMztcbiAgY3Vyc29yOiBwb2ludGVyO1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gIGZvbnQtc2l6ZTogMTZweDtcbiAgaGVpZ2h0OiAyNXB4O1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIHdpZHRoOiAxMDBweDtcbn1cbi5maWx0ZXItY29uZGl0aW9uIC5maWx0ZXItbGFiZWwge1xuICBtYXJnaW4tcmlnaHQ6IDVweDtcbn1cblxuLnNsaWNlciB7XG4gIG1hcmdpbjogMTBweCAwO1xufVxuXG4uc2xpY2VyLWl0ZW0ge1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIGRpc3BsYXk6IC13ZWJraXQtYm94O1xuICBkaXNwbGF5OiAtbXMtZmxleGJveDtcbiAgZGlzcGxheTogZmxleDtcbiAgbWFyZ2luOiAycHggMDtcbn1cbi5zbGljZXItaXRlbS5zZWxlY3RlZCB7XG4gIGNvbG9yOiAjMzM3YWI3O1xufVxuLnNsaWNlci1pdGVtLnNlbGVjdGVkIC5sYWJlbCB7XG4gIGZvbnQtd2VpZ2h0OiBib2xkO1xufVxuLnNsaWNlci1pdGVtOmhvdmVyIHtcbiAgY29sb3I6ICNlNDc5MTE7XG59XG4uc2xpY2VyLWl0ZW0uZmlsdGVyZWQge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xufVxuLnNsaWNlci1pdGVtLmZpbHRlcmVkT3V0QnlPdGhlciB7XG4gIGNvbG9yOiAjYTZhOGIxO1xufVxuLnNsaWNlci1pdGVtLmZpbHRlcmVkT3V0QnlTZWxmIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjtcbn1cbi5zbGljZXItaXRlbSBpbnB1dCB7XG4gIG1hcmdpbi1yaWdodDogNHB4O1xufVxuLnNsaWNlci1pdGVtIC5jb3VudC1iYWRnZSB7XG4gIG1hcmdpbi1sZWZ0OiA0cHg7XG4gIGNvbG9yOiAjYTI5OTk5O1xufVxuXG5AbWVkaWEgb25seSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDc2OHB4KSB7XG4gICNncmlkIHtcbiAgICBoZWlnaHQ6IDkwJTtcbiAgICBwb3NpdGlvbjogc3RhdGljO1xuICB9XG5cbiAgLmZpbHRlci1wYW5lbCB7XG4gICAgYmFja2dyb3VuZDogI2ZmZjtcbiAgICBib3JkZXI6IDFweCBzb2xpZCAjZDNkM2QzO1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgaGVpZ2h0OiBjYWxjKDEwMCUgLSAyNXB4KTtcbiAgICBtYXJnaW4tdG9wOiAtMXB4O1xuICAgIG92ZXJmbG93OiBhdXRvO1xuICAgIHBhZGRpbmc6IDVweCAwIDAgMTBweDtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgei1pbmRleDogMTtcbiAgfVxuXG4gIC5tb2JpbGUtZmlsdGVyLWVudHJ5IHtcbiAgICBkaXNwbGF5OiBibG9jaztcbiAgICBoZWlnaHQ6IDI1cHg7XG4gIH1cbn0iXX0= */