WEBサイト制作の勉強

WEBサイト制作の勉強の為の解説ブログです。

フェリカテクニカルアカデミー

フィルタリングやソートが出来る高機能プラグイン「muuri.js」

フィルター機能、ソート機能が付いて可変グリッドレイアウトも実現出来さらにレスポンシブにも対応した、無料で商用利用も可能な  Javascriptプラグインの「muuri.js」



haltu.github.io



付いている機能

  • フィルター機能
  • ソート機能
  • 検索機能
  • Masonryレイアウト
  • ドラッグ機能

など、非常に高機能です。


digipress.info




See the Pen
Muuri.js
by yachin29 (@yachin29)
on CodePen.



index.html
<body>
<h1>Grid Layout by Muuri.js</h1>

<section class="grid-wrapper">
<div class="filter-controls">
<div class="control">Search
<input class="search-field form-control" type="text" name="search" placeholder="Enter the fruit name">
</div>
<div class="control">Filter
<select class="filter-field form-control">
<option value="">None</option>
<option value="red">Red</option>
<option value="blue">Blue</option>
<option value="green">Green</option>
</select>
</div>
<div class="control">Sort
<select class="sort-field form-control">
<option value="order">None</option>
<option value="title">Order by number</option>
<option value="color">Order by color name</option>
</select>
</div>
</div><!-- filter-controls -->

<div class="grid">
<div class="item blue w2 h2" data-color="blue" data-title="01">
<div class="item-content">
<!-- Safe zone, enter your custom markup -->
<div class="custom-content">
 Item 1
</div>
</div>
</div><!-- item -->

<div class="item red w2" data-color="red" data-color="blue" data-title="05">
<div class="item-content">
<div class="custom-content">
Item 5
</div>
</div>
</div><!-- item -->

<div class="item green w2" data-color="green" data-color="blue" data-title="03">
<div class="item-content">
<div class="custom-content">
Item 3
</div>
</div>
</div><!-- item -->

<div class="item red w2 h2" data-color="red" data-color="blue" data-title="04">
<div class="item-content">
<div class="custom-content">
Item 4
</div>
</div>
</div><!-- item -->

<div class="item red" data-color="red" data-color="blue" data-title="02">
<div class="item-content">
<div class="custom-content">
Item 2
</div>
</div>
</div><!-- item -->

<div class="item blue" data-color="blue" data-color="blue" data-title="06">
<div class="item-content">
<div class="custom-content">
Item 6
</div>
</div>
</div><!-- item -->

<div class="item red h2" data-color="red" data-color="blue" data-title="12">
<div class="item-content">
<div class="custom-content">
Item 12
</div>
</div>
</div><!-- item -->

<div class="item green h2" data-color="green" data-color="blue" data-title="08">
<div class="item-content">
<div class="custom-content">
Item 8
</div>
</div>
</div><!-- item -->

<div class="item green w2" data-color="green" data-color="blue" data-title="11">
<div class="item-content">
<div class="custom-content">
Item 11
</div>
</div>
</div><!-- item -->

<div class="item blue w2" data-color="blue" data-color="blue" data-title="10">
<div class="item-content">
<div class="custom-content">
Item 10
</div>
</div>
</div><!-- item -->

<div class="item green" data-color="green" data-color="blue" data-title="07">
<div class="item-content">
<div class="custom-content">
Item 7
</div>
</div>
</div><!-- item -->

<div class="item red" data-color="red" data-color="blue" data-title="09">
<div class="item-content">
<div class="custom-content">
Item 9
</div>
</div>
</div><!-- item -->


</div>
</select>


<script src="https://cdnjs.cloudflare.com/ajax/libs/web-animations/2.3.1/web-animations.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="js/muuri.js"></script>
<script src="js/script.js"></script>
</body>
muuri.scss
// ******************************
// Normalize (ignore me!)
// ******************************

$bg_color:#fff;
$font_color:#333;
$link_color:#999;
$link_hover_color:#777;

* {
  &:before,
  &:after{
    box-sizing:border-box;
    padding:0;
    margin:0;
  }
}
body{
  background-color:$bg_color;
  color: $font_color;
  text-align: center;
  a, a:visited{
    color: $link_color;
    text-decoration:none;
  }
  a:hover{
    color: $link_hover_color;
  }
}
// ******************************
// End of Normalize
// ******************************

h1{
  font-size:36px;
  margin:40px auto;
}
.filter-controls{
  text-align:center;
  margin-bottom:30px;
  .control{
    display:inline-block;
    width:240px;
    margin:0 10px;
    *{
      box-sizing:border-box;
    }
    .form-control{
      width:100%;
      height:40px;
      padding:0 20px;
      border:2px solid #ccc;
      border-radius:3px;
      background-color:#fff;
      color:#666;
      font-size:16px;
      cursor:pointer;
      -webkit-appearance:none;
      appearance:none;
      &:focus{
        outline:0;
        border-color:#0CAAF5;
      }
    }
  }  
}

