views:

523

answers:

4

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>
+1  A: 

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
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
@Cameron - Yes, currently it's remembering the last set for all, I'll update with an example of remembering per.
Nick Craver
@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
that's awesome if I could give you more points I would, thank you !
mcgrailm
A: 

Removing clutter...

Cameron
@Cameron - 2 things, 1) your question is editable :) 2) Did you give the toggle_container divs a unique ID? Look at the html in my working sample of your code here: http://jsfiddle.net/a33rV/
Nick Craver
A: 

For some reason the comment box has disappeared for me??? I have given the containers unique ID's but the toggles no longer work. Not sure why.

Cameron
The first code you gave me works fine. But the next one for the unique IDS does not toggle.
Cameron
@Cameron - You are now logged in on a different account for some reason. In any case, click add command underneath my question and I'll get an alert that you sent something :) Can you post the html you now have?
Nick Craver
added the code in another answer --> http://stackoverflow.com/questions/2523189/jquery-toggle-with-cookie/2523607#2523607
Cameron
A: 

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
@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
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
@Cameron - Did you click the link in my comment? It's that exact HTML and javascript working...the problem is elsewhere.
Nick Craver
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