AngularJS Example:

by sqiudward

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.17/angular-filter.min.js"></script>
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>

<div ng-app="app">
  <h2>Todo</h2>
  <div ng-controller="TodoCtrl">
    
    
    <div class="row" style="margin-top: 15px;">
      <div masonry class="col-sm-4 masonry-brick" style="height:400px; overflow:scroll">

        <div class="qdi-cache-box " ng-repeat="cache in vm.caches">
          <span class="pull-left">
            <i class="fa fa-archive fa-lg ng-binding"></i>
            {{$index + 1}}
          </span>

          <span class="pull-right">
            <i class="btn btn-danger fa fa-lg fa-retweet"></i>
          </span>


          <br>
          <br>

          <div class="text-center">
            <span class="text-center">
              <b>Name</b> <br>
              <small class="ng-binding">{{cache.name}}</small>
            </span>

            <br>
            <br>

            <span class="text-center">
              <b>Model</b> <br>
              <small class="ng-binding">{{cache.model}}</small> (hrs)
            </span>

            <br>
            <br>


          </div>

        
        
        </div>

      </div>
    
  </div>

  </div>
</div>

CSS

/* Latest compiled and minified CSS included as External Resource*/

/* Optional theme */


body {
    margin: 30px;
    width: 1000px;
    height: 200px;
}

.qdi-cache-box {
    background-color: #e8e8e8;
    border-radius: 20px;
    padding: 13px;
    width: 180px;
    height: 168px;
}

.qdi-cache-box:hover {
    transform: translateY(-5px) translateX(-5px);
    background: #e6e6e6;
    box-shadow: 4px 4px 4px #888888;
    z-index: 1050;
}

/*!
 * Bootstrap v3.0.0
 *
 * Copyright 2013 Twitter, Inc
 * Licensed under the Apache License v2.0
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Designed and built with all the love in the world by @mdo and @fat.
 *//*! normalize.css v2.1.0 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{margin:.67em 0;font-size:2em}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{height:0;-moz-box-sizing:content-box;box-sizing:content-box}mark{color:#000;background:#ff0}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid #c0c0c0}legend{padding:0;border:0}button,input,select,textarea{margin:0;font-family:inherit;font-size:100%}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}button[disabled],html...

JavaScript

var app = angular.module("app", ['a8m.chunk-by', 'wu.masonry']);

function TodoCtrl($scope) {
  $scope.vm = {};
    $scope.vm.caches = [{
      name: "Samsung",
      model: "S8"
    },
    {
      name: "Samsung",
      model: "S9"
    },{
      name: "Iphone",
      model: "X"
    },
    {
      name: "Iphone",
      model: "6"
    },
    {
      name: "Samsung",
      model: "S8"
    },
    {
      name: "Samsung",
      model: "S9"
    },{
      name: "Iphone",
      model: "X"
    },
    {
      name: "Iphone",
      model: "6"
    }];
  
}


angular.module('a8m.filter-watcher', [])
  .provider('filterWatcher', function() {

    this.$get = ['$window', '$rootScope', function($window, $rootScope) {

      /**
       * Cache storing
       * @type {Object}
       */
      var $$cache = {};

      /**
       * Scope listeners container
       * scope.$destroy => remove all cache keys
       * bind to current scope.
       * @type {Object}
       */
      var $$listeners = {};

      /**
       * $timeout without triggering the digest cycle
       * @type {function}
       */
      var $$timeout = $window.setTimeout;

      /**
       * @description
       * get `HashKey` string based on the given arguments.
       * @param fName
       * @param args
       * @returns {string}
       */
      function getHashKey(fName, args) {
        function replacerFactory() {
          var cache = [];
          return function(key, val) {
            if(_.isObject(val) && !_.isNull(val)) {
              if (~cache.indexOf(val)) return '[Circular]';
              cache.push(val)
            }
            if($window == val) return '$WINDOW';
            if($window.document == val) return '$DOCUMENT';
            if(angular.isDefined(val)) return '$SCOPE';
            return val;
          }
        }
        return [fName, JSON.stringify(args, replacerFactory())]
          .join('#')
          .replace(/"/g,'');
      }

      /**
       * @description
       * fir on...