web-dev-qa-db-fra.com

La liste déroulante du bouton Bootstrap dans la table sensible n'est pas visible à cause du défilement

J'ai un problème avec les boutons déroulants dans les tables lorsque sont réactifs et de défilement actif, car la liste déroulante n'est pas visible en raison de la propriété overflow: auto;. Comment puis-je résoudre ce problème afin d'afficher l'option de menu déroulant lorsque cela est réduit? Je peux utiliser un peu de jQuery mais après avoir eu des problèmes avec le défilement gauche-droite, j’ai donc décidé de trouver une autre solution ..__ J'ai joint une photo pour mieux comprendre.enter image description here

Voici un petit violon en js:

59
BurebistaRuler

J'ai moi-même résolu le problème et mis la réponse à la portée des autres utilisateurs ayant le même problème: nous avons un événement dans le bootstrap et nous pouvons utiliser cet événement pour définir overflow: inherited, mais cela fonctionnera si vous n'avez pas la propriété css sur votre parent. récipient.

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

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

et c'est le violon

info: Dans cet exemple de violon fonctionne de manière étrange et je ne suis pas sûr de savoir pourquoi mais dans mon projet fonctionne très bien.

50
BurebistaRuler

Une solution CSS uniquement consiste à autoriser le débordement de l'axe des ordonnées.

http://www.bootply.com/YvePJTDzI0

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

MODIFIER

Une autre solution CSS uniquement consiste à appliquer le débordement en fonction de la largeur de la fenêtre d'affichage: 

@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

36
Zim

J'avais adopté une approche différente, j'avais détaché l'élément du parent et l'avais défini avec position absolute par jQuery

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

 enter image description here

La solution JS que j'utilise. 

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

Cette solution a très bien fonctionné pour moi:

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

Plus de détails: https://github.com/twbs/bootstrap/issues/15374

11
pcuong

J'ai une solution utilisant uniquement CSS, il suffit d'utiliser position relative pour les menus déroulants à l'intérieur de la table sensible:

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

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

9
Leo Caseiro

ma solution globale rapide de 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);
  })
})();

Explications: Lorsqu'un menu déroulant à l'intérieur d'un '.table-responsive' est affiché, il calcule la hauteur du tableau et le développe (avec un remplissage) pour correspondre à la hauteur requise pour afficher le menu. Le menu peut être n'importe quelle taille.

Dans mon cas, ce n'est pas la table qui a la classe '.table-responsive', c'est une div d'habillage:

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

Donc, la variable $ table dans le script est en fait une div! (juste pour être clair ... ou pas) :)

Remarque: je l'enveloppe dans une fonction afin que mon IDE puisse réduire sa fonction;) mais ce n'est pas obligatoire!

8
BaltazarQc

Pour référence, nous sommes en 2018 et j'utilise BS4.1

Essayez d’ajouter data-boundary="viewport" au bouton qui fait basculer la liste déroulante (celle avec la classe dropdown-toggle). Voir https://getbootstrap.com/docs/4.1/components/dropdowns/#options

5
Ben

La solution recommandée et choisie n'est pas toujours la meilleure solution. Malheureusement, c’est la solution récemment utilisée par LinkedIn et elle crée plusieurs barres de défilement sur la page en fonction de la situation. 

Ma méthode était légèrement différente. 

J'ai contenu la div table-responsive dans une autre div. Ensuite, j'ai appliqué hauteur 100%, largeur: 100%, bloc d'affichage et position absolue afin que la hauteur et la largeur soient basées sur la taille de la page et que le dépassement de capacité soit masqué. 

Puis sur la table sensible div j'ai ajouté une hauteur minimum de 100%

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

Comme vous pouvez le voir dans l'exemple de travail ci-dessous, aucune barre de défilement ajoutée, aucun comportement amusant et pratiquement son pourcentage d'utilisation - cela devrait fonctionner quelle que soit la taille de l'écran. Je n'ai pas testé cela pour cela cependant. Si cela échoue pour une raison quelconque, on peut remplacer 100% par 100vh et 100vw respectivement.

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

2
Bruce

Nettoyé la solution @Wazime un peu. Fonctionne très bien comme solution générale.

$(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');
});
1
quakes

Cela pourrait être utile pour quelqu'un d'autre. J'utilise DatatablesJS. J'ajoute 500 pixels à la hauteur actuelle de la table. Je le fais parce que les bases de données vous permettent d’utiliser 10, 20, etc. pages dans votre tableau. J'ai donc besoin de calculer dinamiquement la hauteur de la table. 
Lorsque la liste déroulante est affichée, j'ajoute une hauteur supplémentaire.
Lorsque la liste déroulante est masquée, je réinitialise la hauteur de la table d'origine.

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

Et le HTML

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

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

Avant:  enter image description here

Après le menu déroulant est affiché:  enter image description here

0
miguel.angel

Cela a fonctionné pour moi dans Bootstrap 4 car il a des points d'arrêt différents de ceux de la v3:

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

La réponse de Burebista Ruler fonctionne correctement pour moi sur ios8 (iphone 4s), mais ne fonctionne pas sous Android qui auparavant fonctionnait auparavant .

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

Utilisez simplement ceci

.table-responsive {
    overflow: inherit;
}

Cela fonctionne sur Chrome, mais pas sur IE10 ou Edge, car la propriété inherit n'est pas prise en charge.

0
Deepak swain

Définissez ces propriétés. Bonne chance!

data-toggle="dropdown" data-boundary="window"
0
Halit Yeşil

Sur la base de la réponse acceptée et de la réponse de @LeoCaseiro, voici ce que j’ai fini par utiliser dans mon cas:

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

sur les grands écrans, le menu déroulant ne sera pas caché derrière la table des messages et dans le petit écran, il sera masqué, mais c'est correct car il y a une barre de défilement dans le mobile.

J'espère que cela aidera quelqu'un.

0
medBouzid

Nous avons résolu ce problème ici au travail en appliquant une classe .dropup à la liste déroulante lorsque celle-ci se situe près du bas d'un tableau. entrez la description de l'image ici

0
roshin jose