Fireclay Tile, one of our clients, is the leading U.S. recycled ceramic and 100% recycled glass tile manufacturer. They make beautiful products and offer a wide assortment of customization and purchase options. To help showcase this, they have a Gallery section of the website that shows their products being used in different rooms, using different materials, styles, patterns, and colors.
We were tasked with a refresh of this section of the site with the main emphasis being on speed and fast load times. This section would essentially be a single page app within the larger website. They wanted users to be able to apply the available filters (rooms, materials, styles, patterns, and colors) and have the appropriate content load in without page refreshes. They also wanted the content changes to correspond to a change in push state so the user could go back and forth between the content as if the page was reloading.
- No page reloads between filter clicks
- Push state manipulation
- Filters within the same family should replace the current filter
- Filters outside a given family should be appended as an additional filter
The question I usually ask when faced with a task is, “what libraries exist out there already, which can save me time to accomplish this task?”. There are no shortage of frameworks that could have been used for this (e.g. Backbone, Angular, or React) but the project currently doesn’t use any of those frameworks and it didn’t make sense at the time to bring in a framework for just this one section.
I had previously heard of History.js and it seemed like a great option given its extensive API and browser support. In addition, given the need to swap out family filters, URI.js seemed like a great fit to help break out the URL segments and deal with the logic.
This way I could access the Gallery object from the console and give myself an API in the console to make it easier to test and debug. I also would make sure that my onClick listeners would not be doing the heavy lifting but rather I had functions that would handle all the logic. This would help make the app more testable and allow me to mimic clicks from the console instead of actually clicking around. For example:
This is the code that controls the actual clicking of a filter action. We’re first looping through all the pushLinks, adding an onClick listener to each, grabbing the element, and then passing it to functions that handle the rest of the logic. I’m a firm believer in handling logic in purpose-driven functions and not listeners. This allowed me to write tests using QUnit (which could be a blog post onto itself!) by passing elements into the functions of the Gallery object. Because the Gallery object is an IIFE I could just call
Another tactic that helped a great deal in following what was going on in the logic was adding in debug statements that only show in non-production environments:
The debug.status is set automatically based on the environment, so all those debug statements won’t show on production but only on my local and staging environment. That logic looks like this
This allows me to also turn the debug off in case debug statements are crowding the console.
You can view the final product here: https://www.fireclaytile.com/gallery! This was a very fun mini single page app to build and I learned a ton of things along the way.