0

I'm trying to replicate a UI effect as on http://mcfc.co.uk I have written a script that hides a div on click function and applies a class to a div with the #id corresponding to the div that was clicked, and the reverse. I'm new to jQuery, how would I save the state of these 'clicked' divs to a cookie to show which were hidden etc??

Thanks for any help.

<script type="text/javascript">

$(document).ready(function(){
    $('.portlet').click( function(){ 
        var idtext = this.id;
        $(this).hide();
        $("[id*=" + idtext + "]").not(this).addClass('add'); 
    });

    $("#content-footer div").click( function(){
        var idtext = this.id;   
        $(this).removeClass('add');                 
        $("[id*=" + idtext + "]").not(this).show();
    }); 
})

</script>

HTML:

DIVs that are hidden/shown on click.....

<div class="column" id="col0">

<div class="portlet" id="p_0">
  <div class="portlet-header">Feeds</div>
  <div class="portlet-content">Lorem ipsum dolor sit amet, consectetuer adipiscing elit
  </div>
</div>
<div class="portlet" id="p_1">
  <div class="portlet-header">News</div>
  <div class="portlet-content">Lorem ipsum dolor sit amet, consectetuer adipiscing elit
  </div>
</div>

</div>

etc....

DIV's that class is applied to.....

<div id="content-footer">
  <div id="p_0"></div>
  <div id="p_1"></div>
  <div id="p_2"></div>
  <div id="p_3"></div>
  <div id="p_4"></div>
</div>
Val
  • 2,291
  • 7
  • 34
  • 63
RobW
  • 5
  • 2
  • 5
  • please edit your formatting, select the code in your question first and then click the code button .. – Gabriele Petrioli Jan 20 '10 at 12:59
  • You don't have unique IDs in your HTML, granted using `$("[id*="+ idtext +"]")` would work, but I don't think it's a good practice. – Mottie Jan 20 '10 at 16:55

2 Answers2

2

Since you're already using jQuery, you could take an advantage of that and use the very simple and easy-to-use plugin, Cookie:

You can see some demos here.

Or here:

$.cookie("myCookie", true);

alert($.cookie("myCookie")); // alerts true. but remember, it's always returned as a string.

Update with example on usage:

$(document).ready(function(){
    $('.portlet').click(function(){ 
        var idtext = this.id;
        $(this).hide();
        $("[id*="+ idtext +"]").not(this).addClass('add'); 
        $.cookie(idtext, false);
    });

    $("#content-footer div").click(function(){
        var idtext = this.id;   
        $(this).removeClass('add');                 
        $("[id*="+ idtext +"]").not(this).show();
        $.cookie(idtext, true);
    }); 
})

As you can see, we're setting the visible state of that current id (idtext) in a cookie with the value of either true or false. When loading these portlets you can check the cookie (either serverside or clientside, your choise) and serve the front end as desired. Tell me if you need anymore help :-)

Kordonme
  • 2,314
  • 3
  • 20
  • 32
  • thanks for your advice kordonme. Looking over this plugin, i am unsure of how to go about implementing it to save the state for each div # - and the equivalent div #'s class on 'each' click ? – RobW Jan 20 '10 at 13:26
  • thanks for the eg - how would i go about manipulating that value stored in 'idtext' and update the 'portlet' and related div # clientside, no backend ? – RobW Jan 20 '10 at 15:15
  • Actually fudgey posted a perfect demo. This looks like exactually what you want :-) – Kordonme Jan 20 '10 at 21:00
  • Thanks for pointing me in the right direction - been a great help – RobW Jan 20 '10 at 21:43
2

I posted a demo of what I think you want here. Be sure to include the jQuery cookie plugin.

Here is the HTML I used:

<div class="column" id="col0">

<div class="portlet" id="p_0">
  <div class="portlet-header">Feeds</div>
  <div class="portlet-content">Lorem ipsum dolor sit amet, consectetuer adipiscing elit</div>
</div>
<div class="portlet" id="p_1">
  <div class="portlet-header">News</div>
  <div class="portlet-content">Lorem ipsum dolor sit amet, consectetuer adipiscing elit</div>
