Rozwijany przycisk Bootstrap wewnątrz responsywnej tabeli nie jest widoczny z powodu przewijania

86

Mam problem z przyciskami rozwijanymi wewnątrz tabel, gdy są responsywne i aktywne, ponieważ lista rozwijana nie jest widoczna z powodu overflow: auto;właściwości. Jak mogę to naprawić, aby wyświetlić rozwijaną opcję przycisku, gdy ta jest zwinięta? Mogę użyć jQuery, ale po problemach z przewijaniem w lewo-w prawo postanowiłem znaleźć inne rozwiązanie. Załączam zdjęcie, aby lepiej zrozumieć.wprowadź opis obrazu tutaj

Oto małe skrzypce js:

BurebistaRuler
źródło

Odpowiedzi:

60

Rozwiązałem to sam i umieściłem odpowiedź w zakresie, aby pomóc innemu użytkownikowi, który ma ten sam problem: Mamy zdarzenie w bootstrapie i możemy użyć tego zdarzenia do ustawienia, overflow: inheritale to zadziała, jeśli nie masz właściwości css na swoim rodzicu pojemnik.

$('.table-responsive').on('show.bs.dropdown', function () {
     $('.table-responsive').css( "overflow", "inherit" );
});

$('.table-responsive').on('hide.bs.dropdown', function () {
     $('.table-responsive').css( "overflow", "auto" );
})

a to jest skrzypce

info: W tym przykładzie skrzypcowym działa dziwnie i nie jestem pewien dlaczego, ale w moim projekcie działa dobrze.

BurebistaRuler
źródło
3
Działa to tylko w przypadku tabel z listą rozwijaną w pierwszej komórce wiersza.
Almino Melo
6
w przypadku dynamicznie załadowanej tabeli: $('body') .on('show.bs.dropdown', '.table-responsive', function () { $(this).css("overflow", "visible"); }) .on('hide.bs.dropdown', '.table-responsive', function () { $(this).css("overflow", "auto"); });
Exlord
4
Ale po kliknięciu dane wykraczają poza minimalny rozmiar ekranu. Więc to nie działa. !!!!
Shreya Shah
1
To zadziałałoby, gdybyś mógł zatrzymać przewijanie tabeli z powrotem w lewo po otwarciu listy rozwijanej. Ale tak jak jest, jeśli masz listę rozwijaną po prawej stronie ekranu, stół szarpie się w lewo podczas otwierania. Listy rozwijane, które znajdują się daleko w prawo (zasłonięte przez .table-responsiveklasę) są całkowicie ukryte podczas próby ich edycji.
Ponyboy
43

Tylko CSS rozwiązaniem jest, aby oś y przepełnienia.

http://www.bootply.com/YvePJTDzI0

.table-responsive {
  overflow-y: visible !important;
}

EDYTOWAĆ

Innym rozwiązaniem tylko w CSS jest responsywne zastosowanie przepełnienia na podstawie szerokości widocznego obszaru:

@media (max-width: 767px) {
    .table-responsive .dropdown-menu {
        position: static !important;
    }
}
@media (min-width: 768px) {
    .table-responsive {
        overflow: inherit;
    }
}

https://www.codeply.com/go/D3XBvspns4

Zim
źródło
@ZimSystem Wciąż robi to samo, to zasadniczo nie jest rozwiązaniem.
Jemar Jones
To rozwiązanie działa nawet po usunięciu niestandardowego pliku CSS. Może to kwestia HTML. Nadal szukam rozwiązania tylko dla CSS.
fernandodof
1
Nie. Nie działa. Myślę, że to dlatego, że używam tabel danych
peterchaula
u mnie działa poza tym, że przycisk jest na dole strony ... wtedy rozwijane menu pojawia się za oknem ...
Brucie Alpha
31

Dla porównania, jest rok 2018 i używam BS4.1

Spróbuj dodać data-boundary="viewport"do przycisku, który przełącza menu rozwijane (ten z klasą dropdown-toggle). Zobacz https://getbootstrap.com/docs/4.1/components/dropdowns/#options

Ben
źródło
4
Potwierdzam, że jest to działające rozwiązanie, które również wymyśliłem.
sdvnksv
4
Nie mogę mówić o wcześniejszych wersjach, ale w przypadku Bootstrap 4 jest to naprawdę najlepsze rozwiązanie. Jest prosty, nie rezygnuje z responsywności, wykorzystuje funkcjonalność, która jest już dostarczona we frameworku, zamiast próbować włamać się do niego za pomocą dodatkowych stylów lub skryptów.
T. Linnell
16

