0

I have a bootstrap3 responsive table that contains a dropdown selection (made with unordered list elements) in each row. When the dropdown is clicked the user is forced to scroll to see all the options, and on smaller screens I cannot even scroll to do that.

I'm trying to make it so the options can appear on top of the table instead of under/behind (which forces the vertical scrolling). I have tried altering the z-index and overflow-y properties of the li, ul and containing div elements in CSS but it isn't making a difference.

Similar SO questions have not received an accepted/working answer either:

"dropdown button get cutoff by responsive table in bootstrap 3"

"Bootstrap dropdown menu within a responsive table"

"Responsive table issues in bootstrap"

How can I make the list appear to float on top/outside of the responsive table? Is this even possible?

jsfiddle:

https://jsfiddle.net/vndyLy1e/3/

html:

<div class="table-responsive">
  <table class="table table-striped table-condensed" style="z-index: 1">
    <thead>
      <tr>
        <th class="col-xs-2 col-md-3">Col 1</th>
        <th class="col-xs-1 col-md-2">Col 2</th>
        <th class="col-xs-1 col-md-2">Col 3</th>
        <th class="col-xs-1 col-md-2">Col 4</th>
        <th class="col-xs-1 col-md-1">Col 5</th>
        <th class="col-xs-1 col-md-1">Col 6</th>
        <th class="col-xs-1 col-md-1"></th>
      </tr>
    </thead>
    <tbody class="table-body">

      <tr>
        <td>$Col 1 Data</td>
        <td>$Col 2 Data</td>
        <td>$Col 3 Data</td>
        <td>$Col 4 Data</td>
        <td>$Col 4 Data</td>
        <td>$Col 5 Data</td>

        <!-- Action Dropdown-->
        <td>
          <div class="btn-group">
            <button type="button" class="btn btn-default btn-transparent btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
              <span class="title-element-name">Actions </span><span class="caret"></span>
            </button>
            <ul class="dropdown-menu">
              <li><a>Drop Option 1</a></li>
              <li><a>Drop Option 2</a></li>
              <li><a>Drop Option 3</a></li>
              <li><a>Drop Option 4</a></li>
            </ul>
          </div>
        </td>
      </tr>
    </tbody>
  </table>
</div>

css:

.dropdown-menu {
  overflow-y: visible !important;
  z-index: 999;
  ul {
    overflow-y: visible !important;
  }
  li {
    overflow-y: visible !important;
  }
  li:hover {
    cursor: pointer;
    cursor: hand;
  }
}

.title-element-name {
  color: #FF8200;
  font-weight: bold;
}

.table-responsive {
  z-index: 999;
  overflow-y: auto !important;
}
DjH
  • 1,448
  • 2
  • 22
  • 41
  • top of table means ? – Shubham Jul 18 '17 at 19:05
  • You included it your template. It means it will appear in every row of your table. If you wanted it outside the table, move it outside the scope of your template. – jmag Jul 18 '17 at 19:26
  • @jmag: it's supposed to be in each row. the problem is of dropdown visibility. – DjH Jul 18 '17 at 19:28
  • In that case, consider the height of your dropdown when it is expanded. you need it to pop above the other elements. try including z-index higher than 999 in it when active. – jmag Jul 18 '17 at 19:34
  • Found out the class table-responsive is placed outside the table class. – jmag Jul 18 '17 at 19:48
  • Right. It should be assigned to the tables parent div – DjH Jul 18 '17 at 19:58

4 Answers4

1

I had this problem too. Pretty much every fix I found would break something else. In the end, I ended up making it a dropup button. It was working great until the dropdown list became too large, then it was hiding again so I just put a javascript function to change the top margin everytime the button is pressed (so that you can see everything again).

I had an action button for each row in my table so I had to add another statement that only changes the margin when the top button is pressed. I am not sure if you plan on having multiple action buttons but here is my fix for your initial issue:

https://jsfiddle.net/vndyLy1e/7/

$(document).on('show.bs.dropdown', function(e) {
     if ($(e.relatedTarget).hasClass('queryDropdown')) {
         $('#test').css('padding-top', '90px');
     }
});
$(document).on('hide.bs.dropdown',function (e) {
    if ($(e.relatedTarget).hasClass('queryDropdown')) {
        $('#test').css('padding-top', '25px');
    }
});