.grid {
  position: relative;
  max-width:80%;
  margin:0 auto;
}
.item {
  position: absolute;
  width:200px;
  height:200px;
  margin: 5px;
  z-index: 1;
  transition:transform .6s ease;
  cursor:move;
  &.blue{
    .custom-content{
      border-color:#0CAAF5;
      color:#0CAAF5;
    }
  }
  &.red{
    .custom-content{
      border-color:#F54487;
      color:#F54487;
    }
  }
  &.green{
    .custom-content{
      border-color:#00DE73;
      color:#00DE73;
    }
  }
  &.w2{
    width:410px;
  }
  &.h2{
    height:410px;
  }
}
.item-content {
  position: relative;
  width: 100%;
  height: 100%;
  display:table;
}
.custom-content{
  display:table-cell;
  vertical-align:middle;
  text-align: center;
  background: #fff;
  color: #666;
  border:2px solid;
  border-radius:3px;
}

// If use dragging
.item.muuri-item-dragging {
  z-index: 3;
  transition:none;
}
.item.muuri-item-releasing {
  z-index: 2;
}

@media ( max-width : 877px ){
  .item{
    width:calc(33.33% - 11px);
    height:calc(33.33vw - 11px);
    &.w2{
      width:calc(33.33% - 11px);
    }
    &.h2{
      height:calc(33.33vw - 11px);
    }
  }
}
@media ( max-width : 640px ){
  .item{
    width:calc(50% - 10px);
    height:calc(50vw - 10px);
    &.w2{
      width:calc(50% - 10px);
    }
    &.h2{
      height:calc(50vw - 10px);
    }
  }
}
CDN
<script src="https://cdn.jsdelivr.net/npm/muuri@0.9.3/dist/muuri.min.js"></script>
muuri.js
document.addEventListener('DOMContentLoaded', function () {
  var grid = null,
      wrapper = document.querySelector('.grid-wrapper'),
      searchField = wrapper.querySelector('.search-field'),
      filterField = wrapper.querySelector('.filter-field'),
      sortField = wrapper.querySelector('.sort-field'),
      gridElem = wrapper.querySelector('.grid'),
      searchAttr = 'data-title',
      filterAttr = 'data-color',
      searchFieldValue,
      filterFieldValue,
      sortFieldValue,
      dragOrder = [];

  // Init the grid layout
  grid = new Muuri(gridElem, {
    dragEnabled: true
  });
  
  // Set inital search query, active filter, active sort value and active layout.
  searchFieldValue = searchField.value.toLowerCase();
  filterFieldValue = filterField.value;
  sortFieldValue = sortField.value;

  // Search field event binding
  searchField.addEventListener('keyup', function () {
    var newSearch = searchField.value.toLowerCase();
    if (searchFieldValue !== newSearch) {
      searchFieldValue = newSearch;
      filter();
    }
  });

  // Filter field event binding
  filterField.addEventListener('change', filter);
  
  // Sort field event binding
  sortField.addEventListener('change', sort);

  // Filtering
  function filter() {
    filterFieldValue = filterField.value;
    grid.filter(function (item) {
      var element = item.getElement(),
          isSearchMatch = !searchFieldValue ? true : (element.getAttribute(searchAttr) || '').toLowerCase().indexOf(searchFieldValue) > -1,
          isFilterMatch = !filterFieldValue ? true : (element.getAttribute(filterAttr) || '') === filterFieldValue;
      return isSearchMatch && isFilterMatch;
    });
  }
  
  // Sorting
  function sort() {
    // Do nothing if sort value did not change.
    var currentSort = sortField.value;
    if (sortFieldValue === currentSort) {
      return;
    }

    // If we are changing from "order" sorting to something else
    // let's store the drag order.
    if (sortFieldValue === 'order') {
      dragOrder = grid.getItems();
    }

    // Sort the items.
    grid.sort(
      currentSort === 'title' ? compareItemTitle :
      currentSort === 'color' ? compareItemColor :
      dragOrder
    );
    sortFieldValue = currentSort;
  }
  
  // Compare data-title
  function compareItemTitle(a, b) {
    var aVal = a.getElement().getAttribute(searchAttr) || '';
    var bVal = b.getElement().getAttribute(searchAttr) || '';
    return aVal < bVal ? -1 : aVal > bVal ? 1 : 0;

  }

  // Compare data-color
  function compareItemColor(a, b) {
    var aVal = a.getElement().getAttribute(filterAttr) || '';
    var bVal = b.getElement().getAttribute(filterAttr) || '';
    return aVal < bVal ? -1 : aVal > bVal ? 1 : compareItemTitle(a, b);
  }
});