24

I need to store an array in a jQuery cookie, any one help me please?

Gumbo
  • 643,351
  • 109
  • 780
  • 844
mukamaivan
  • 1,435
  • 6
  • 16
  • 24

13 Answers13

60

Still not exactly sure what you need but i hope this will help. This is a sample that will allow you to access the items on any page, its just a sample! It uses the cookieName to identify it across the pages.

//This is not production quality, its just demo code.
var cookieList = function(cookieName) {
//When the cookie is saved the items will be a comma seperated string
//So we will split the cookie by comma to get the original array
var cookie = $.cookie(cookieName);
//Load the items or a new array if null.
var items = cookie ? cookie.split(/,/) : new Array();

//Return a object that we can use to access the array.
//while hiding direct access to the declared items array
//this is called closures see http://www.jibbering.com/faq/faq_notes/closures.html
return {
    "add": function(val) {
        //Add to the items.
        items.push(val);
        //Save the items to a cookie.
        //EDIT: Modified from linked answer by Nick see 
        //      http://stackoverflow.com/questions/3387251/how-to-store-array-in-jquery-cookie
        $.cookie(cookieName, items.join(','));
    },
    "remove": function (val) { 
        //EDIT: Thx to Assef and luke for remove.
        indx = items.indexOf(val); 
        if(indx!=-1) items.splice(indx, 1); 
        $.cookie(cookieName, items.join(','));        },
    "clear": function() {
        items = null;
        //clear the cookie.
        $.cookie(cookieName, null);
    },
    "items": function() {
        //Get all the items.
        return items;
    }
  }
}  

So on any page you can get the items like this.

var list = new cookieList("MyItems"); // all items in the array.

Adding items to the cookieList

list.add("foo"); 
//Note this value cannot have a comma "," as this will spilt into
//two seperate values when you declare the cookieList.

Getting all the items as an array

alert(list.items());

Clearing the items

list.clear();

You can add additional things like push and pop quite easily. Again hope this helps.

EDIT See bravos answer if you having issues with IE

almog.ori
  • 7,839
  • 1
  • 35
  • 49
  • Hi - Thanks for your code. I just tried it and it works great except when I call the remove function `list.remove("foo")` it does not remove it from the cookie. Clear and Add work fine, is there anything up with remove? – Redwall Sep 17 '13 at 06:34
  • i based my cookie object from this one to track comment upvotes and downvotes for guests. and i learned about closures! thanks almog.ori! – bonbon.langes Nov 08 '13 at 18:15
  • @almog.ori How set never expire cookies – vakeel Sep 02 '15 at 05:36
  • try this ----> $.cookie(cookieName, items.join(','), { expires: 20*365 }); <---- This will set to expire in 20 years, there is no way to set to never expire . It's not a javascript limitation, it's just not the part of the specification of the cookie http://www.faqs.org/rfcs/rfc2965.html. – almog.ori Sep 02 '15 at 10:23
11

Download the jQuery cookie plugin here: http://plugins.jquery.com/project/Cookie

Setting a cookie with jQuery is as simple as this, where we are creating a cookie called "example" with a value of ["foo1", "foo2"]

$.cookie("example", ["foo1", "foo2"]);

Getting the cookie's value is also very easy with jQuery. The following would show the value of the "example" cookie in a dialog window

