In this post I will share how can be implemented Isotope sorting and combine it with a filter functionality in a real case.
But first, for those that doesn’t know, Isotope is a jQuery plugin that in resume, have the following features:
- Layout modes: Intelligent, dynamic layouts that can’t be achieved with CSS alone.
- Filtering: Hide and reveal item elements easily with jQuery selectors.
- Sorting: Re-order item elements with sorting. Sorting data can be extracted from just about anything.
- Interoperability: features can be utilized together for a cohesive experience.
- Progressive enhancement: Isotope’s animation engine takes advantage of the best browser features when available — CSS transitions and transforms, GPU acceleration — but will also fall back to JavaScript animation for lesser browsers.
Requirement (simplified):
Be able to re-order a set of items based on a selected category and at the same time highlight at the top of the list (filtering) the items that matched that category.
Result:
In our new website our team section display a grid with thumbnails of the team members of the company and in the right side of the page is showing list of fields (categories) of expertise that the user can select to sorting and filter the thumbnails. In order to create that functionality, we decided to use Isotope, specifically the sorting capability and we added a modification to create a kind of filter:
By default all the thumbnails are sorted by the field name every time the page is displayed:
The Isotope JavaScript code looks as follow:
itemSelector: '.team-member-grid', getSortData : { // ... name: function($elem) { return $elem.find('.name').text(); } }
Note: getSorData is used by Isotope to create all the sorts that the user can applied to a set of items. getSorData accepts an object, whose values are the functions to extract the data. Each function receives one argument, which represents a jQuery object for each item element. With that argument, the function needs to return the data point.
To sort the items by name I diced to use the div that contains the name of the team member for this purpose and the HTML looks as follow:
<div class="widget team"> <div class="team-member-grid element"> <!-- more code here...--> <div class="team-member-title name">Alex Arriaga</div> <!-- more code here...--></div> <div class="team-member-grid element"> <!-- more code here...--> <div class="team-member-title name">Alfonso Ramos</div> <!-- mode code here...--></div> <div class="team-member-grid element"> <!-- more code here...--> <div class="team-member-title name">Ben Shoemate</div> <!-- mode code here...--></div>
At this point, this is a default implementation of Isotope sorting, but now, if you click in one of the fields of expertise (right side of the page), you will see that the items that match that category are displayed (ordered by name) at the top of the list and the rest of the items at the bottom with a opacity: In order to achieve that, using Isotope, I needed that each of the items had a flag for each of the fields of expertise, why?, because Isotope requires that all the elements that are going to be sorted have the attribute/css class name that will be used for sorting and in our scenario a team member could have more than one field of expertise. So, I used as a flag an integer value of 1 if “is in that field of expertise” and 2 for “is not in that field of expertise”. With that little trick I forced Isotope to move at the top of the Grid all the items that matched that field of expertise since all that items will have a value of 1 for that attribute, and at the same time Isotope will move at the bottom the rest of the items, since have a value of 2, and with that trick I covered the filter requirement.
Now my JavaScript code looks as follow:
itemSelector: '.team-member-grid', getSortData: { manager: function($elem) { return parseInt($elem.attr('data-category-manager'), 10); }, solarchitect: function($elem) { return parseInt($elem.attr('data-category-solarchitect'), 10); }, analysis: function($elem) { return parseInt($elem.attr('data-category-analysis'), 10); }, qualityassu: function($elem) { return parseInt($elem.attr('data-category-qualityassu'), 10); }, //... name: function($elem) { return $elem.find('.name').text(); } }
And now, each of the items needs to have a data attribute for each of that filters I have created:
<div class="widget team"> <div class="team-member-grid element isotope-item" data-category-solarchitect="2" data-category-qualityassu="2" data-category-analysis="2" data-category-manager="2"> <div class="team-member-title name">Alex Arriaga</div> <!-- more code here...--></div> <div class="team-member-grid element isotope-item" data-category-solarchitect="2" data-category-qualityassu="1" data-category-analysis="2" data-category-manager="2"> <!-- more code here...--> <div class="team-member-title name">Alfonso Ramos</div> <!-- mode code here...--></div> <div class="team-member-grid element isotope-item" data-category-solarchitect="2" data-category-qualityassu="2" data-category-analysis="2" data-category-manager="2"> <!-- more code here...--> <div class="team-member-title name">Ben Shoemate</div> <!-- mode code here...--></div>