Sidebar

Sidebar Basics

1. Layout

  • Default HTML layout used for sidebar is:
    1. shortcut buttons: optional
    2. .nav-list: contains sidebar items
    3. expand/collapse button: optional
    
    
  • Starting with the following file you can find more details:
    mustache/app/views/layouts/partials/_shared/sidebar.mustache

2. Menu item

  • First level menu item has the following markup:
  • Item text
  • mustache/app/views/layouts/partials/_shared/sidebar/item.mustache
  • Icons should have .menu-icon class.
    First level menu item's text should be inside .menu-text element, but this isn't needed for deeper levels:
    
    
  • level 2 item text
  • level 2 item text

3. Shortcut Buttons

  • It consists of .sidebar-shortcuts-large and .sidebar-shortcuts-mini which is displayed when sidebar is minimized (collpased)
  •  
    

4. Minimize Button

  • Sidebar collapse/expand button is used to minimize/restore sidebar.
      
    
  • There is also another .sidebar-expand button for sidebar in 2nd mobile view style.
    In that case, sidebar is automatically minimized and the button is used to expand it:
     
    
  • You can use data-icon1 and data-icon2 attributes to specify icons to use in collapsed/expanded state

5. Other notes

  • To add a badge or label inside menu items, you should put it inside .menu-text element:
     
       Menu Text
       4
     
    
    You can also include a tooltip:
     
       Menu Text
       
         
       
     
    

6. Sidebar options

Responsive Sidebar

Mobiles Views

  • There are 3 styles of responsive (mobile view) sidebar when screen size is below 992px.
    You can change this value by recompiling LESS files.
    See CSS section

1. Default mobile menu style

  • Default mobile menu style

    You should add .responsive class to .sidebar element.
  • You can also add .push_away class to .sidebar to push content when sidebar is shown:
     
    

2. Automatically minimized menu style

  • You should add .responsive-min class to .sidebar element and there should also be an invisible toggle button present, right before sidebar.
    An additional .sidebar-toggle.sidebar-expand button, expands sidebar in mobile view: (More info)
    
    
    

3. Bootstrap collapse style

  • For this you should add .collapse.navbar-collapse class to .sidebar element and have the correct toggle buttons inside navbar:
    
    

Toggle Button

  • In default responsive (mobile) style and collapsible responsive style, toggle buttons are used to show and hide sidebar.
  • Buttons can are either before brand text container (.navbar-header) or inside it:
     
    
     
    
  • If you want to use old style toggle button, you should insert it before .sidebar element:
     
       Toggle sidebar
       
     
     
    
    It should have a span.toggler-text inside it and you can change MENU text to something else by modifying @toggler-text variable inside assets/css/less/sidebar/old-toggle-button.less and recompiling ace.less
  • In 2nd mobile menu style, you should add an invisible .menu-toggler element right before .sidebar
     
     
    
  • For collapse style sidebar in mobile view (3rd style), you should use data-toggle and data-target attributes:
    <button class="pull-right navbar-toggle collapsed" type="button"
               data-toggle="collapse" data-target=".sidebar">
      <span class="sr-only">Toggle sidebar</span>
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
    </button>
    
     
     
    

Sidebar Options

1. Horizontal Sidebar

  • For horizontal menu you should add .h-sidebar class to .sidebar and .h-navbar to .navbar element:
     
     
  • You should also add .hover class to all LI elements, so that submenus are shown on mouse hover:
     
    
  • Horizontal menu is only visible when screen width is above 991px.
    You can choose any of the three possible mobile menu styles for smaller widths.
  • Also, in demo page, when horizontal menu is fixed and you scroll down, it moves up gradually.
    To enable this, you should include the following code in your page:
    mustache/app/views/assets/scripts/top-menu.js

2. Submenu on Hover

  • You can have submenus to be displayed on mouse hover instead of click.
  • For that you should add .hover class to each LI element and also add .arrow element before submenus.
     
    

3. Compact Sidebar

  • Simply add .compact class to .sidebar element:
     
    

4. Highlight Item

  • An alternative active item highlight.
    Add .highlight to LI elements:
     
    

5. Fixed Sidebar

  • Adding .sidebar-fixed class to .sidebar element makes it fixed by default:
     
    
  • For more info please see sidebar settings

6. Minimized Sidebar

  • Adding .menu-min class to .sidebar element makes it minimized by default:
     
    
  • For more info please see sidebar settings

Sidebar Active Item