Zrobiłem inne podejście, odłączyłem element od rodzica i ustawiłem go na pozycję bezwzględną przez jQuery

Działające skrzypce JS: http://jsfiddle.net/s270Lyrd/

wprowadź opis obrazu tutaj

Rozwiązanie JS, którego używam.

//fix menu overflow under the responsive table 
// hide menu on click... (This is a must because when we open a menu )
$(document).click(function (event) {
    //hide all our dropdowns
    $('.dropdown-menu[data-parent]').hide();

});
$(document).on('click', '.table-responsive [data-toggle="dropdown"]', function () {
    // if the button is inside a modal
    if ($('body').hasClass('modal-open')) {
        throw new Error("This solution is not working inside a responsive table inside a modal, you need to find out a way to calculate the modal Z-index and add it to the element")
        return true;
    }

    $buttonGroup = $(this).parent();
    if (!$buttonGroup.attr('data-attachedUl')) {
        var ts = +new Date;
        $ul = $(this).siblings('ul');
        $ul.attr('data-parent', ts);
        $buttonGroup.attr('data-attachedUl', ts);
        $(window).resize(function () {
            $ul.css('display', 'none').data('top');
        });
    } else {
        $ul = $('[data-parent=' + $buttonGroup.attr('data-attachedUl') + ']');
    }
    if (!$buttonGroup.hasClass('open')) {
        $ul.css('display', 'none');
        return;
    }
    dropDownFixPosition($(this).parent(), $ul);
    function dropDownFixPosition(button, dropdown) {
        var dropDownTop = button.offset().top + button.outerHeight();
        dropdown.css('top', dropDownTop + "px");
        dropdown.css('left', button.offset().left + "px");
        dropdown.css('position', "absolute");

        dropdown.css('width', dropdown.width());
        dropdown.css('heigt', dropdown.height());
        dropdown.css('display', 'block');
        dropdown.appendTo('body');
    }
});
Wazime
źródło
1
Ta odpowiedź jest dla mnie idealną poprawką podczas używania jquery datatable (ajax render). Odpowiednio dostosowałem i działa świetnie.
13

To rozwiązanie zadziałało dla mnie świetnie:

@media (max-width: 767px) {
    .table-responsive .dropdown-menu {
        position: static !important;
    }
}
@media (min-width: 768px) {
    .table-responsive {
        overflow: visible;
    }
}

Więcej szczegółów: https://github.com/twbs/bootstrap/issues/15374

pham cuong
źródło
11

moja szybka globalna poprawka w wysokości 2 centów:

// drop down in responsive table

(function () {
  $('.table-responsive').on('shown.bs.dropdown', function (e) {
    var $table = $(this),
        $menu = $(e.target).find('.dropdown-menu'),
        tableOffsetHeight = $table.offset().top + $table.height(),
        menuOffsetHeight = $menu.offset().top + $menu.outerHeight(true);

    if (menuOffsetHeight > tableOffsetHeight)
      $table.css("padding-bottom", menuOffsetHeight - tableOffsetHeight);
  });

  $('.table-responsive').on('hide.bs.dropdown', function () {
    $(this).css("padding-bottom", 0);
  })
})();

Objaśnienia: Kiedy wyświetlane jest rozwijane menu wewnątrz „.table-responsive”, oblicza on wysokość tabeli i rozwija ją (z dopełnieniem), aby dopasować ją do wysokości wymaganej do wyświetlenia menu. Menu może mieć dowolną wielkość.

W moim przypadku to nie jest tabela, która ma klasę „.table-responsive”, jest to zawijający element div:

<div class="table-responsive" style="overflow:auto;">
    <table class="table table-hover table-bordered table-condensed server-sort">

Więc $ table var w skrypcie jest w rzeczywistości div! (żeby było jasne ... albo nie) :)

Uwaga: zawijam go w funkcję, aby moje IDE mogło zwinąć funkcję;), ale nie jest to obowiązkowe!

BaltazarQc
źródło
2
To jedyne rozwiązanie, które działało w moim przypadku, ale sugerowałbym użycie $ table.css ("padding-bottom", menuOffsetHeight - tableOffsetHeight + 16); insetad of $ table.css ("padding-bottom", menuOffsetHeight - tableOffsetHeight); aby dodać dodatkowe wypełnienie, które jest domyślnie na bootstrapie, plus małą przerwę na dole.
Phil Young
To działa, ale wyściółka sprawia, że ​​wygląda źle. Żałuję, że nie było rozwiązania, które sprawiłoby, że działałoby bez wzdęcia wypełnienia.
Qasim
ładne i proste rozwiązanie
NMC
11

