Il menu a discesa del pulsante Bootstrap all'interno della tabella reattiva non è visibile a causa dello scorrimento


88

Ho un problema con i pulsanti a discesa all'interno delle tabelle quando sono reattivi e lo scorrimento è attivo perché il menu a discesa non è visibile a causa della overflow: auto;proprietà. Come posso risolverlo per mostrare l'opzione a discesa del pulsante quando questo è compresso? Posso usare un po 'di jQuery ma dopo aver avuto problemi con lo scorrimento da sinistra a destra ho deciso di trovare un'altra soluzione. Ho allegato una foto per capire meglio.inserisci qui la descrizione dell'immagine

Ecco un piccolo violino js:

Risposte:


60

L'ho risolto da solo e ho messo la risposta nello scopo di aiutare altri utenti che hanno lo stesso problema: abbiamo un evento in bootstrap e possiamo usare quell'evento per impostarlo overflow: inheritma funzionerà se non hai la proprietà css sul tuo genitore contenitore.

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

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

e questo è il violino

info: In questo esempio di violino funziona in modo strano e non sono sicuro del perché, ma nel mio progetto funziona bene.


3
Funziona solo per le tabelle con un menu a discesa nella prima cella della riga.
Almino Melo

6
in caso di tabella caricata dinamica: $('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
Ma dopo il clic i dati escono dalla dimensione minima dello schermo. Quindi questo non funziona. !!!!
Shreya Shah

1
Ciò funzionerebbe se potessi impedire alla tabella di scorrere indietro a sinistra quando viene aperto il menu a discesa. Ma così com'è, se hai un menu a discesa a destra dello schermo, la tabella scatta a sinistra quando si apre. I menu a discesa che si trovano molto a destra (mascherati dalla .table-responsiveclasse) sono completamente nascosti quando si tenta di modificarli.
Ponyboy

43

Un solo CSS soluzione è quella di consentire l'asse y per troppopieno.

http://www.bootply.com/YvePJTDzI0

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

MODIFICARE

Un'altra soluzione unica per CSS è applicare in modo reattivo l'overflow in base alla larghezza del viewport:

@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 fa ancora la stessa cosa, questa non è fondamentalmente la soluzione.
Jemar Jones

Questa soluzione funziona anche se rimuovi il css personalizzato. Forse è una cosa html. Sto ancora cercando una soluzione solo css.
Fernando

1
No. Non funziona. Immagino sia perché sto usando tabelle di dati
peterchaula

funziona per me tranne che il pulsante è in fondo alla pagina ... quindi il menu a discesa appare fuori dalla finestra ...
Brucie Alpha

34

Per riferimento, è il 2018 e sto usando BS4.1

Prova ad aggiungere data-boundary="viewport"al pulsante che attiva il menu a discesa (quello con la classe dropdown-toggle). Vedi https://getbootstrap.com/docs/4.1/components/dropdowns/#options


4
Confermo che anche questa è una soluzione funzionante che ho trovato.
sdvnksv

4
Non posso parlare delle versioni precedenti, ma per Bootstrap 4 questa è davvero la soluzione migliore. È semplice, non sacrifica la reattività, utilizza funzionalità già fornite nel framework invece di cercare di aggirarlo con stili o script extra.
T. Linnell

16

Avevo adottato un approccio diverso, avevo staccato l'elemento dal genitore e lo avevo impostato con la posizione assoluta di jQuery

JS fidle funzionante: http://jsfiddle.net/s270Lyrd/

inserisci qui la descrizione dell'immagine

La soluzione JS che sto usando.

//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
Questa risposta è una soluzione perfetta per me durante l'utilizzo di jquery datatable (rendering ajax). Mi sono adattato di conseguenza e funziona benissimo.


11

la mia soluzione globale rapida di 2 ¢:

// 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);
  })
})();

