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:

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.


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


@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


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');
    }
});

1
Ta odpowiedź jest dla mnie idealną poprawką podczas używania jquery datatable (ajax render). Odpowiednio dostosowałem i działa świetnie.


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!


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/


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


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': ''});
});

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');
});

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>


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.


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" );
})

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


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


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;
    }
}

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;
}

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.


-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%;
}

-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


-1

W moim przypadku to działa dobrze:

.table-responsive {
  overflow-y: visible !important;
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.