Mam rozwiązanie wykorzystujące tylko CSS, po prostu użyj pozycji względnej dla rozwijanych menu wewnątrz tabeli responsywnej:

@media (max-width: 767px) {
  .table-responsive .dropdown-menu {
    position: relative; /* Sometimes needs !important */
  }
}

https://codepen.io/leocaseiro/full/rKxmpz/

Leo Caseiro
źródło
1
to jest najlepsze rozwiązanie, używam go do ui-select w mojej responsywnej tabeli.
Sergio Ivanuzzo,
Najlepsze rozwiązanie również dla mnie
Mauro
2
To skrzypce nie działa . To wciąż ukrywa listę rozwijaną pod stołem.
HelloIT
@HelloIT wypróbuj codepen (zaktualizowany) codepen.io/leocaseiro/pen/rKxmpz
Leo Caseiro
1
Zgadzam się z @hellioIT ta metoda wydaje się nie działać w piórze
MrPaulDriver
9

Zdefiniuj te właściwości. Powodzenia!

data-toggle="dropdown" data-boundary="window"
Halit Yeşil
źródło
3
Tylko rozwiązanie Bootstrap 4
nevada_scout
5

Zostało to naprawione w Bootstrap v4.1 i nowszych poprzez dodanie data-boundary="viewport"( Bootstrap Dropdowns Docs )

Ale w przypadku wcześniejszych wersji (v4.0 i poniżej) znalazłem ten fragment kodu javascript, który działa idealnie. Działa dla małych tabel i przewijanych tabel:

$('.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': ''});
});
Cyrus V.
źródło
4

Trochę wyczyszczono rozwiązanie @Wazime. Świetnie sprawdza się jako rozwiązanie ogólne.

$(document).on('shown.bs.dropdown', '.table-responsive', function (e) {
    // The .dropdown container
    var $container = $(e.target);

    // Find the actual .dropdown-menu
    var $dropdown = $container.find('.dropdown-menu');
    if ($dropdown.length) {
        // Save a reference to it, so we can find it after we've attached it to the body
        $container.data('dropdown-menu', $dropdown);
    } else {
        $dropdown = $container.data('dropdown-menu');
    }

    $dropdown.css('top', ($container.offset().top + $container.outerHeight()) + 'px');
    $dropdown.css('left', $container.offset().left + 'px');
    $dropdown.css('position', 'absolute');
    $dropdown.css('display', 'block');
    $dropdown.appendTo('body');
});

$(document).on('hide.bs.dropdown', '.table-responsive', function (e) {
    // Hide the dropdown menu bound to this button
    $(e.target).data('dropdown-menu').css('display', 'none');
});
trzęsienia się
źródło
2

Zalecane i wybrane rozwiązanie nie zawsze jest najlepszym rozwiązaniem. Niestety jest to ostatnio używane rozwiązanie, które w serwisie linkedin tworzy wiele pasków przewijania na stronie w zależności od sytuacji.

Moja metoda była nieco inna.

Umieściłem element div odpowiadający tabeli w innym elemencie div. Następnie zastosowałem wysokość 100%, szerokość: 100%, blok wyświetlania i położenie bezwzględne, więc wysokość i szerokość zależą od rozmiaru strony i ustawiłem przepełnienie na ukryte.

Następnie na tabeli responsywnej div dodałem min-height 100%

<div class="table_container" 
    style="height: 100%; width: 100%; display: block;position: absolute;overflow: hidden;">
<div class="table-responsive" style="min-height:100%;">

Jak widać na poniższym przykładzie roboczym, bez dodanych pasków przewijania, bez zabawnego zachowania, a praktycznie jako użycie procentów - powinno działać niezależnie od rozmiaru ekranu. Jednak nie testowałem tego. Jeśli z jakiegoś powodu to się nie powiedzie, można zastąpić 100% odpowiednio 100vh i 100vw.

<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">

<!-- Optional theme -->
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">

            <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>


