The ability to set and read cookies is a very useful feature of many programming languages. Fortunately, JavaScript has this functionality. Klaus Hartl released a cookie plugin last year for jQuery. What I particularly like about this plugin is the simple syntax - synonymous with jQuery. Traditionally, one would create a cookie and set the value of a cookie using standard JavaScript as follows:
document.cookie = 'name=value; expires=Thu, 2 Aug 2008 20:00:00 UTC; path=/'
You can read more about using standard JavaScript to set and read cookies over at Quirksmode. We can use jQuery with Klaus Hartl’s cookie plugin to streamline the process of creating and reading cookies. Furthermore, the plugin simplifies the syntax used.
Before we get started on designing a collapsible layout, I’m going to introduce the syntax for Klaus Hartl’s Cookie plugin:
// Get the value of a cookie: $.cookie('sampleCookie'); // Create (or update) the value of a cookie: $.cookie('sampleCookie', 'cookieValue'); //Create (or update) the value of a cookie to expire in 2 days: $.cookie('sampleCookie', 'cookieValue', { expires: 2 }); // Delete a cookie: $.cookie('sampleCookie', null);
Please note that in the examples above, ’sampleCookie’ is the name of a cookie and ‘cookieValue’ is the value assigned to that cookie.
Collapsible Layout
I’m going to demonstrate how to use cookies with jQuery by designing a simple collapsible layout. The page layout will comprise of 2 columns. 2-column structures are common amongst many websites. The left column typically contains site navigation whilst the right column houses the page content. Allowing users to colapse entire columns is probably not beneficial in most cases. It would be more beneficial to allow users to collapse and subsequently expand (often referred to as toggling) individual sections within columns (e.g. navigation sections, news sections etc.). However, to keep this article short and simple, we’ll work with entire columns.
Firstly, we’ll need a 2-column page layout to work with. We’ll allow users to collapse and expand both the left and right columns. In order to add this functionality, we will be utilizing jQuery’s CSS manipulation features:
// LEFT COLUMN: // When the collapse button is clicked: $('.collapseLeft').click(function() { $('.collapseLeft').css("display","none"); $('.expandLeft').css("display","block"); $('#leftCol').css("height","20px"); }); // When the expand button is clicked: $('.expandLeft').click(function() { $('.expandLeft').css("display","none"); $('.collapseLeft').css("display","block"); $('#leftCol').css("height","500px"); }); // RIGHT COLUMN: // When the collapse button is clicked: $('.collapseRight').click(function() { $('.collapseRight').css("display","none"); $('.expandRight').css("display","block"); $('#rightCol').css("height","20px"); }); // When the expand button is clicked: $('.expandRight').click(function() { $('.expandRight').css("display","none"); $('.collapseRight').css("display","block"); $('#rightCol').css("height","500px"); }); });
This is really some very simple code. Let’s take a detailed look. We’ll deal with the left column first. In the left column, there will be 2 possible buttons. One button will expand the column. The other button will collapse the column. However, if the left column is already expanded, there is no need to display the expand button. The same principal can be applied to the collapse button.
I have assigned a collapse button for the left column the class: ‘ collapseLeft’. When this button is clicked, we want 3 actions to occur. Firstly, we want to hide the collapse button. We can do this by manipulating the CSS as follows:
$('.collapseLeft').css("display","none");
We now want to give the user the option to expand the column. We do this by displaying the expand button. I have given the expand button for the left column the class: ‘expandLeft’. Initially, we want to hide the expand button. This can be done using plain CSS (i.e. display: none;). To now display this button, we need to manipulate the CSS:
$('.expandLeft').css("display","block");
Finally, we want to collapse the left column. Since I have positioned the buttons (using CSS) ‘absolutely’ at the top of left column, I don’t want to completely hide the left column. Instead, I’ll manipulate the CSS, changing the height of the left column to leave just enough room to display the expand button:
$('#rightCol').css("height","20px");
You should now be able to follow through the next 3 blocks of code and understand what each line does. You can see that for the right column expand and collapse buttons, I have used the classes: ‘collapseRight’ and ‘expandRight’. Obviously, instead of collapsing or expanding the left column, these buttons will collapse or expand the right column.
I have designed a quick demonstration page. We have not yet used cookies to remember which columns are expanded or collapsed. Therefore, when you collapse a column and refresh the page’, the column will return to its default state (i.e. fully expanded). Try it for your self!
Using Cookies
In most cases, this functionality added thus far is pretty useless. What we really want is for the site to remember each user’s preferences. To do this, we will use the jQuery cookie plugin.
$(document).ready(function() { // LEFT COLUMN: // When the collapse button is clicked: $('.collapseLeft').click(function() { $('.collapseLeft').css("display","none"); $('.expandLeft').css("display","block"); $('#leftCol').css("height","20px"); $.cookie('leftCol', 'collapsed'); }); // When the expand button is clicked: $('.expandLeft').click(function() { $('.expandLeft').css("display","none"); $('.collapseLeft').css("display","block"); $('#leftCol').css("height","500px"); $.cookie('leftCol', 'expanded'); }); // RIGHT COLUMN: // When the collapse button is clicked: $('.collapseRight').click(function() { $('.collapseRight').css("display","none"); $('.expandRight').css("display","block"); $('#rightCol').css("height","20px"); $.cookie('rightCol', 'collapsed'); }); // When the expand button is clicked: $('.expandRight').click(function() { $('.expandRight').css("display","none"); $('.collapseRight').css("display","block"); $('#rightCol').css("height","500px"); $.cookie('rightCol', 'expanded'); }); // COOKIES // Left column state var leftCol = $.cookie('leftCol'); // Right column state var rightCol = $.cookie('rightCol'); // Set the user's selection for the left column if (leftCol == 'collapsed') { $('.collapseLeft').css("display","none"); $('.expandLeft').css("display","block"); $('#leftCol').css("height","20px"); }; // Set the user's selection for the right column if (rightCol == 'collapsed') { $('.collapseRight').css("display","none"); $('.expandRight').css("display","block"); $('#rightCol').css("height","20px"); }; });
Let’s walk through the new code. In order to remember the user’s selection (i.e. which columns are collapsed or expanded), we must create a cookie for both the right and left column. The 1st line of code added creates (or updates) a cookie named ‘leftCol’. When the collapse button for the left column is clicked, we want to set the value of this cookie to ‘collapsed’:
$.cookie('leftCol', 'collapsed');
When the expand button for the left column is clicked, we want to update the value of this cookie to ‘expanded’:
$.cookie('leftCol', 'expanded');
We do the same for the right column. However, this time the cookie is named ‘rightCol’:
$.cookie('rightCol', 'collapsed'); $.cookie('rightCol', 'expanded');
So, now we have up to 2 cookies (note the words ‘up to’ since the cookies will only exist when the expand or collapse buttons are clicked for the first time). The values of these cookies depend on if the columns are expanded or collapsed. We now want to apply the user’s preferences when the page loads. This is obviously read from the cookies.
Firstly, We’ll created 2 variables:
// Left column state var leftCol = $.cookie('leftCol'); // Right column state var rightCol = $.cookie('rightCol');
We’ll create and assign the variable ‘leftCol’ the value of the cookie also named ‘leftCol’. Similarly, I’ve create and assign the variable ‘rightCol’ the value of the cookie named ‘rightCol’. This just makes life easier when we test the value of the cookies (as we’re about to do).
The final step is to apply the user’s selection. To do this, we will first deal with the left column:
if (leftCol == 'collapsed') { $('.collapseLeft').css("display","none"); $('.expandLeft').css("display","block"); $('#leftCol').css("height","20px"); };
This block of code first identifies if the value of the variable ‘leftCol’ (and hence the value of the cookie also named ‘leftCol’) is equal to ‘collapsed’. If this is true (i.e. if the user has selected to collapse the left column), the same actions are performed as when the collapse button for the left column is clicked (see the ‘Collapsible Layout’ section for more information). To refresh your memory, these actions are:
- Hide the button which allows users to collapse the left column.
- Display the button which allows users to expand the left column.
- Set the height of the left column to 20px.
We do exactly the same for the right column:
if (rightCol == 'collapsed') { $('.collapseRight').css("display","none"); $('.expandRight').css("display","block"); $('#rightCol').css("height","20px"); };
Let’s take a look at the demo:
When we now refresh the page (or navigate to other pages using the same cookies), the selection is remembered. Please do post any comments you may have. Let me know what you think!

March 11, 2008
Quote
Thanks for this great tutorial! I used an alteration of it to show/hide the navigation elements persistently across multiple pages in the current CodeIgniter project I am working on.
April 4, 2008
Quote
Great!! I’m follow your instruction and it works!! Thanks for this one, and wish that you will write some more fresh stuff int the future
May 25, 2008
Quote
But how can I use the cookie plugin with the slidetoogle function?
May 25, 2008
Quote
Hi Marc!
If I understand what you’re asking for, you simply apply the sildeUp() and slideDown() functions to the columns:
The ‘400′ is just the time duration for the animation.
Note to visitors: please wrap all you code in ‘pre’ tags when posting comments.
May 26, 2008
Quote
Ah! Ok, thanx for you help! Next time I will use the pre-Tags! =)
May 26, 2008
Quote
I ran into a problem: I have the slideToggle function build into my webpage. If I would use your solution I had to completely my markup. So is it possible to check the current state of the slideToggle-function to use cookies with it?
My jQuery-code:
May 26, 2008
Quote
mhh, I used the -Tags but it did not work. Sorry
May 26, 2008
Quote
If you want to check the current state (i.e. whether a column is up or down), just call the value of the cookie. You’ll notice in the example, I set the value of the cookie to a variable:
and when the column is expanded, for example, we set the value of the cookie to ‘expanded’:
So, to identify if the column is expanded, we just look at the value of the variable (called ‘leftCol’ in this example).
May 26, 2008
Quote
Just to add. We can use the value of the variable (as detailed in my previous comment) to expand or collapse the column (depeding on the visitor’s preference) when they load the page. This way, the script remembers if they expanded or collapsed the column and sets the page accordingly:
May 26, 2008
Quote
ok, but I am using the slideToggle-function and not your way. I have the problem that the build-in slideToggle-function does not offer a way to check in which state it is. Or did I miss the point?
May 26, 2008
Quote
It shouldn’t matter if you use the slideUp and slideDown functions (instead of manipulating the CSS to a certain height). For example:
You can see this here: shopdev.co.uk/demos/CC3/V1/Biome/index.php
I would not use the slideToggle function, as it may be more difficult to keep track of the user’s preferences with regards to which columns are expanded and collapsed. Instead, use both slideUp and slideDown.
May 26, 2008
Quote
ok. But how can I use the same tag for the interaction? In your example are 2 div tags. If you click on the first div then it will disappears and then the other div-tag appears instead.
But I have another structure:
http://www.marctv.de/download/jquery_cookies.txt
I put it in a txt because the tags would be removed here in the comments
May 26, 2008
Quote
Ah.. In this case, all you need to do is add some kind of identifier to the heading. For example, you could add/change the class:
And, to check the preferences (inside document.ready):
Do the same for the expansion action. Remember to add the class, “expanded” to “roll_head”.
May 27, 2008
Quote
Ok, I played a lot with your code. But it does not work for me:
“zu” means: collapsed
“auf” means: expanded
It does not switch the classes. =( Why?
May 27, 2008
Quote
And this does not work either:
May 27, 2008
Quote
Hi Marc!
I see what you mean. It is probably best to use a unique selector as in the demo. To use a single selector will probably mean extending the use of selectors. I would simply use an arrow to the right of the heading. Then, switch between 2 divs as per the example. You could even have the divs extend right across the heading so as to imitate clicking the heading.
May 27, 2008
Quote
I did it:
I used it for the sidebar elements on the right on http://www.marctv.de
=)
May 27, 2008
Quote
Great Job!
I don’t know why I didn’t think of using the “else”. Must be having a bad day.
June 22, 2008
Quote
[…] Recall your interface state using jQuery and Klaus Hartl’s cookie plugin. […]
June 30, 2008
Quote
Got the plugin. Man, this is an awesome little add to jQuery. Ease of use is sky high and this write up makes it so understandable it is hard to imagine a way to screw things up.
I am thrilled with it. And I am thrilled with the tutorial you put together here. It works as expected out of the box. Thanks a million.
July 1, 2008
Quote
Thanks for the comment Robert! All the positive feedback certainly makes it worth while.
July 3, 2008
Quote
@ Homar:
Thank you very much!
Really, I save a lot of time learning your tutorials! They’re amazing!
Thanks again,
David Carreira
July 30, 2008
Quote
Thanks for the write up! Also, the current design of your site is lovely. It’s hard to make the web feel soft.
August 1, 2008
Quote
Quick question, using your example code, how would one extend the cookie to not die at end of the current session?
August 1, 2008
Quote
Hi Rob!
The cookie should not be destroyed. This is indeed the whole point of using the cookies. You can see Klaus Hartl’s page (link near the top of the article) for defining an expiry time and path.