alert( $.cookie("example") );
almog.ori
  • 7,839
  • 1
  • 35
  • 49
  • Thanx Ori, it works. But then my actual problem is pushing values in an array cookie onclick. After every thing is done on more than one page, i can be able to append each each array element of the cookie elements to unordered list (ul) and be able to pop out any index i a client feels like. More help please. – mukamaivan Dec 24 '09 at 20:13
  • not sure what you mean, but id start with a function that is called when you click that saves the "selection" (or whatever you need it to be) this can be in a seperate js file that the different pages reference using a script tag with url. – almog.ori Dec 24 '09 at 20:32
  • Fine my js is aready an external file. I hope this sample code gives you a clue on what i want. $(function(){ /**This is what i tend to do*/ $.cookie('cookieItem', msg.txt, { expires: 1}); myCookie_arr.push($.cookie('cookieItem'));// add elements at the end of my cookie array .. $(window).load(function() { .. alert(myCookie_arr); for(var i= 0; i < myCookie_arr; i++){ $('#item-list').append(myCookie_arr[i]);//append on visiting other pages } .. if(cookieItem){ $('#item-list').append($.cookie('cookieItem')); }else{ $('#cat').hide(); } }); }); – mukamaivan Dec 24 '09 at 21:37
  • my varriables are: var myCookie; var initial_arr = new Array(); var myCookie_arr = new Array(); var cookieItem; – mukamaivan Dec 24 '09 at 21:38
  • ........ /*******This quite works but can't actually achievewhat i want***********/ $('#add_item').click(function(){ initial_arr.push(msg.txt); $.cookie('cookieItem', initial_arr, { expires: 1});//Update new cookie $('#item-list').append(msg.txt);//append on click }); /**************This is what i tend to do******************/ $.cookie('cookieItem', msg.txt, { expires: 1});//Update new cookie myCookie_arr.push($.cookie('cookieItem'));// add elements at the end of my cookie array ........... – mukamaivan Dec 24 '09 at 21:40
3

Check out my implementation (as a jquery plugin):

(function ($) {
    $.fn.extend({
        cookieList: function (cookieName) {
            var cookie = $.cookie(cookieName);

            var items = cookie ? eval("([" + cookie + "])") : [];

            return {
                add: function (val) {
                    var index = items.indexOf(val);

                    // Note: Add only unique values.
                    if (index == -1) {
                        items.push(val);
                        $.cookie(cookieName, items.join(','), { expires: 365, path: '/' });
                    }
                },
                remove: function (val) {
                    var index = items.indexOf(val);

                    if (index != -1) {
                        items.splice(index, 1);
                        $.cookie(cookieName, items.join(','), { expires: 365, path: '/' });
                     }
                },
                indexOf: function (val) {
                    return items.indexOf(val);
                },
                clear: function () {
                    items = null;
                    $.cookie(cookieName, null, { expires: 365, path: '/' });
                },
                items: function () {
                    return items;
                },
                length: function () {
                    return items.length;
                },
                join: function (separator) {
                    return items.join(separator);
                }
            };
        }
    });
})(jQuery);

Usage:

  var cookieList = $.fn.cookieList("cookieName");
  cookieList.add(1);
  cookieList.add(2);
  cookieList.remove(1);
  var index = cookieList.indexOf(2);
  var length = cookieList.length();
Pavel Shkleinik
  • 6,298
  • 2
  • 24
  • 36
  • Actually if the array will be accessed by multiple plugins/controls from the page simultaneously, it will be better to reread the cookie before any activity (do not store it to the items variable). – Pavel Shkleinik Apr 13 '12 at 14:32
3

I got error when I try to use almog.ori's script in IE 8

    //This is not production quality, its just demo code.
    var cookieList = function(cookieName) {
    //When the cookie is saved the items will be a comma seperated string
    //So we will split the cookie by comma to get the original array
    var cookie = $.cookie(cookieName);
    //Load the items or a new array if null.
    var items = cookie ? cookie.split(/,/) : new Array();

    //Return a object that we can use to access the array.
    //while hiding direct access to the declared items array
    //this is called closures see http://www.jibbering.com/faq/faq_notes/closures.html
    return {
        "add": function(val) {
            //Add to the items.
            items.push(val);
            //Save the items to a cookie.
            //EDIT: Modified from linked answer by Nick see 
            //      https://stackoverflow.com/questions/3387251/how-to-store-array-in-jquery-cookie
            $.cookie(cookieName, items.join(','));
        },
        "remove": function (val) { 
            //EDIT: Thx to Assef and luke for remove.
            indx = items.indexOf(val); 
            if(indx!=-1) items.splice(indx, 1); 
            $.cookie(cookieName, items.join(','));        },
        "clear": function() {
            items = null;
            //clear the cookie.
            $.cookie(cookieName, null);
        },
        "items": function() {
            //Get all the items.
            return items;
        }
      }

}  

after a few hours digging the error, i only realised that indexOf in

"remove": function (val) { 
                //EDIT: Thx to Assef and luke for remove.
                indx = items.indexOf(val); 
                if(indx!=-1) items.splice(indx, 1); 
                $.cookie(cookieName, items.join(','));        },

is not support in IE 8.

and so I add in another code base from here How to fix Array indexOf() in JavaScript for Internet Explorer browsers

it works,

"remove": function (val) {
    //EDIT: Thx to Assef and luke for remove.
    /** indexOf not support in IE, and I add the below code **/
    if (!Array.prototype.indexOf) {
        Array.prototype.indexOf = function(obj, start) {
            for (var i = (start || 0), j = this.length; i < j; i++) {
                if (this[i] === obj) { return i; }
            }
            return -1;
        }
    }
    var indx = items.indexOf(val);
    if(indx!=-1) items.splice(indx, 1);
    //if(indx!=-1) alert('lol');
    $.cookie(cookieName, items.join(','));
},

just in case anyone found the script is not working in IE 8, this might help.

Community
  • 1
  • 1
Bravo Net
  • 805
  • 5
  • 17
  • 30
  • That the remove method also shims the native Array object is something you wouldn't expect from the remove method. Unexpected side effect. – oyvindn Aug 17 '12 at 10:33
3

I don't know if this will help someone but I also needed the function that checks if the item already there so I do not add it again.

I used the same remove function and alter it to be contain function:

"contain": function (val) {
//Check if an item is there.
if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(obj, start) {
        for (var i = (start || 0), j = this.length; i < j; i++) {
            if (this[i] === obj) { return i; }
        }
        return -1;
    };
}
var indx = items.indexOf(val);
if(indx>-1){
    return true;
}else{
    return false;
}
},

for some reason the code above does not always work. so here is the new one that works:

"contain": function (val) {
//Check if an item is there.
if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(obj, start) {
        for (var i = (start || 0), j = this.length; i < j; i++) {
            if (this[i] === obj) { return i; }
        }
        return -1;
    };
}
var indx = items.join(',').indexOf(val);
if(indx > -1){
    return true;
}else{
    return false;
}
},
alhoseany
  • 761
  • 9
  • 28
2

This implementation provides independent access for multiple controls on the page:

(function ($) {
    $.fn.extend({
        cookieList: function (cookieName) {

            return {
                add: function (val) {
                    var items = this.items();

                    var index = items.indexOf(val);

                    // Note: Add only unique values.
                    if (index == -1) {
                        items.push(val);
                        $.cookie(cookieName, items.join(','), { expires: 365, path: '/' });
                    }
                },
                remove: function (val) {
                    var items = this.items();

                    var index = items.indexOf(val);

                    if (index != -1) {
                        items.splice(index, 1);
                        $.cookie(cookieName, items.join(','), { expires: 365, path: '/' });
                    }
                },
                indexOf: function (val) {
                    return this.items().indexOf(val);
                },
                clear: function () {
                    $.cookie(cookieName, null, { expires: 365, path: '/' });
                },
                items: function () {
                    var cookie = $.cookie(cookieName);

                    return cookie ? eval("([" + cookie + "])") : []; ;
                },
                length: function () {
                    return this.items().length;
                },
                join: function (separator) {
                    return this.items().join(separator);
                }
            };
        }
    });
})(jQuery);
Pavel Shkleinik
  • 6,298
  • 2
  • 24
  • 36
  • 1
    Why 2 answers? If you're unsatisfied of / have to update your answer use the 'edit' function. – BlackBear Apr 14 '12 at 11:17
  • 1st implementation will work a little bit faster, while second is a little bit slower BUT in this case the array could be access by multiple controls on the single page or even from different tabs and the values in the array will be always actual. – Pavel Shkleinik May 29 '12 at 08:51
2

I slightly adjusted the example to use JSON encoding and secureJSON decode, making it more robust and save.

It depends on https://code.google.com/p/jquery-json/

/*
 * Combined with:
 * http://www.terminally-incoherent.com/blog/2008/11/25/serializing-javascript-objects-into-cookies/
 * With:
 * https://code.google.com/p/jquery-json/
 *
 */
(function ($) {
    $.fn.extend({
        cookieList: function (cookieName, expireTime) {

            var cookie = $.cookie(cookieName);              
            var items = cookie ? $.secureEvalJSON(cookie) : [];

            return {
                add: function (val) {
                    var index = items.indexOf(val);
                    // Note: Add only unique values.
                    if (index == -1) {
                        items.push(val);
                        $.cookie(cookieName, $.toJSON(items), { expires: expireTime, path: '/' });
                    }
                },
                remove: function (val) {
                    var index = items.indexOf(val);

                    if (index != -1) {
                        items.splice(index, 1);
                        $.cookie(cookieName, $.toJSON(items), { expires: expireTime, path: '/' });
                    }
                },
                indexOf: function (val) {
                    return items.indexOf(val);
                },
                clear: function () {
                    items = null;
                    $.cookie(cookieName, null, { expires: expireTime, path: '/' });
                },
                items: function () {
                    return items;
                },
                length: function () {
                    return items.length;
                },
                join: function (separator) {
                    return items.join(separator);
                }
            };
        }
    });
})(jQuery);
Wxll
  • 316
  • 3
  • 5
  • Excellent. Code snippets on this page where eval("([" + cookie + "])") is used fail to deal with strings (I guess they only work for numbers). – Vitaly Sazanovich Feb 06 '14 at 15:41
2

Nice piece of code for what I am doing at the moment, but found a bug. I was saving a list of integers (IDs) to the cookie. However when the cookie is first read it typecasts to strings. I previously save (int) 1, and later when the cookie is retrieved on a page reload is designates it as "1". Thus when I try to remove (int) 1 from the list it won't index a match.

The fix I applied is to change the "val" expressions to val.toString() prior to adding or indexing the items. Thus items is an array of strings.

"add": function(val) {
    //Add to the items.
    items.push(val.toString());
    //Save the items to a cookie.
    $.cookie(cookieName, items.join(','));
},

"remove": function (val) { 
    //EDIT: Thx to Assef and luke for remove.
    if (!Array.prototype.indexOf) {
        Array.prototype.indexOf = function(obj, start) {
            for (var i = (start || 0), j = this.length; i < j; i++) {
                if (this[i] === obj) { return i; }
            }
            return -1;
        };
    }

    var indx = items.indexOf(val.toString()); 
    if(indx!=-1) items.splice(indx, 1); 
    //Save the items to a cookie.
    $.cookie(cookieName, items.join(','));
},
user3369864
  • 131
  • 1
  • 5
2

This is how you store and retrieve an array in cookie using json and jquery.

//Array    
var employees = [
                {"firstName" : "Matt", "lastName" : "Hendi"},
                {"firstName" : "Tim", "lastName" : "Rowel"}
];

var jsonEmployees = JSON.stringify(employees);//converting array into json string   
$.cookie("employees", jsonEmployees);//storing it in a cookie

var empString = $.cookie("employees");//retrieving data from cookie
var empArr = $.parseJSON(empString);//converting "empString" to an array. 
Susie
  • 5,038
  • 10
  • 53
  • 74
1

Here is JSON implementation for working with cookie, much better way for storing arrays. tested from my end.

$.fn.extend({
  cookieList: function (cookieName) {
      var cookie = $.cookie(cookieName);

      var storedAry = ( cookie == null ) ? [] : jQuery.parseJSON( cookie );


      return {
          add: function (val) {

              var is_Arr = $.isArray( storedAry );
              //console.log(storedAry);


              if( $.inArray(val, storedAry) === -1 ){
                storedAry.push(val);
                //console.log('inside');
              }

              $.cookie( cookieName, JSON.stringify(storedAry), { expires : 1 ,  path : '/'});
              /*var index = storedAry.indexOf(val);
              if (index == -1) {
                  storedAry.push(val);
                  $.cookie(cookieName, storedAry.join(','), { expires: 1, path: '/' });
              }*/
          },
          remove: function (val) {

              storedAry = $.grep(storedAry, function(value) {
                return value != val;
              });
              //console.log('Removed '+storedAry);

              $.cookie( cookieName, JSON.stringify(storedAry), { expires : 1 ,  path : '/'});
              /*var index = storedAry.indexOf(val);
              if ( index != -1 ){
                  storedAry.splice( index, 1 );
                  $.cookie(cookieName, storedAry.join(','), { expires: 1, path: '/' });
               }*/
          }
          clear: function () {
              storedAry = null;
              $.cookie(cookieName, null, { expires: 1, path: '/' });
          }
      };
  }

});

Mohan Dere
  • 4,497
  • 1
  • 25
  • 21
1

I added the "remove" action to whoever want to use it - val is the index at which to start changing the array:

    "remove": function (val) {
        items.splice(val, 1);
        $.cookie(cookieName, items.join(','));
    }
almog.ori
  • 7,839
  • 1
  • 35
  • 49
1

just a little alternative to the "remove" function:

    "removeItem": function (val) { 
        indx = items.indexOf(val);
        if(indx!=-1) items.splice(indx, 1);
        $.cookie(cookieName, items.join(',')); 
    }

where val is the value of an item in the array e.g:

   >>> list.add("foo1");
   >>> list.add("foo2");
   >>> list.add("foo3");
   >>> list.items();

   ["foo1", "foo2", "foo3"];

   >>> list.removeItem("foo2");
   >>> list.items();

   ["foo1", "foo3"];
Luke
  • 36
  • 1
0

You could serialize the arrays before storing as cookie and then deserialize when reading. ie with json?

Flobo
  • 1
  • 1