<div class="table_container" style="height: 100%; width: 100%; display: block;position: absolute;overflow: hidden;">
<div class="table-responsive" style="min-height:100%;">
                <table class="table">
                    <thead>
                        <tr>
                            <th>Value1</th>
                            <th>Value2</th>
                            <th>Value3</th>
                            <th>Value4</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>
                                DATA
                                <div class="btn-group btn-group-rounded">
                                    <button type="button" class="btn btn-default btn-xs" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="border-radius:3px;">
                                        <span class="caret"></span>
                                    </button>
                                    <ul class="dropdown-menu">
                                        <li><a href="#">One</a></li>
                                        <li><a href="#">Two</a></li>
                                        <li><a href="#">Three</a></li>
                                        <li role="seperator" class="divider"></li>
                                        <li><a href="#">Four</a></li>
                                    </ul>
                                </div>
                            </td>

                            <td>
                                DATA
                                <div class="btn-group btn-group-rounded">
                                    <button type="button" class="btn btn-default btn-xs" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="border-radius:3px;">
                                        <span class="caret"></span>
                                    </button>
                                    <ul class="dropdown-menu">
                                        <li><a href="#">One</a></li>
                                        <li><a href="#">Two</a></li>
                                        <li><a href="#">Three</a></li>
                                        <li role="seperator" class="divider"></li>
                                        <li><a href="#">Four</a></li>
                                    </ul>
                                </div>
                            </td>
                            <td>
                                DATA
                                <div class="btn-group btn-group-rounded">
                                    <button type="button" class="btn btn-default btn-xs" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="border-radius:3px;">
                                        <span class="caret"></span>
                                    </button>
                                    <ul class="dropdown-menu">
                                        <li><a href="#">One</a></li>
                                        <li><a href="#">Two</a></li>
                                        <li><a href="#">Three</a></li>
                                        <li role="seperator" class="divider"></li>
                                        <li><a href="#">Four</a></li>
                                    </ul>
                                </div>
                            </td>
                            <td>DATA</td>
                        </tr>
                        <tr>
                            <td>
                                DATA
                                <div class="btn-group btn-group-rounded">
                                    <button type="button" class="btn btn-default btn-xs" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="border-radius:3px;">
                                        <span class="caret"></span>
                                    </button>
                                    <ul class="dropdown-menu">
                                        <li><a href="#">One</a></li>
                                        <li><a href="#">Two</a></li>
                                        <li><a href="#">Three</a></li>
                                        <li role="seperator" class="divider"></li>
                                        <li><a href="#">Four</a></li>                                    </ul>
                                </div>
                            </td>

                            <td>
                                DATA
                                <div class="btn-group btn-group-rounded">
                                    <button type="button" class="btn btn-default btn-xs" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="border-radius:3px;">
                                        <span class="caret"></span>
                                    </button>
                                    <ul class="dropdown-menu">
                                        <li><a href="#">One</a></li>
                                        <li><a href="#">Two</a></li>
                                        <li><a href="#">Three</a></li>
                                        <li role="seperator" class="divider"></li>
                                        <li><a href="#">Four</a></li>
                                    </ul>
                                </div>
                            </td>
                            <td>
                                DATA
                                <div class="btn-group btn-group-rounded">
                                    <button type="button" class="btn btn-default btn-xs" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="border-radius:3px;">
                                        <span class="caret"></span>
                                    </button>
                                    <ul class="dropdown-menu">
                                        <li><a href="#">One</a></li>
                                        <li><a href="#">Two</a></li>
                                        <li><a href="#">Three</a></li>
                                        <li role="seperator" class="divider"></li>
                                        <li><a href="#">Four</a></li>
                                    </ul>
                                </div>
                            </td>
                            <td>DATA</td>
                        </tr>
                    </tbody>
                </table>
            </div>
</div>

Bruce
źródło
Nie jest to rozwiązanie dla mniejszej wysokości widoku. Dolne linki rozwijane stają się niedostępne z powodu niewidoczności.
Seika85,
1

Na podstawie zaakceptowanej odpowiedzi i odpowiedzi @LeoCaseiro oto, co ostatecznie wykorzystałem w moim przypadku:

@media (max-width: 767px) {
    .table-responsive{
        overflow-x: auto;
        overflow-y: auto;
    }
}
@media (min-width: 767px) {
    .table-responsive{
        overflow: inherit !important; /* Sometimes needs !important */
    }
}

na dużych ekranach lista rozwijana nie będzie ukryta za stołem odpowiadającym, a na małym ekranie będzie ukryta, ale jest w porządku, ponieważ i tak jest pasek przewijania w telefonie komórkowym.

