Version 1
Version 1

E-commerce Website Interface

The enhanced features provided by DataViewsJS can be used to create a comprehensive e-commerce website design layout. The optimized user interface of DataViewsJS is supported in large screen devices as well as mobile and tablet views.

You can create this demo using the following DataViewsJS features:

Use the following steps to create an interface for the e-commerce website using DataViewsJS, as shown in the following image.

ecommgrid

Sample Code

  1. Add the following CSS and JS references to the project.
<!DOCTYPE html>
<html style="height:100%;font-size:14px">
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!--CSS-->
    <link href="css/bootstrap-snippet.min.css" rel="stylesheet" />
    <link href="css/font-awesome.min.css" rel="stylesheet" />
    <link href="css/gc.dataviews.calendar.min.css" rel="stylesheet" />
    <link href="css/gc.dataviews.cardlayout.css" rel="stylesheet" />
    <!--SCRIPTS-->
    <script src="scripts/jquery-1.8.2.min.js"></script>
    <script src="scripts/zepto.min.js"></script>
    <script src="scripts/gc.dataviews.common.min.js"></script>
    <script src="scripts/gc.dataviews.core.min.js"></script>
    <script src="scripts/gc.dataviews.grid.min.js"></script>
    <script src="scripts/lodash.min.js"></script>
    <script src="scripts/gc.dataviews.cardlayout.min.js"></script>
    <script src="scripts/gc.spread.common.12.2.0.min.js"></script>
  </head>
</html>
  1. Add a style tag within the head tag to apply styling to the interface.
<head>
  <style>
    * {
      -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
    }

    ::-webkit-scrollbar {
      width: 5px;
      height: 5px;
    }

    ::-webkit-scrollbar-thumb {
      background: #e0e0e0;
      border-radius: 5px;
    }

    label {
      font-weight: normal;
      margin: 0;
    }

    .card-layout.gc-grid {
      border: none;
    }

    .card-layout .gc-row {
      text-align: center;
      padding: 3px;
    }

    #grid1 {
      position: absolute;
      left: 220px;
      right: 0;
      height: 100%;
    }

    .demo-container {
      -moz-user-select: none;
      -khtml-user-select: none;
      -webkit-user-select: none;
      -ms-user-select: none;
      user-select: none;
      width: 100%;
      height: 100%;
      position: relative;
    }

    .filter-panel {
      float: left;
      width: 219px;
      height: 100%;
      overflow: auto;
      display: block;
      border: none;
      z-index: auto;
      position: static;
    }

    .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 {
      display: inline-block;
      height: 13px;
      width: 65px;
      overflow: hidden;
      background-image: url('./images/star-ratings.png');
      vertical-align: middle;
    }

    .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 {
      font-size: 13px;
      color: lightgrey;
      margin-bottom: 8px;
    }

    .tv-price {
      color: #b12704;
    }

    .mobile-filter-entry {
      display: none;
    }

    .filter-condition {
      display: inline-block;
      border: 1px solid lightgrey;
      width: 100px;
      height: 25px;
      font-family: -apple-system-font, 'Helvetica Neue', 'Segoe UI', Helvetica, Arial, sans-serif;
      font-size: 16px;
      text-align: center;
      cursor: pointer;
    }

    .slicer {
      margin: 10px 0;
    }

    .slicer-item {
      margin: 2px 0;
      cursor: pointer;
    }

    .hover {
      color: #e47911;
    }

    .filtered {
      background-color: #ffffff;
    }

    .filteredOutByOther {
      color: #a6a8b1;
    }

    .filteredOutBySelf {
      background-color: #ffffff;
    }

    @media only screen and (max-width: 768px) {
      #grid1 {
        position: static;
        height: 90%;
      }

      .filter-panel {
        margin-top: -1px;
        border: 1px solid lightgrey;
        width: 100%;
        overflow: auto;
        height: 90%;
        position: absolute;
        z-index: 1;
        background: white;
        padding: 5px 0 0 10px;
        display: none;
      }

      .mobile-filter-entry {
        height: 25px;
        display: block;
      }
    }
  </style>
</head>
  1. Add a div tag within the body tag to include the DOM element as the container in the page. Then, add a variable definition to instantiate the instance of DataViewsJS.
<body style="margin:0;position:absolute;top:0;bottom:0;left:0;right:0;font-size:14px;">
    <div class="demo-container">
        <div class="mobile-filter-entry">
            <div class="filter-condition"><span style="padding-right:5px;">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="grid1"></div>
    </div>
    <script type="text/javascript">
        var dataView;
        var slicerComponentNS = GC.Spread.Slicers;

        var rowTemplate =
            '<div>' +
            '<div data-column="image"></div>' +
            '<div data-column="description"></div>' +
            '<div data-column="brand"></div>' +
            '<div data-column="price"></div>' +
            '<div data-column="starsIcon"></div>' +
            '</div>';

        var imagePresenter = '<img class="tv-image" src=\{{=it.image}} />';
        var descriptionPresenter = '<a href="#"><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>';
  1. Add a column definition to specify the grid values.
var columns = [
  {
    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',
  },
];
  1. Initialize the code by calling the grid ID from the DIV tag.
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>';

$(document).ready(function () {
  $.getJSON('data/TVData.json', function (data) {
    var layout = new GC.DataViews.CardLayout({
      cardHeight: 300,
      cardWidth: 210,
      rowTemplate: rowTemplate,
    });
    dataView = new GC.DataViews.DataView(document.getElementById('grid'), data, cols, layout);
  });
});
  1. Specify functions for the filtering conditions.
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);