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.