Mam nadzieję, że to komuś pomoże.

medBouzid
źródło
0

Odpowiedź Burebistaruler działa dla mnie dobrze na ios8 (iphone4s), ale nie działa na Androidzie, który wcześniej działał. To, co mam, co działa dla mnie na iOS8 (iPhone4s) i Andoir, to:

$('.table-responsive').on('show.bs.dropdown', function () {
 $('.table-responsive').css( "min-height", "400px" );
});

$('.table-responsive').on('hide.bs.dropdown', function () {
     $('.table-responsive').css( "min-height", "none" );
})
Oscar Jofre
źródło
0

Może to być przydatne dla kogoś innego. Używam DatatablesJS. Do aktualnej wysokości stołu dodaję 500px. Robię to, ponieważ zbiory danych pozwalają na użycie 10, 20 itd. Stron w tabeli. Muszę więc ręcznie obliczyć wysokość stołu.
Po wyświetleniu listy rozwijanej dodaję dodatkową wysokość.
Gdy lista rozwijana jest ukryta, resetuję oryginalną wysokość stołu.

$(document).ready(function() {
    $('.table-responsive .dropdown').on('shown.bs.dropdown', function () {
          console.log($('#table-responsive-cliente').height() + 500)
          $("#table-responsive-cliente").css("height",$('#table-responsive-cliente').height() + 500 );
    })

    $('.table-responsive .dropdown').on('hide.bs.dropdown', function () {
           $("#table-responsive-cliente").css("height","auto");
    })
})

I HTML

<div class="table-responsive" id="table-responsive-cliente">
    <table class="table-striped table-hover">
     ....

     ....
    </table>
</div>

Przed: wprowadź opis obrazu tutaj

Po wyświetleniu listy rozwijanej: wprowadź opis obrazu tutaj

Miguel angel
źródło
0

Rozwiązaliśmy ten problem tutaj, w pracy, stosując klasę .dropup do listy rozwijanej, gdy lista znajduje się blisko dołu tabeli. wprowadź opis obrazu tutaj

roshin jose
źródło
Ostatecznie najbardziej jestem zadowolony z tego rozwiązania. $('table tr:nth-last-child(-n+3) td').addClass('dropup').
Furgas
0

To zadziałało dla mnie w Bootstrap 4, ponieważ ma inne punkty przerwania niż v3:

@media (min-width: 992px) {
    .table-responsive {
        overflow: inherit;
    }
}
ar31an
źródło
0

O ile ludzie wciąż tkwią w tej kwestii i jesteśmy już w 2020 roku. Otrzymuję czyste rozwiązanie CSS, dając menu rozwijanemu elastyczny wyświetlacz

ten fragment działa świetnie z datatable-scroll-wrapklasą

.datatable-scroll-wrap .dropdown.dropup.open .dropdown-menu {
    display: flex;
}
.datatable-scroll-wrap .dropdown.dropup.open .dropdown-menu li a {
    display: flex;
}
hassan
źródło
0

Cóż, czytając najwyższą odpowiedź, zobaczyłem, że to naprawdę nie działa, gdy widzisz pasek przewijania, a przycisk przełączania był w ostatniej kolumnie (w moim przypadku) lub innej niewidocznej kolumnie

pic-error

Ale jeśli zmienisz „dziedziczenie” na „ukryte”, to zadziała.

$('.table-responsive').on('show.bs.dropdown', function () {
    $('.table-responsive').css( "overflow", "hidden" );
}).on('hide.bs.dropdown', function () {
    $('.table-responsive').css( "overflow", "auto" );
})

wprowadź opis obrazu tutaj

Spróbuj zrobić w ten sposób.

Luís Gustavo Batista
źródło
-1

Wewnątrz pliku bootstrap.css wyszukaj następny kod:

.fixed-table-body {
  overflow-x: auto;
  overflow-y: auto;
  height: 100%;
}

... i zaktualizuj za pomocą tego:

.fixed-table-body {
  overflow-x: visible;
  overflow-y: visible;
  height: 100%;
}
Cesar
źródło
-1

Po prostu użyj tego

.table-responsive {
    overflow: inherit;
}

Działa w przeglądarce Chrome, ale nie IE10 ani Edge, ponieważ dziedziczenie nie jest obsługiwane

Deepak Swain
źródło
-1

W moim przypadku to działa dobrze:

.table-responsive {
  overflow-y: visible !important;
}
Hamid
źródło