Spiegazioni: quando viene mostrato un menu a discesa all'interno di un '.table-responsive', calcola l'altezza della tabella e la espande (con padding) in modo che corrisponda all'altezza richiesta per visualizzare il menu. Il menu può essere di qualsiasi dimensione.

Nel mio caso, questa non è la tabella che ha la classe '.table-responsive', è un div wrapping:

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

Quindi la $ table var nello script è in realtà un div! (giusto per essere chiari ... o no) :)

Nota: lo inserisco in una funzione in modo che il mio IDE possa comprimere la funzione;) ma non è obbligatorio!


2
Questa è l'unica soluzione che ha funzionato per me, ma suggerirei di usare $ table.css ("padding-bottom", menuOffsetHeight - tableOffsetHeight + 16); insetad di $ table.css ("padding-bottom", menuOffsetHeight - tableOffsetHeight); per aggiungere un'imbottitura extra presente sul bootstrap per impostazione predefinita, più un piccolo spazio nella parte inferiore.
Phil Young

Funziona, ma l'imbottitura lo fa sembrare brutto. Vorrei che ci fosse una soluzione che lo facesse funzionare senza il gonfiore dell'imbottitura.
Qasim

bella e semplice soluzione
NMC

11

Ho una soluzione che utilizza solo CSS, usa solo la posizione relativa per i menu a discesa all'interno della tabella reattiva:

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

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


1
questa è la soluzione migliore, la sto usando per ui-select nella mia tabella reattiva.
Sergio Ivanuzzo

Soluzione migliore anche per me
Mauro

2
Questo violino non funziona . Si mantiene nascondere la discesa sotto il tavolo.
HelloIT

@HelloIT prova il codepen (aggiornato) codepen.io/leocaseiro/pen/rKxmpz
Leo Caseiro

1
D'accordo con @hellioIT questo metodo non sembra funzionare nella penna
MrPaulDriver

9

Definisci queste proprietà. In bocca al lupo!

data-toggle="dropdown" data-boundary="window"

3
Solo soluzione Bootstrap 4
nevada_scout

6

Questo è stato risolto in Bootstrap v4.1 e versioni successive aggiungendo data-boundary="viewport"( Bootstrap Dropdowns Docs )

Ma per le versioni precedenti (v4.0 e precedenti), ho trovato questo frammento di javascript che funziona perfettamente. Funziona per piccoli tavoli e tabelle a scorrimento:

