Some jquery magic?



  • SOLVED: http://what.thedailywtf.com/t/some-jquery-magic/2161/14?u=matches

    In the ongoing saga of 'push towards creating a working prototype' I have to make the front end user interface to my application. This is a web app, so I figured some form of javascript would be appropriate in enhancing usability of the site.

    The Mission:
    Create an expanding/collapsing navigation menu that preserves state between page changes, postbacks, etc.

    I've been able to get the expand/collapse code working, but I'm at an utter loss as to how to preserve the information between pagechange/postbacks. (I don't normally do UI code, so if I had to venture a guess, a cookie might be appropriate? I don't know though.)

    The JQuery Script

    <script src="~/Scripts/jquery.js"></script>
    <script>
            jQuery(document).ready(function () {
                jQuery(".nav-heading").click(function () {
                    jQuery(this).next(".nav-content").slideToggle(500);
                });
            });
        </script>
    

    The HTML

     <div class="Column C1">
                                    <p class="nav-heading">Viewer</p>
                                    <div class="nav-content">
                                        <ul>
                                            <li>@Html.ActionLink("Home", "Index", "Home")</li>
                                            <li>@Html.ActionLink("About", "About", "Home")</li>
                                            <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                                        </ul>
                                    </div>
                                    <p class="nav-heading">Broadcaster</p>
                                    <div class="nav-content">
                                        <ul>
                                            <li>@Html.ActionLink("Home", "Index", "Home")</li>
                                            <li>@Html.ActionLink("About", "About", "Home")</li>
                                            <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                                        </ul>
                                    </div>
                                    <p class="nav-heading">Administrator</p>
                                    <div class="nav-content">
                                        <ul>
                                            <li>@Html.ActionLink("Home", "Index", "Home")</li>
                                            <li>@Html.ActionLink("About", "About", "Home")</li>
                                            <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                                        </ul>
                                    </div>
                                </div>
    

    More can be provided if needed. The toggle is intentional, I don't like the auto collapsing accordion stuff.



  • Do you really need to roll your own? What's wrong with Bootstrap or Foundation?



  • Bootstrap uses accordion, which as mentioned in the last sentence, I don't like it auto hiding when you click on other items. I also don't know if bootstrap preserves state between pages by default either.

    (To clarify for bootstrap issue, click option 1 to expand, click option 2 to expand, see how option one slides up and option 2 expands? I don't want that. I want option 1 to stay expanded.)



  • Bootstrap accordion doesn't have to autohide. It only happens if you make the panels part of the collapse class.

    I don't know what you mean by preserving state, though. HTTP is stateless, so you would have to be doing ajax to load content into a div to preserve state. In that case, Bootstrap would leave its state alone, unless you went out of your way to touch it.



  • Preserving state in this instance:

    I have 3 nav items that expand/collapse

    I expand 1&3, but 2 remains collapsed

    When I change pages, or postback, I expect 1&3 to be expanded, and 2 collapsed. What actually happens is all three are returned to their default state. Thus the requirement to preserve state, through cookie or (whatever).



  • Yeah, you will always have to do that manually, unless you use something like (Knockout.js + Pager.js) or Ember.js to make a single page app.



  • I understand this, but as stated in the original post, I'm not a UI coder, and so far everything I've found on the web related to this topic is literally utter trash. I figured somebody here has done it.


  • :belt_onion:

    You have to do it manually unless you're using some framework that does the manual part for you.hanzo'd by the cap'n.

    .NET keeps a "state" in a hidden post input that gets updated with each UI change, which has to be ajax-posted or full page posted(ugh) to keep things synchronized. Or as you stated you can store it in a cookie, or in new html5 forms of storage if you want to fuck over the older browsers.



  • Hmm... I asked him why he's rolling his own components instead of using pre-made ones and getting on with it. He's stuck doing things that a framework would do for him. What would you suggest?



  • Except what you don't seem to be reading is that the framework doesn't do what I want it to do. It does something similar, but fundamentally different than what I'm trying to accomplish.



  • Which part? The accordion does what you want for a lot less effort than rolling your own. All you need to do is not make the panels have the same (or any) data-parent attribute.

    State is orthogonal to the presentation layer. You will either need some framework for state or will have to do it yourself.



  • No. It doesn't.

    http://getbootstrap.com/javascript/

    ctrl+f for accordion

    Click on the first option
    Click on the second option
    See how the first option goes away?

    Now click a link, and go elsewhere. See how it resets?

    It doesn't do what I want.

    I'm currently implementing jquery.cookie to address the issue.



  • facepalm

    All you have to do is NOT PUT IN A DATA-PARENT attribute.

    To add accordion-like group management to a collapsible control, add the data attribute data-parent="#selector". Refer to the demo to see this in action.



  • <script>
    		jQuery(document).ready(function () {
    			if ($.cookie("NavViewer") == null) { $.cookie("NavViewer", "true"); }
    			if ($.cookie("NavBroadcaster") == null) { $.cookie("NavBroadcaster", "true"); }
    			if ($.cookie("NavAdministrator") == null) { $.cookie("NavAdministrator", "true"); }
    
    			$('.nav-heading').each(function () {
    				if ($.cookie(this.id) != "" && $.cookie(this.id) == "false") { jQuery(this).next(".nav-content").slideToggle(0) };
    			});
    
            	jQuery(".nav-heading").click(function () {
            		jQuery(this).next(".nav-content").slideToggle(500);
                	if ($.cookie(this.id) == "true")
                	{
                		$.cookie(this.id, "false");
                	}
                	else
                	{
                		$.cookie(this.id, "true");
                	}
                });
            });
        </script>
    

    Fixed.


Log in to reply