</div>
<div class="portlet" id="p_2">
  <div class="portlet-header">Extra</div>
  <div class="portlet-content">Lorem ipsum dolor sit amet, consectetuer adipiscing elit</div>
</div>
<div class="portlet" id="p_3">
  <div class="portlet-header">Other</div>
  <div class="portlet-content">Lorem ipsum dolor sit amet, consectetuer adipiscing elit</div>
</div>
<div class="portlet" id="p_4">
  <div class="portlet-header">Last</div>
  <div class="portlet-content">Lorem ipsum dolor sit amet, consectetuer adipiscing elit</div>
</div>

</div>

<div id="content-footer">
  <div name="p_0">p0 - Feeds</div>
  <div name="p_1">p1 - News</div>
  <div name="p_2">p2 - Extra</div>
  <div name="p_3">p3 - Other</div>
  <div name="p_4">p4 - Last</div>
</div>

And the script:

$(document).ready(function(){
 var cookie = $.cookie("hidden");
 var hidden = cookie ? cookie.split("|").getUnique() : [];
 var cookieExpires = 7; // cookie expires in 7 days, or set this as a date object to specify a date

 // Remember content that was hidden
 $.each( hidden, function(){
  var pid = this; //parseInt(this,10);
  $('#' + pid).hide();
  $("#content-footer div[name='" + pid + "']").addClass('add');
 })

 // Add Click functionality
 $('.portlet').click(function(){
  $(this).hide();
  $("#content-footer div[name=" + this.id + "]").addClass('add');
  updateCookie( $(this) );
 });
 $("#content-footer div").click(function(){
  $(this).toggleClass('add');
  var el = $("div#" + $(this).attr('name'));
  el.toggle();
  updateCookie( el );
 });

 // Update the Cookie
 function updateCookie(el){
  var indx = el.attr('id');
  var tmp = hidden.getUnique();
  if (el.is(':hidden')) {
   // add index of widget to hidden list
   tmp.push(indx);
  } else {
   // remove element id from the list
   tmp.splice( tmp.indexOf(indx) , 1);
  }
  hidden = tmp.getUnique();
  $.cookie("hidden", hidden.join('|'), { expires: cookieExpires } );
 }
}) 

// Return a unique array.
Array.prototype.getUnique = function() {
 var o = new Object();
 var i, e;
 for (i = 0; e = this[i]; i++) {o[e] = 1};
 var a = new Array();
 for (e in o) {a.push (e)};
 return a;
}

// Fix indexOf in IE
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;
 }
}

Update: Added "indexOf" prototype at the end of the script above to fix an IE bug

Update #2: Added cookieExpires variable, use a number to set the number of days, set it as a date() to set an end date or "null" to set it as a session cookie.

Mottie
  • 84,355
  • 30
  • 126
  • 241
  • Fudgey - this script achieves exactly what i was trying to do. Much appreciated - unique # selectors taken on-board. Thanks. stackoverflow = a great place – RobW Jan 20 '10 at 21:55
  • Im having trouble with this in IE, it wont show the portlets on loading of the page, Mozilla is fine?? – RobW Jan 21 '10 at 09:28
  • ugh, #&$^% IE isn't cooperating. I think I need some help figuring out why it works for all browsers but IE. – Mottie Jan 21 '10 at 14:52
  • Ok, I got it... apparently IE's `indexOf` javascript function is foobared. I added a fix to the end of the code thanks to this post (http://stackoverflow.com/questions/1744310/how-to-fix-array-indexof-in-javascript-for-ie-browsers). The code and demo have been updated! – Mottie Jan 21 '10 at 15:08
  • Thanks once again Fudgey, i was'nt aware of this, perfect! – RobW Jan 21 '10 at 21:13
  • One last thing is im having trouble setting the expiry time of the cookie to say 7 days in the future - not just session based. How would i do this?? – RobW Jan 22 '10 at 09:45
  • Added another variable to set the cookie expiration for 7 days. Although it's not that well documented, there is an example page for the cookie plugin here (http://stilbuero.de/jquery/cookie/) – Mottie Jan 22 '10 at 14:06