If you have multiple action dropdowns, just make sure only the top action dropdown has the id "queryDropdown" class. After that, all the rows below it will have their dropdowns drop up over the other elements in the table so it will look normal.

You can probably add a css animation to make the margin change more smooth.

  • that's an interesting solution... from the looks of things what i initially wanted to do might just not be possible at all. I found another working solution to keep the menu dropping *down* and posted here is well – DjH Jul 18 '17 at 19:38
1

Found a solution in a GitHub issues discussion on this issue here.

Credit to @baltazarqc, @llins and @simon21587.

This is still not really what I was hoping for, but it does at least make the dropdown functional.

Added the pull-right class to my ul.drop-down element. Then used their jQuery solution.

$(function() {
  $('.table-responsive').on('shown.bs.dropdown', function(e) {
    var t = $(this),
      m = $(e.target).find('.dropdown-menu'),
      tb = t.offset().top + t.height(),
      mb = m.offset().top + m.outerHeight(true),
      d = 20; // Space for shadow + scrollbar.   
    if (t[0].scrollWidth > t.innerWidth()) {
      if (mb + d > tb) {
        t.css('padding-bottom', ((mb + d) - tb));
      }
    } else {
      t.css('overflow', 'visible');
    }
  }).on('hidden.bs.dropdown', function() {
    $(this).css({
      'padding-bottom': '',
      'overflow': ''
    });
  });
});

Working fiddle here.

DjH
  • 1,448
  • 2
  • 22
  • 41
0

The class table-responsive is place in div seperated from the class table.

 <div class="table-responsive">

Placing them together fixes the issue.

<table class="table table-responsive table-striped table-condensed" >

.dropdown-menu {
  overflow-y: visible !important;
  z-index: 999;
 left:-80px !important;
 }
  ul {
    overflow-y: visible !important;
  }
  li {
    overflow-y: visible !important;
  }
  li:hover {
    cursor: pointer;
    cursor: hand;
  }

.title-element-name {
  color: #FF8200;
  font-weight: bold;
}

.table-responsive {
  z-index: 999;
  overflow-y: auto !important;
}

.title-element-name {
  color: #FF8200;
  font-weight: bold;
}

.table-responsive {
  z-index: 999;
  overflow-y: auto !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div >
  <table class="table table-responsive table-striped table-condensed" >
    <thead>
      <tr>
        <th class="col-xs-2 col-md-3">Col 1</th>
        <th class="col-xs-1 col-md-2">Col 2</th>
        <th class="col-xs-1 col-md-2">Col 3</th>
        <th class="col-xs-1 col-md-2">Col 4</th>
        <th class="col-xs-1 col-md-1">Col 5</th>
        <th class="col-xs-1 col-md-1">Col 6</th>
        <th class="col-xs-1 col-md-1"> </th>
            
    </thead>
    <tbody class="table-body">
      <tr>
        <td>$Col 1 Data</td>
        <td>$Col 2 Data</td>
        <td>$Col 3 Data</td>
        <td>$Col 4 Data</td>
        <td>$Col 4 Data</td>
        <td>$Col 5 Data</td>
        <td> <div class="btn-group">
            <button type="button" class="btn btn-default btn-transparent btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
              <span class="title-element-name">Actions </span><span class="caret"></span>
            </button>
            <ul class="dropdown-menu">
              <li><a>Drop Option 1</a></li>
              <li><a>Drop Option 2</a></li>
              <li><a>Drop Option 3</a></li>
              <li><a>Drop Option 4</a></li>
            </ul>
            </div>
            </td>
      </tr>
    </tbody>
  </table>
</div>
jmag
  • 796
  • 1
  • 8
  • 17
  • 1
    can't scroll horizontally with that. basically removes the functionality of the table being 'responsive'. this may work for others, but for my use case the columns contain too much data to compacted like that – DjH Jul 18 '17 at 19:52
  • @DjH I think you are referring to Bootstrap's dropdown-menu's properties. The is nothing I can do about it unless you want to move it so it will align on its right edge by altering left:0 to left:-80px; – jmag Jul 18 '17 at 20:30
  • I have added the left:-80px in the code snippet. See if that works for you. – jmag Jul 18 '17 at 20:34
0

The most easy way is to setting min-height to <div> which has table-responsive as height as dropdown-menu.