Building a List/Grid View Switcher with jQuery

A fairly common web interface feature is the dynamic view switcher. On product pages or blog archives you’ll sometimes find buttons to change the layout from display lists to smaller grids. In this tutorial I’ve built a simpler example using basic CSS and some jQuery commands.

I’ll be using interface elements from the Zephirro E-Commerce UI Set which include buttons and thumbnail photos. Feel free to demo the code yourself and try out a similar experience on your own website. This is a tricky effect to nail down, but when done properly your users will love the unique experience.

Building a List/Grid View Switcher with jQuery

Live DemoDownload Source Code

Coding the Basic HTML

The main page isn’t very complicated but does contain a lot of repetitive code. Towards the top I’ve included two links with the IDs listview and gridview.

<span class="list-style-buttons">
	<a href="#" id="gridview" class="switcher"><img src="images/grid-view.png" alt="Grid"></a>
	<a href="#" id="listview" class="switcher active"><img src="images/list-view-active.png" alt="List"></a>
</span>

We’ll bind a click event handler onto these two links later on. Then we can determine which display block the user clicks and how we need to render the page. Afterwards I’ve setup an unordered list with each list item containing a different product to display. The list item element is used as a block which contains more detailed elements.

<!-- row 1 -->
<li class="clearfix">
	<section class="left">
		<img src="images/products/list-default-thumb.png" alt="default thumb" class="thumb">
		<h3>Product Name</h3>
		<span class="meta">Product ID: 543J423</span>
	</section>

	<section class="right">
		<span class="price">$45.00</span>
		<span class="darkview">
		<a href="javascript:void(0);" class="firstbtn"><img src="images/read-more-btn.png" alt="Read More..."></a>
		<a href="javascript:void(0);"><img src="images/add-to-cart-btn.png" alt="Add to Cart"></a>
		</span>
	</section>
</li>

This example only includes the first row but you can copy/paste to build more. In my demo I’ve used 9 different product rows containing the left and right columns.

Just to point out I’ve wrapped the product buttons in a span with the class .darkview. This is used in the grid layout to hide the big round buttons until you hover over a product display. But in the default list view it doesn’t affect anything. Notice, however, that it’s very important we setup the HTML properly from the start.

Looking at CSS Styles

My project outline is to adapt each list item based on the UL’s current class. Using jQuery we can change it between list and grid, then apply styles for each. The list is setup first by default and I’ve kept all the related selectors in the same block of code.

