3

I have the following toggle system, but I want it to remember what was open/closed using the jQuery cookie plugin. So for example if I open a toggle and then navigate away from the page, when I come back it should be still open. By default all Toggles should be closed.

This is code I have so far, but it's becoming rather confusing, some help would be much appreciated thanks.

jQuery.cookie = function (name, value, options) { if (typeof value != 'undefined') { options = options || {}; if (value === null) { value = ''; options = $.extend({}, options); options.expires = -1; } var expires = ''; if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) { var date; if (typeof options.expires == 'number') { date = new Date(); date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); } else { date = options.expires; } expires = '; expires=' + date.toUTCString(); } var path = options.path ? '; path=' + (options.path) : ''; var domain = options.domain ? '; domain=' + (options.domain) : ''; var secure = options.secure ? '; secure' : ''; document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join(''); } else { var cookieValue = null; if (document.cookie && document.cookie != '') { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookie = jQuery.trim(cookies[i]); if (cookie.substring(0, name.length + 1) == (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } };
        // var showTop = $.cookie('showTop');
        if ($.cookie('showTop') == 'collapsed') {

            $(".toggle_container").hide();
            $(".trigger").toggle(function () {
                $(this).addClass("active");
            }, function () {
                $(this).removeClass("active");
            });
            $(".trigger").click(function () {
                $(this).next(".toggle_container").slideToggle("slow,");
            });
        } else {

            $(".toggle_container").show();
            $(".trigger").toggle(function () {
                $(this).addClass("active");
            }, function () {
                $(this).removeClass("active");
            });
            $(".trigger").click(function () {
                $(this).next(".toggle_container").slideToggle("slow,");
            });
        };

        $(".trigger").click(function () {
            if ($(".toggle_container").is(":hidden")) {
                $(this).next(".toggle_container").slideToggle("slow,");
                $.cookie('showTop', 'expanded');
            } else {
                $(this).next(".toggle_container").slideToggle("slow,");
                $.cookie('showTop', 'collapsed');
            }

            return false;

        });

and this is a snippet of the HTML it works with:

<li> 
                                        <label for="small"><input type="checkbox" id="small" /> Small</label> 
                                        <a class="trigger" href="#">Toggle</a>  
                                        <div class="toggle_container"> 
                                            <p class="funding"><strong>Funding</strong></p> 
                                            <ul class="childs"> 
                                                <li class="child"> 
                                                    <label for="fully-funded1"><input type="checkbox" id="fully-funded1" /> Fully Funded</label> 
                                                    <a class="trigger" href="#">Toggle</a> 
                                                    <div class="toggle_container"> 
                                                        <p class="days"><strong>Days</strong></p> 
                                                        <ul class="days clearfix"> 
                                                            <li><label for="1pre16">Pre 16</label> <input type="text" id="1pre16" /></li> 
                                                            <li><label for="2post16">Post 16</label> <input type="text" id="2post16" /></li> 
                                                            <li><label for="3teacher">Teacher</label> <input type="text" id="3teacher" /></li> 
                                                        </ul> 
                                                    </div> 
                                                </li>
Cameron
  • 91
  • 1
  • 2
  • 4
  • @Cameron - Based on your comments, you most likely have a syntax error somewhere preventing all code from running and throwing an error, check this with Firebug if possible. – Nick Craver Mar 26 '10 at 13:29

2 Answers2

2

You can shorten all that code down to this, should keep it much simpler:

$(".toggle_container").toggle($.cookie('showTop') != 'collapsed');

$(".trigger").click(function () {
    $(this).toggleClass("active").next(".toggle_container").slideToggle("slow,");
    $.cookie('showTop', 
                $(".toggle_container").is(":hidden") ? 'expanded' : 'collapsed');
    return false;
});

Here's an approach that sets a cookie for each container, all that's necessary is to give each .toggle_container a unique ID:

$(".toggle_container").each(function() {
    $(this).toggle($.cookie('show-' + this.id) != 'collapsed');
});

$(".trigger").click(function () {
    var tc = $(this).toggleClass("active").next(".toggle_container").slideToggle("slow", function() {
        $.cookie('show-' + $(this).attr("id"), $(this).is(":hidden") ? 'collapsed' : 'expanded');        
    });
    return false;
});​
Nick Craver
  • 594,859
  • 130
  • 1,270
  • 1,139
  • It's not working properly. All the toggles are open by default and it's not remembering which one was open/closed. And it's no longer showing the correct toggle class. It should be noted that there is about 20+ of these toggles, so I'm guessing we need some way of using unique ids for each toggle? – Cameron Mar 26 '10 at 12:40
  • @Cameron - Yes, currently it's remembering the last set for all, I'll update with an example of remembering per. – Nick Craver Mar 26 '10 at 12:41
  • @Cameron - Updated the answer, just give each `.toggle_container` and ID and this will handle each one individually. You can play with it here, click run up top to reload the page, you can see the hide/shown state being restored by the cookies: http://jsfiddle.net/a33rV/ – Nick Craver Mar 26 '10 at 12:50
  • that's awesome if I could give you more points I would, thank you ! – mcgrailm Mar 26 '10 at 12:55
1

Okay this is the code I have:

The stuff commented out worked fine, but didn't talk to unique ID's. The code above that doesn't work.

$(document).ready(function () {

        $(".toggle_container").each(function() {
            $(this).toggle($.cookie('show-' + this.id) != 'collapsed');
        });

        $(".trigger").click(function () {
            var tc = $(this).toggleClass("active").next(".toggle_container").slideToggle("slow", function() {
                $.cookie('show-' + $(this).attr("id"), $(this).is(":hidden") ? 'collapsed' : 'expanded');        
            });
            return false;
        });​

        //$(".toggle_container").toggle($.cookie('showTop') != 'collapsed');

        /*$(".trigger").click(function () {
            $(this).toggleClass("active").next(".toggle_container").slideToggle("slow,");
            $.cookie('showTop',
            $(".toggle_container").is(":hidden") ? 'expanded' : 'collapsed');
            return false;
        });*/

    });

and this is the HTML

                            <li> 
                    <input id="MC_ctl00_RPS_chkItem_1" type="checkbox" name="ctl00$MC$ctl00$RPS$ctl01$chkItem" /> 
                    <label for="MC_ctl00_RPS_chkItem_1" id="MC_ctl00_RPS_lbl_1">Medium</label> 
                    <a class="trigger" href="#">Toggle</a>  
                    <div class="toggle_container" id="divFund"> 
                        <p class="funding"><strong>Funding</strong></p> 
                        <ul class="childs"> 

                                <li class="child"> 
                                    <input id="MC_ctl00_RPS_RPF_1_chkItem_0" type="checkbox" name="ctl00$MC$ctl00$RPS$ctl01$RPF$ctl00$chkItem" /> 
                                    <label for="MC_ctl00_RPS_RPF_1_chkItem_0" id="MC_ctl00_RPS_RPF_1_lbl_0">Fully Funded</label> 
                                    <a class="trigger" href="#">Toggle</a> 
                                    <div class="toggle_container" id="divDays"> 
                                        <p class="days"><strong>Days</strong></p> 
                                        <ul class="days clearfix"> 
                                            <li> 
                                                <label for="MC_ctl00_RPS_RPF_1_txtPre16_0" id="MC_ctl00_RPS_RPF_1_lblPre16_0">Pre 16</label> 
                                                <input name="ctl00$MC$ctl00$RPS$ctl01$RPF$ctl00$txtPre16" type="text" id="MC_ctl00_RPS_RPF_1_txtPre16_0" /> 
                                            </li> 
                                            <li> 
                                                <label for="MC_ctl00_RPS_RPF_1_txtPost16_0" id="MC_ctl00_RPS_RPF_1_Label1_0">Post 16</label> 
                                                <input name="ctl00$MC$ctl00$RPS$ctl01$RPF$ctl00$txtPost16" type="text" id="MC_ctl00_RPS_RPF_1_txtPost16_0" /> 
                                            </li> 
                                            <li> 
                                                <label for="MC_ctl00_RPS_RPF_1_txtTeacher_0" id="MC_ctl00_RPS_RPF_1_Label2_0">Teacher</label> 
                                                <input name="ctl00$MC$ctl00$RPS$ctl01$RPF$ctl00$txtTeacher" type="text" id="MC_ctl00_RPS_RPF_1_txtTeacher_0" /> 
                                            </li> 

                                        </ul> 
                                    </div> 
                                </li> 
Cameron
  • 24,868
  • 91
  • 263
  • 449
  • @Cameron - Login and edit your original question, this really clutters things up. This javascript and code works, test here: http://jsfiddle.net/a33rV/1/ Your problem is elsewhere... – Nick Craver Mar 26 '10 at 13:43
  • Sorry I can't. Because the original Q was not logged in :/ The other code (before choosing IDs) works so I can't see how a problem elsewhere is causing it. – Cameron Mar 26 '10 at 13:47
  • Did you click the link in my comment? It's that exact HTML and javascript working...the problem is elsewhere. – Nick Craver Mar 26 '10 at 13:52
  • Yes I have tried adding the code as well and it works in that test thing. But for some reason its not working on my site? However the code prior to this you provided does work. So something new that was added is what is breaking it (poss in conflict with something else but I don't know what). – Cameron Mar 26 '10 at 13:55