Accordion style sidebar

Has anyone found a way to build an accordion style sidebar without using JQuery in Meteor?

I don’t mind manipulating CSS within Template events, in fact that’s the way I prefer to do it. I’d like the finished product to look something like this: http://codepen.io/rbobrowski/pen/likvA

Any tips on getting started?

1 Like

I hacked this for one of my projects: https://github.com/ManuelDeLeon/viewmodel-explorer

To see it in action go to http://viewmodel.meteor.com/ and press Ctrl + Shift + E

It needs a lot of cleanup but it might give you an idea of how to do it.

2 Likes

Given the fact that how much less code you have to write using viewmodel, I wonder whether or not it would actually make sense to make it the recommended way of doing things in meteor.

People love .jade, .coffee, .styl, and that’s just for the fact that they have to write less code and it’s simpler to read, not even involving the fact (as it is with viewmodel) that it’s also a really nice technical upside to it…

That being said, compared to the current way of writing and wiring up models, views and controllers, are there any downsides to this idea?

I got this working, with a small kink, maybe someone can help me with the JQuery:

// factored out function that works for the most part

function sideBarAction (target) {
  var headers = ["H1","H2","H3","H4","H5","H6"];
  var target = target,
    name = target.nodeName.toUpperCase();

  if($.inArray(name,headers) > -1) {
    var subItem = $(target).next();

    //slideUp all elements (except target) at current depth or greater
    var depth = $(subItem).parents().length;
    var allAtDepth = $(".accordion div").filter(function() {
      if($(this).parents().length >= depth && this !== subItem.get(0)) {
        return true;
      }
    });
    $(allAtDepth).slideUp("slow");

    //slideToggle target content and adjust bottom border if necessary
    subItem.slideToggle("slow",function() {
        // $(".accordion :visible:last").css("border-radius","0 0 10px 10px");
    });
  }
}

// onrendred, i have to call out to sidebar twice to get the proper h2 to unfold and the others to fold up as it should.

Template.userDashboardSidebar.onRendered(function () {
  debugger;
  var accoutDefaults = Session.get('accountDefaults');
  var section = accoutDefaults.currentSection;
  var h2 = '.accordion h2#' + section;
  var target = this.find(h2)
  sideBarAction(target);
  sideBarAction(target);
});

// events

Template.userDashboardSidebar.events({
  "click .accordion": function (event, template) {
    event.preventDefault();
    debugger;
    sideBarAction(event.target);
  }
});

// html

<div class="accordion">
      <section style="top: 193px;" class="" id="main-menu">
        <h1>Top Header</h1>
        <div class="opened-for-fp">
          <h2 id="firstSubHeader">First Sub Header</h2>
          <div class="opened-for-fp">
             <h3>Sub Sub Header 1</h3><div></div>
             <h3>Sub Sub Header 2</h3><div></div>
          </div>
          <h2>Second Sub Header</h2>
          <div class="opened-for-fp">
             <h3>Sub Sub Header 1</h3><div></div>
             <h3>Sub Sub Header 2</h3><div></div>
          </div>
...

What’s happening is, I have to call the sideBarAction twice in order for the accordion to open the section I want in the onRendered method. In the onRendered method, the first call to sideBarAction rolls up all the h2 elements, and the section call (hard coded at this point) roles up the first h2 with the id (this is just an example, all the h2 and h3 elements will eventually have an id.

If I remove the onRendered code, the accordion is fully expanded to start. Then if I click an h2 on the first pass all the elements roll up and (sometimes it seems) the correct h2 will expand, on all subsequent clicks on a h2 it acts normal.

How can I modify the h2 so it acts as it should?

Try this bootstrap accordion menu for sidebar