Create A Sortable and Filterable Grid of Items - Shuffle

File Size: 131 KB
Views Total: 34508
Last Update:
Publish Date:
Official Website: Go to website
License: MIT
   
Create A Sortable and Filterable Grid of Items - Shuffle

Shuffle is a responsive jQuery Vanilla JavaScript (ES6) plugin for categorizing your grid of items to make them sortable, searchable and filterable.

With this plugin, your visitors can filter items by groups with CSS transitions.

Great for creating a resonsive & Filterable Portfolio website.

Note that the plugin now works as a Vanilla JavaScript plugin since 4.0.

Features:

  • Responsive and cross-browser.
  • Each item should be able to be in multiple categories.
  • Smooth CSS3 transitions.

Similar Plugins:

How to use it:

1. Install and import the Shuffle.js library.

# NPM
$ npm install shufflejs --save
import Shuffle from 'shufflejs';

2. Or directly include the necessary JavaScript from the dist folder .

<script src="/path/to/dist/shuffle.js"></script>
<!-- or from a CDN -->
<script src="https://cdn.jsdelivr.net/npm/shufflejs/dist/shuffle.min.js"></script>

3. The basic HTML structure to create an image grid. To categorize your grid items, assign group names to each grid item using the data-groups attribute:

<div class="my-shuffle-container">
  <figure class="picture-item" data-groups='["jquery"]' data-date-created="2019-11-26" data-title="jQuery">
    <div class="aspect aspect--16x9">
      <div class="aspect__inner">
        <img src="jQuery.jpg" alt="Image Description" />
      </div>
    </div>
    <figcaption>jQuery</figcaption>
  </figure>
  <figure class="picture-item" data-groups='["jquery"]' data-date-created="2019-11-26" data-title="jQuery">
    <div class="aspect aspect--16x9">
      <div class="aspect__inner">
        <img src="jQuery.jpg" alt="Image Description" />
      </div>
    </div>
    <figcaption>jQuery</figcaption>
  </figure>
  <figure class="picture-item" data-groups='["javascript"]' data-date-created="2019-11-26" data-title="JavaScript">
    <div class="aspect aspect--16x9">
      <div class="aspect__inner">
        <img src="JavaScript.jpg" alt="Image Description" />
      </div>
    </div>
    <figcaption>JavaScript</figcaption>
  </figure>
  <figure class="picture-item" data-groups='["CSS"]' data-date-created="2019-11-26" data-title="CSS">
    <div class="aspect aspect--16x9">
      <div class="aspect__inner">
        <img src="CSS.jpg" alt="Image Description" />
      </div>
    </div>
    <figcaption>CSS</figcaption>
  </figure>
</div>

3. Attach the plugin to the top container and specify the selector of grid items. Done.

var Shuffle = window.Shuffle;
var element = document.querySelector('.my-shuffle-container');
var myGrid = new Shuffle(element, {
    itemSelector: '.picture-item'
});

4. Filter the grid items based on the value defined in the data-groups attribute:

myGrid.filter('javascript');
myGrid.filter(['jquery', 'javascript']);
myGrid.filter(Shuffle.ALL_ITEMS); // reset

// the plugin also supports custom filter function
myGrid.filter(function (element) {
  return element.getAttribute('data-title').length < 10;
});

5. Enable a search field to filter through the grid items.

// Advanced filtering
myGrid.prototype.addSearchFilter = function () {
  document.querySelector('.search-field').addEventListener('keyup', this._handleSearchKeyup.bind(this));
};

// Filter the shuffle instance by items with a title that matches the search input.
myGrid.prototype._handleSearchKeyup = function (evt) {
  var searchText = evt.target.value.toLowerCase();

  this.shuffle.filter(function (element, shuffle) {
    var titleElement = element.querySelector('.picture-item__title');
    var titleText = titleElement.textContent.toLowerCase().trim();

    return titleText.indexOf(searchText) !== -1;
  });
};

6. Resort the grid items.

<select class="sort-options">
  <option value="">Default</option>
  <option value="title">Title</option>
  <option value="date-created">Date Created</option>
</select>
myGrid.prototype.addSorting = function () {
  document.querySelector('.sort-options').addEventListener('change', this._handleSortChange.bind(this));
};

myGrid.prototype._handleSortChange = function (evt) {
  var value = evt.target.value;

  function sortByDate(element) {
    return element.getAttribute('data-created');
  }

  function sortByTitle(element) {
    return element.getAttribute('data-title').toLowerCase();
  }

  var options;
  if (value === 'date-created') {
    options = {
      reverse: true,
      by: sortByDate,
    };
  } else if (value === 'title') {
    options = {
      by: sortByTitle,
    };
  } else {
    options = {};
  }

  this.shuffle.sort(options);
};

7. All possible options to customize the grid layout.