$('.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

Soluzione @Wazime ripulita un po '. Funziona alla grande come soluzione generale.

$(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

La soluzione consigliata e scelta, non è sempre la soluzione migliore. Sfortunatamente è la soluzione utilizzata di recente da LinkedIn e crea più barre di scorrimento sulla pagina in base alla situazione.

Il mio metodo era leggermente diverso.

Ho contenuto il div che risponde alla tabella in un altro div. Quindi ho applicato l'altezza 100%, la larghezza: 100%, il blocco di visualizzazione e la posizione assoluta in modo che l'altezza e la larghezza siano basate sulle dimensioni della pagina e impostato l'overflow su nascosto.

Quindi sul div responsivo del tavolo ho aggiunto un'altezza minima del 100%

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

Come puoi vedere nell'esempio di lavoro qui sotto, nessuna barra di scorrimento aggiunta, nessun comportamento divertente e praticamente come le percentuali di utilizzo - dovrebbe funzionare indipendentemente dalle dimensioni dello schermo. Tuttavia, non l'ho provato per quello. Se ciò fallisce per qualche motivo, è possibile sostituire il 100% con 100vh e 100vw rispettivamente.

<!-- 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>


Non è una soluzione per un'altezza di visualizzazione ridotta. I link a discesa inferiori non sono più raggiungibili a causa di fuori vista.
Seika85

1

Sulla base della risposta accettata e della risposta di @LeoCaseiro ecco cosa ho finito per usare nel mio caso:

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

sugli schermi grandi il menu a discesa non sarà nascosto dietro la tabella di risposta e sullo schermo piccolo sarà nascosto ma va bene perché c'è comunque la barra di scorrimento nel cellulare.

Spero che questo aiuti qualcuno.


0

La risposta di Burebistaruler funziona bene per me su ios8 (iphone4s) ma non funziona su Android che prima funzionava. Quello che ho donne che funziona per me su ios8 (iphone4s) e andoir è:

$('.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

Questo potrebbe essere utile per qualcun altro. Sto usando DatatablesJS. Aggiungo 500px all'altezza attuale del tavolo. Lo faccio perché i Datatables ti consentono di utilizzare 10, 20, ecc. Pagine nella tua tabella. Quindi devo calcolare dinamicamente l'altezza del tavolo.
Quando viene visualizzato il menu a discesa, aggiungo un'altezza extra.
Quando il menu a discesa è nascosto, ripristino l'altezza della tabella originale.

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

E l'HTML

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

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

Prima: inserisci qui la descrizione dell'immagine

Dopo che viene visualizzato il menu a discesa: inserisci qui la descrizione dell'immagine


0

Abbiamo risolto questo problema qui al lavoro applicando una classe .dropup al menu a discesa quando il menu a discesa è vicino alla fine di una tabella. inserisci qui la descrizione dell'immagine


Alla fine sono molto contento di quella soluzione. $('table tr:nth-last-child(-n+3) td').addClass('dropup').
Furgas

0

Questo ha funzionato per me in Bootstrap 4 poiché ha diversi punti di interruzione rispetto alla v3:

@media (min-width: 992px) {
    .table-responsive {
        overflow: inherit;
    }
}

0

Finché le persone sono ancora bloccate su questo problema e siamo già nel 2020. Ottengo una soluzione CSS pura dando al menu a discesa una visualizzazione flessibile

questo snippet funziona alla grande con la datatable-scroll-wrapclasse

.datatable-scroll-wrap .dropdown.dropup.open .dropdown-menu {
    display: flex;
}
.datatable-scroll-wrap .dropdown.dropup.open .dropdown-menu li a {
    display: flex;
}

0

Bene, leggendo la risposta in alto, ho visto che non funziona davvero quando vedi la barra di scorrimento e il pulsante di attivazione / disattivazione era sull'ultima colonna (nel mio caso) o su un'altra colonna che non è stata vista

pic-error

Ma, se cambi "inherit" in "nascosto", funzionerà.

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

inserisci qui la descrizione dell'immagine

Prova a farlo in questo modo.


0

Provalo una volta. dopo 1 ora di ricerca in rete ho trovato la migliore soluzione per questo problema.

Soluzione: basta aggiungere lo script

(function () {
    // hold onto the drop down menu                                             
    var dropdownMenu;

    // and when you show it, move it to the body                                     
    $(window).on('show.bs.dropdown', function (e) {

    // grab the menu        
    dropdownMenu = $(e.target).find('.dropdown-menu');

    // detach it and append it to the body
    $('body').append(dropdownMenu.detach());

    // grab the new offset position
    var eOffset = $(e.target).offset();

    // make sure to place it where it would normally go (this could be improved)
    dropdownMenu.css({
        'display': 'block',
            'top': eOffset.top + $(e.target).outerHeight(),
            'left': eOffset.left
       });
    });

    // and when you hide it, reattach the drop down, and hide it normally                                                   
    $(window).on('hide.bs.dropdown', function (e) {
        $(e.target).append(dropdownMenu.detach());
        dropdownMenu.hide();
    });
})();

PRODUZIONE:- Soluzione


-1

All'interno di bootstrap.css cerca il codice successivo:

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

... e aggiorna con questo:

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

-1

Usa semplicemente questo

.table-responsive {
    overflow: inherit;
}

Funziona su Chrome, ma non su IE10 o Edge perché la proprietà inherit non è supportata


-1

Nel mio caso, funziona bene:

.table-responsive {
  overflow-y: visible !important;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.