Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bootstrap Menu with "More" option Responsive issue

I used bootstrap for my work. I have a bunch of menu-items on top of the page, around 15 items. Hence, my top menu doesn't adopt to the screen widths. It gets broken into the next line introduced by overflowing menus. I want to stop the menu overflow to the next line by having a "More" menu.

Idea is that the overflowing menu-items move to the "More" menu dropdown. But I don't know how to detect the menu overflow. How to move the extra menu-items into the "More" dropdown?

I do have a basic structure and markup in place.

Fiddle: http://jsfiddle.net/xFW8t/347/

Markup:

<ul class="nav nav-pills topnavi">
      <li class="active" ><a href="#">Dashboard</a></li>
      <li ><a href="#">Docs</a></li>
      <li ><a href="#">Docs 2</a></li>
      <li ><a href="#">Docs 3</a></li>
      <li ><a href="#">Docs 4</a></li>
      <li ><a href="#">Data</a></li>
      <li ><a href="#">iWeb</a></li>
      <li ><a href="#">Program</a></li>
      <li ><a href="#">Config</a></li>
      <!-- <li ><a href="#">Smart Inside</a></li>
      <li ><a href="#">Settings </a></li>
      <li ><a href="#">Account</a></li>
      <li ><a href="#">Types</a></li>
      <li ><a href="#">Notifications</a></li>
      <li ><a href="#">History</a></li>
      <li ><a href="#">Redmine</a></li>
      <li ><a href="#">Logout</a></li> -->
      <li class="dropdown" >
        <a aria-expanded="false" aria-haspopup="true" role="button" href="#" data-toggle="dropdown" class="dropdown-toggle">
          More <span class="caret"></span>
        </a>
        <ul class="dropdown-menu">
          <li ><a href="#">Settings </a></li>
          <li ><a href="#">Account</a></li>
          <li ><a href="#">Types</a></li>
          <li ><a href="#">Notifications</a></li>
          <li ><a href="#">History</a></li>
          <li ><a href="#">Redmine</a></li>
          <li class="divider" role="separator"></li>
          <li><a href="#">Logout</a></li>
        </ul>
      </li>
    </ul>

CSS:

.topnavi {
    margin-top:26px; 
}
.nav-pills.topnavi > li > a {
    border-radius: 4px 4px 0 0;
    background:#f2f2f2;
    padding: 8px 12px;
    font-size:12px;
    color: #727272;
    border:1px solid #e7e7e7;
    border-bottom:none;
}
.nav-pills.topnavi > li.active > a, .nav-pills.topnavi > li.active > a:focus, .nav-pills.topnavi > li.active > a:hover {
    background-color: #d9d9d9;
    color: #5b5b5b;
    border: none;
}
.nav-pills.topnavi > li + li {
    margin-left: 3px;
}
.dropdown-menu
{
   right:0px !important; 
    left:auto;
}
like image 274
Bhavan Kumar Natarajan Avatar asked Nov 24 '15 07:11

Bhavan Kumar Natarajan


1 Answers

I want to stop menu overflow next line by "More" menu.

You will have to collect extra list-items and push them into a separate list, depending on the width of the menu as compared to the total width of all menu items.

Deriving from this answer of mine (and adapting it for Bootstrap): https://stackoverflow.com/a/27450575/1355315

Markup:

Split the menu into two uls. One for the menu and one for the dropdown.

<div class="menuwrap">
    <ul id="menu" class="nav nav-pills menu">
        ...<!-- This will contain all the menu items -->
    </ul>
    <ul class="nav nav-pills collect">
        ...<!-- This will contain the dropdown -->
    </ul>
</div>

Javascript (jQuery) code fragment:

function collect() {
    elemWidth = $menu.width();
    fitCount = Math.floor((elemWidth / varWidth) * ctr) - 1;
    $menu.children().css({"display": "block", "width": "auto"});
    $collectedSet = $menu.children(":gt(" + fitCount + ")");
    $("#submenu").empty().append($collectedSet.clone());  
    $collectedSet.css({"display": "none", "width": "0"});
}

Where:

  1. $menu.width() gets the width of the menu
  2. varWidth is the total width of all menu items
  3. ctr is the number of menu items
  4. fitCount gets the number of menu items that exceed the menu width
  5. Reset the width of all items which was zeroed in step #8
  6. $collectedSet collects all such items which exceed the menu width
  7. Empty the dropdown menu and add the cloned collected items
  8. Set the width of original items to zero.

Here is a fiddle putting this all together: http://jsfiddle.net/abhitalks/y0ypz38w/

Note: This is good for small simple menus and a demo. For larger ones, it would be better to remove the menu items and move to the collected dropdown instead of cloning and changing the width. Also, it is not optimized and may throw up some problems in edge cases. Having gotten the idea, you can fine-tune it from here.

.

like image 58
Abhitalks Avatar answered Sep 28 '22 16:09

Abhitalks