var myGrid = new Shuffle(element, {

    // Initial filter group.
    group: Shuffle.ALL_ITEMS,

    // Transition/animation speed (milliseconds).
    speed: 250,

    // CSS easing function to use.
    easing: 'cubic-bezier(0.4, 0.0, 0.2, 1)',

    // e.g. '.picture-item'.
    itemSelector: '*',

    // Element or selector string. Use an element to determine the size of columns
    // and gutters.
    sizer: null,

    // A static number or function that tells the plugin how wide the gutters
    // between columns are (in pixels).
    gutterWidth: 0,

    // A static number or function that returns a number which tells the plugin
    // how wide the columns are (in pixels).
    columnWidth: 0,

    // If your group is not json, and is comma delimited, you could set delimiter
    // to ','.
    delimiter: null,

    // Useful for percentage based heights when they might not always be exactly
    // the same (in pixels).
    buffer: 0,

    // Reading the width of elements isn't precise enough and can cause columns to
    // jump between values.
    columnThreshold: 0.01,

    // Shuffle can be isInitialized with a sort object. It is the same object
    // given to the sort method.
    initialSort: null,

    // Transition delay offset for each item in milliseconds.
    staggerAmount: 15,

    // Maximum stagger delay in milliseconds.
    staggerAmountMax: 150,

    // Whether to use transforms or absolute positioning.
    useTransforms: true,

    // Affects using an array with filter. e.g. `filter(['one', 'two'])`. With "any",
    // the element passes the test if any of its groups are in the array. With "all",
    // the element only passes if all groups are in the array.
    // Note, this has no effect if you supply a custom filter function.
    filterMode: Shuffle.FilterMode.ANY,

    // Attempt to center grid items in each row.
    isCentered: false,

    // Attempt to align grid items to right.
    isRTL: false,

    // Whether to round pixel values used in translate(x, y). This usually avoids
    // blurriness.
    roundTransforms: true,
    
});

8. API methods.

// Filter items
// Category can be a string, array of strings, or a function
// The sort object is optional and will use the last-used sort object
myGrid.filter(category, sortObject);

// Sort items
myGrid.sort(sortObject);

// Update the layout. Useful for window resize
myGrid.update({ 
  force: true 
});

myGrid.update({ 
  recalculateSizes: false
});

// Update the layout if you don't need the columns and gutters updated
myGrid.layout();

// Add new grid items
// newItems is an array of elements
myGrid.add(newItems);

// Disable
myGrid.disable();

// Enable
myGrid.enable();

// Remove grid item(s)
myGrid.remove();

// Get an item by its element
myGrid.getItemByElement(element);

// destroy the instance
myGrid.destroy()

Changelog:

v6.1.1 (2024-02-23)

  • Bugfixes

v6.1.0 (2022-07-07)

  • The package.json now contains sideEffects: false to improve dead code removal and tree shaking.
  • The package.json now contains an export-map to assist bundlers in choosing the correct file.
  • Bug fixes

v6 (2022-02-15)

  • Remove IE 11 from browsers list. If you need to support IE 11 (sorry), please use v5. Did you know Microsoft 365 apps and services stopped supporting IE 11 in August 2021?
  • Remove matches-selector package and use the native matches (see browser support).
  • Remove deprecated delimeter option (the misspelled one). Use the delimiter option instead.
  • Replace window resize event listener with ResizeObserver (#321). Browser support for it is very good, but if you want to support a browser that doesn't have it, you can manually add a window resize event and call update() within the event callback.
  • Changed the method signature for update().
  • Changed how data attribute are accessed. Previously, Shuffle used element.getAttribute('data-groups'). Now, it uses element.dataset.groups. dataset is very well supported now.
  • Added force option to update method to force shuffle to update even if it's disabled
  • Convert demos to ES6 classes.
  • Move browsers list to .browserslistrc.
  • Add prettier
  • Add BMC button.

v5.4.1 (2021-06-01)

  • Add sortedItems property which is the shuffle items in sorted order. Only visible items are in this array.
  • Fix Chrome DPI bug that was causing column sizes to be calculated incorrectly.

v5.3.0 (2021-03-23)

  • Add isRTL option

v5.2.3 (2019-11-26)

  • Major update
  • Doc updated

v4.0.0 (2016-04-20)

  • Use ES6 export for main file. Add index.js to export the `default` to module.exports. This would allow module bundlers like rollup to use jsnext:main and it'll all be ES6 import/exports

v3.1.1 (2015-03-25)

  • Update

v3.0.4 (2015-02-17)

  • Add NPM support

v3.0.1 (2014-12-30)

  • Add CommonJS support

v3.0.0 (2014-11-27)

  • Add blurred image for caption.

v2.1.2 (2014-06-02)

  • update.

v2.1.0 (2014-04-19)

  • update.

v2.1.0 (2014-04-13)

  • update.

v2.0.8 (2014-04-12)

  • Add more demos.
  • Add AMD support. 

v2.0.6 (2014-03-16)

  • bug fixed.

v2.0.5 (2014-03-09)

  • Add bootstrap 3 demo, fix percentage width issue with Shuffle

This awesome jQuery plugin is developed by Vestride. For more Advanced Usages, please check the demo page or visit the official website.