Ajax

  • If your page content is updated via ajax and you want to mark a different menu item as active, you can do like this as an example:
    //inside the function when ajax content is loaded
    
    //somehow get a reference to our newly clicked(selected) element's parent "LI"
    var new_active = $(this).parent();
    
    //remove ".active" class from all (previously) ".active" elements
    $('.nav-list li.active').removeClass('active');
    
    //add ".active" class to our newly selected item and all its parent "LI" elements
    new_active.addClass('active').parents('.nav-list li').addClass('active');
    
    //you can also update breadcrumbs:
    var breadcrumb_items = [];
    //$(this) is a reference to our clicked/selected element
    $(this).parents('.nav-list li').each(function() {
      var link = $(this).find('> a');
      var text = link.text();
      var href = link.attr('href');
      breadcrumb_items.push({'text': text, 'href': href});
    })
    //now we have a breadcrumbs list and can replace breadcrumbs area
    
  • If you are using a client side application framework such as ember.js or angular.js, you may have other approaches that work better in the specific context.

non-Ajax

  • If you navigate to other pages without ajax, you can have several approaches depending on your application.
  • For example if you have a list of pages retrieved from a data source, you can lookup the item that matches current page and mark it as active.
    You should also mark its parents as active and open
  • In the following example we have a list of items.
    We find our current item using its identifier.
    Then we mark it as active, find its parent, mark the parent as active & open and repeat this action.
  • Sample PHP code:
    //suppose we have a list of pages (associative array or other data structure)
    //$menu_list = ... //retrieved from database
    //or
     $menu_list = array(
        'id or name of page 1' => array (
             'href' => '#link1',
             'text' => 'item name or text',
           'parent' => 'parent id or name'
        )
        ,
       'id or name of page 2' => array (
             'href' => '#link2',
             'text' => 'item name or text',
           'parent' => 'parent id or name'
        )
        ,
       'new-user' => array (
             'href' => 'user/create',
             'text' => 'Add User',
           'parent' => 'operations'
        )
        ...
     );
    
    //we somehow know the ID or tag or hash of the current page
    //perhapse from a database lookup or by simply checking its URL
    //for some pointers such as ID, file name, category name, etc ...
    $current_page = 'new-user';
    $breadcrumbs = array();//let's create our breadcrumbs array as well
    
    //make_me should be a reference to current_item not a copy of it
    $mark_me = &$menu_list[$current_page];
    $open = false;
    while(true) {//you can also use a recursive function instead of a loop
      $mark_me['active'] = true;//mark this as "active"
      if( $open ) $mark_me['open'] = true;//mark this as "open"
      
      $breadcrumbs[] = $mark_me;
    
      $parent_id = $mark_me['parent'];//see if it has a parent
      if( $parent_id == null || !isset($menu_list[$parent_id]) ) break;//if not, break
      
      $mark_me = &$menu_list[$parent_id];//set item's parent as the new "mark_me" and repeat
      $open = true;//parent elements should be marked as "open" too
    }
    
    foreach($menu_list as $id => $menu_item) {
      print('<li class="');
       if( $menu_item['active'] ) print('active');
       if( $menu_item['open'] ) print(' open');
      print('">');
      //something like <li class="active open"> will be printed
      //...
      //print other parts of menu item
    }
    
    //now we also have a list of breadcrumb items to print later
    

    Sample Javascript code (for example in Nodejs):
    //suppose we have a list of pages (associative array or other data structure)
    //var menu_list = ... //retrieved from database
    //or
     var menu_list = {
        'id or name of page 1' : {
             'href' : '#link1',
             'text' : 'item name or text',
           'parent' : 'parent id or name'
        }
        ,
       'id or name of page 2' : {
             'href' : '#link2',
             'text' : 'item name or text',
           'parent' : 'parent id or name'
        }
        ,
       'new-user' : {
             'href' : 'user/create',
             'text' : 'Add User',
           'parent' : 'operations'
        }
        ...
     };
    
    //we somehow know the ID or tag or hash of the current page
    //perhapse from a database lookup or by simply checking its URL
    //for some pointers such as ID, file name, category name, etc ...
    var current_page = 'new-user';
    var breadcrumbs = [];//let's create our breadcrumbs array as well
    
    //make_me should be a reference to current_item not a copy of it
    var mark_me = menu_list[current_page];
    var open = false;
    while(true) {//you can also use a recursive function instead of a loop
      mark_me['active'] = true;//mark this as "active"
      if( open ) mark_me['open'] = true;//mark this as "open"
      
      breadcrumbs.push(mark_me);
    
      var parent_id = mark_me['parent'];//see if it has a parent
      if( parent_id == null || !(parent_id in menu_list) ) break;//if not, break
      
      mark_me = menu_list[parent_id];//set item's parent as the new "mark_me" and repeat
      open = true;//parent elements should be marked as "open" too
    }
    
    var output = '';
    for(var id in menu_list) if(menu_list.hasOwnProperty(id)) {
      var menu_item = menu_list[id];
      output += '<li class="';
       if( menu_item['active'] ) output += 'active';
       if( menu_item['open'] ) output += ' open';
      output += '">';
      //something like <li class="active open"> will be printed
      //...
      //print other parts of menu item
    }
    console.log(output);
    
    //now we also have a list of breadcrumb items to print later