/** list view **/
ul.list { list-style: none; width: 100%; }
ul.list li { display: block; background: #c9d0d1; padding: 10px 15px; }

ul.list li.alt { background: #d7dfe0; }

ul.list li section.left { display: block; float: left; width: 350px; position: relative; padding-left: 20px; }
ul.list li section.right { display: block; float: right; margin-right: 10px; width: 250px; text-align: right; }

ul.list li section.left img.thumb { float: left; margin-right: 10px; }
ul.list li section.left img.featured-banner { position: absolute; left: -18px; top: 35px; }

ul.list li section.left h3 { font-family: "Trebuchet MS", Arial, sans-serif; font-weight: bold; text-transform: uppercase; color: #707375; font-size: 1.4em; line-height: 1.6em; }
ul.list li section.left span.meta { color: #93989b; font-weight: normal; font-size: 1.1em; }

ul.list li section.right span.price { font-weight: bold; display: block; margin-bottom: 15px; color: #ad3939; font-size: 1.6em; text-align: right; }

ul.list li section.right a.firstbtn { margin-right: 7px; }

Now the grid view is very similar with the exception of our dark hover menu. The title, product ID, and price elements are styled very similar to the original list design. I’m also switching out thumbnail images to display larger grid blocks.

A particularly interesting bit of code is the darkview class for our grid layout. This span is originally set to 0 opacity and transitions into full display. For some people this layout may be annoying or intimidating – but there’s always a workaround to adapt this functionality for your own website.

/** grid view **/
ul.grid { list-style: none; margin: 0 auto; padding-left: 25px; }
ul.grid li { position: relative; display: block; float: left; width: 220px; height: 200px; border-right: 1px solid #b6bdbe; padding: 5px 22px; margin-bottom: 20px; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; }
ul.grid li.third { border: 0; }

ul.grid li section.left { position: relative; }
ul.grid li section.right { /* nothing */ }

ul.grid li section.left img.featured-banner { position: absolute; top: 0; }

ul.grid li section.left h3 { font-family: "Trebuchet MS", Arial, sans-serif; font-weight: bold; text-transform: uppercase; color: #707375; font-size: 1.4em; line-height: 1.5em; }
ul.grid li section.left span.meta { display: block; color: #93989b; font-weight: normal; font-size: 1.1em; margin-bottom: 7px; }

ul.grid li section.right span.price { font-weight: bold; display: block; margin-bottom: 5px; color: #ad3939; font-size: 1.75em; }

ul.grid li section.right span.darkview {
opacity: 0;
margin: 0;
position: absolute;
top: 0;
left: 0;
width: 190px;
height: 200px;
margin: 0 15px;
border-radius: 6px;
background: rgba(40, 45, 55, 0.75);
overflow: hidden;
text-align: center;
padding-top: 35px;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
transition: opacity 0.2s linear 0s;
-webkit-transition: opacity 0.2s linear 0s;
-moz-transition: opacity 0.25s linear 0s;
-o-transition: opacity 0.25s linear 0s;
}
ul.grid li:hover section.right span.darkview { opacity: 1; }

ul.grid li section.right span.darkview a.firstbtn { display: block; margin-bottom: 10px; }

jQuery Switch Effects

I am including the latest jQuery release directly from Google’s cloud hosting for developers. I then created a new script.js file and we can write all our main function code inside. Let’s look at the opening bind method:

$(document).ready(function(){

	$("a.switcher").bind("click", function(e){
		e.preventDefault();

Once the document is loaded jQuery will bind a click event handler to any anchor links with the class .switcher. We want to disable linking to anything and prevent the default browser action. Then afterwards I go on to setup a few variables which will save us time writing out selectors.

var theid = $(this).attr("id");
var theproducts = $("ul#products");
var classNames = $(this).attr('class').split(' ');

var gridthumb = "images/products/grid-default-thumb.png";
var listthumb = "images/products/list-default-thumb.png";

We need theid in order to determine which view style we’re switching over to display. Also the two thumbnail image URLs help to update the grid/list view later on.

Updating Products List Display

The final portion of my code uses a couple basic if/else clauses. First we check if the button clicked has an active class. This would mean the user is already viewing the desired layout and we don’t need to perform anything. Otherwise we need to check the button ID and switchup the layout accordingly.

if($(this).hasClass("active")) {
	// if currently clicked button has the active class
	// then we do nothing!
	return false;
} else {
	// otherwise we are clicking on the inactive button
	// and in the process of switching views!

Inside the else clause I’m performing two more logic checks. First we see if the user has clicked gridview and update the current list objects to display in a grid-style. Otherwise we switch back from the grids into a list format.

The lines of code go through a few different functions. First we update the currently active button and change the images to highlight our new display. Then we remove the previous grid/list class and apply our updated selection, along with changing all of the thumbnail images.

if(theid == "gridview") {
	$(this).addClass("active");
	$("#listview").removeClass("active");

	$("#listview").children("img").attr("src","images/list-view.png");

	var theimg = $(this).children("img");
	theimg.attr("src","images/grid-view-active.png");

	// remove the list class and change to grid
	theproducts.removeClass("list");
	theproducts.addClass("grid");

	// update all thumbnails to larger size
	$("img.thumb").attr("src",gridthumb);
}

else if(theid == "listview") {
	$(this).addClass("active");
	$("#gridview").removeClass("active");

	$("#gridview").children("img").attr("src","images/grid-view.png");

	var theimg = $(this).children("img");
	theimg.attr("src","images/list-view-active.png");

	// remove the grid view and change to list
	theproducts.removeClass("grid")
	theproducts.addClass("list");
	// update all thumbnails to smaller size
	$("img.thumb").attr("src",listthumb);
}

It does seem confusing without context but all the code is fairly straightforward. Much of the DOM manipulation has to do with replacing classes and image src attributes. But if you wanted to get fancy it’s a simple process to further animate fade in/out effects on the layout change. Yet for a basic switcher like this you don’t always need animations.

Building a List/Grid View Switcher with jQuery

Live DemoDownload Source Code

Conclusion

This tutorial should give you a strong introduction to manipulating your page layouts with jQuery. Even the simple action of mixing up classes & IDs can boldly enhance the user experience. And developing over the jQuery library makes coding JavaScript easier than ever before! Be sure to let us know your thoughts on the tutorial in our post discussion area below.

About the Author:

Jake is a freelance writer and frontend web developer. He can be found writing in many blogs on topics such as mobile interfaces, freelancing, jQuery, and Objective-C. Check out his other articles throughout Google and follow his tweets @jakerocheleau. Jake’s Google+ profile.

Published June 11th, 2012 by

Looking for hosting? WPEngine offers secure managed WordPress hosting. You’ll get expert WordPress support, automatic backups, and caching for fast page loads. Visit WPEngine.

Join Our Newsletter!

Subscribe to our weekly newsletter chalked full of useful tips, techniques, and design goodies. We have 20,000+ loyal readers and counting! We’ll even send you a free e-book (Freelance Designer’s Guide to Multiple Income Streams) and a $10 discount on our most popular product the Freelance Starter Kit.

21 Responses

Comments are now closed on this post.

  • Shyam, June 11, 2012

    Great stuff. The css is so flexible. I will surely use it for my shopping cart for my website for my new company for Website designing in qatar.

  • MJ Meyer, June 11, 2012

    Hi Jake,
    Nice post! I might just use this.

    I know tutorials aren’t meant to cover everything, but I do think there’s a small part that needs clarifying.

    In a real world scenario, people have different images for different products. And not the same “default” image for all the products. So your jQuery covering the insertion of the different URL’s depending on grid or list view only works if you have 1 product.

    To make this manageable from a real world “client adding products via CMS” perspective, you should either just resize the images via CSS as the size difference is minimal, or your jQuery should rather change the folder structure of the URL depending on the view type leaving your client free to select one image.

    So, your client has different products:
    /images/list/product-1.png
    /images/list/product-2.png
    /images/list/product-3.png

    And your jQuery changes it back and forth depending on what view your on, like:
    /images/grid/product-1.png
    /images/grid/product-2.png
    /images/grid/product-3.png

    I hope what I’m saying makes sense. But all the same, it’s still a good tut!

    Cheers,
    MJ

  • Scott, June 11, 2012

    Very nice, I built something similar for a shopping site last year. I agree with the post above regarding images, mines turned into a bit of a pain due to having to use different image sizes for each view. Just out of convenience I would have made the buttons spans instead of anchors too. None the less its good to see real world situations being demonstrated, well done!

  • Joe Elliott, June 13, 2012

    Hi Jake,

    This is a great tutorial, time to learn these tips and get some practice. It gives more user control, which is always a good thing, and I would think it would definitely help the users experience…

    Thanks
    Joe

  • Prince, June 14, 2012

    Hi Jake,

    I’ve tried your tutorial and it works greats. I agree with many of the comments posted earlier because in a real world you’d use different images. If you could work out a way to use different images to switching the views it’ll greatly help a lot of us who are really finding your tutorial a great masterpiece that can be adapted not just for shopping carts, but any website which uses images.

    thanks once more for this great tutorial

  • D Steve, June 16, 2012

    Very nicely done tutorial , it would be great if this tutorial is taken to next step to show how to handle pagination in list/grid through jquery.

  • Vidhya, June 25, 2012

    HI,

    I used your code.. it is working fine… In IE is not working… Pls reply me…

    With Regards,
    Vidhya.C

    • Steven Snell, June 25, 2012

      Hi Vidhya,
      What specifically is not working in IE and what version of IE? The demo works in IE9 and the download includes the same codes as the demo.

  • TomyToan, August 2, 2012

    Hi! I use IE8, It works fine in IE9 but IE8, It not work, I tested on demo

  • Jermaine, August 9, 2012

    Thank you so much for this tut its going to come in handy for an eCommerce theme im building.

  • jac, August 23, 2012

    Hello,

    I tried this but not working in IE 8 .. :(

  • john, August 25, 2012

    thanks for sharing this script it’s brilliant, take a look at my implementation on my website.

    just need to add a cookie or something so it remembers the users selection after page load, at the minute it reverts back to list on each load.

    any idea on the? will post back if i find a solution in the meantime.

  • josef, August 30, 2012

    Hi,,!Very Nice Tutorial..
    .But Not Working IE8,9…
    & When I change grid View Not Showing My products Images as dynamically….
    How to implement dynamic images in your tutorial,,,please reply me as soon as possible…..

    Great Job..Keep It Up!!!!

  • Liza-Mari, September 10, 2012

    just change the following:

    var gridthumb = “images/products/grid/”;
    var listthumb = “images/products/list/”;

    to:
    var gridimg = “src:images/products/grid/”;
    var listimg = “src:images/products/list/”;

    where the image is located.

  • Akatsukininja, September 14, 2012

    Is there a way to change the hover to a click event? I’ve tried replacing it with other mouse event keywords but none of them seem to work.

  • Hoopoe, November 13, 2012

    Hi!
    Very good tutorial.
    Is it possible to make a grid-list as default on start?

  • pRaveen, December 1, 2012

    how to remove the list view from this? and make grid view default only??

  • Bongani, February 20, 2013

    Well written tutorial, thanks again.

  • j smith, May 14, 2013

    Thanks for this tutorial. I’ve been curious on how this is done for a while. I’m currently using this on my website. once again thanks.

  • P nielsen, July 17, 2013

    Great Tutorial and a cool effect.
    But the Multi image problem.
    I added this to the code.
    Don’t know if it is the best way to do it, but I worked :)
    if (theid == “gridview”) {
    $(“img.thumb”).each(function (index) {
    var ImgSrc = $(this).attr(“src”);
    $(this).attr(“src”, ImgSrc.replace(“&width=81&height=81″, “&width=130&height=130″));
    });
    }
    else if(theid == “listview”) {
    $(“img.thumb”).each(function (index) {
    var ImgSrc = $(this).attr(“src”);
    $(this).attr(“src”, ImgSrc.replace(“&width=130&height=130″, “&width=81&height=81″));
    });
    }

  • Brad P., August 12, 2013

    This is exactly what I’ve been looking for, thank you for sharing this!