javascript - desplegable - dropdown menu bootstrap
El menú desplegable del botón Bootstrap dentro de la tabla receptiva no está visible debido al desplazamiento (16)
Basado en la respuesta aceptada y la respuesta de @LeoCaseiro, aquí está lo que terminé usando en mi 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 */
}
}
en las pantallas grandes, el menú desplegable no estará oculto detrás de la mesa sensible y en la pantalla pequeña estará oculto, pero está bien porque de todos modos hay una barra de desplazamiento en el móvil.
Espero que esto ayude a alguien.
Tengo un problema con los botones desplegables dentro de las tablas cuando son receptivos y se desplazan activos porque el menú desplegable no está visible debido al overflow: auto;
propiedad. ¿Cómo puedo arreglar eso para mostrar la opción desplegable del botón cuando este está contraído? Puedo usar jQuery pero después de tener problemas con el scroll de izquierda a derecha, decidí buscar otra solución. He adjuntado una foto para entender mejor.
Como referencia, es 2018 y estoy usando BS4.1
Intente agregar data-boundary="viewport"
al botón que activa el menú desplegable (el que tiene el dropdown-toggle
la clase). Ver https://getbootstrap.com/docs/4.1/components/dropdowns/#options
Dentro de bootstrap.css busca el siguiente código:
.fixed-table-body {
overflow-x: auto;
overflow-y: auto;
height: 100%;
}
... y actualiza con esto:
.fixed-table-body {
overflow-x: visible;
overflow-y: visible;
height: 100%;
}
Esta solución funcionó muy bien para mí:
@media (max-width: 767px) {
.table-responsive .dropdown-menu {
position: static !important;
}
}
@media (min-width: 768px) {
.table-responsive {
overflow: visible;
}
}
Más detalles: https://github.com/twbs/bootstrap/issues/15374
Esto funcionó para mí en Bootstrap 4 ya que tiene diferentes puntos de interrupción que v3:
@media (min-width: 992px) {
.table-responsive {
overflow: inherit;
}
}
Esto podría ser útil para otra persona. Estoy usando DatatablesJS. Agrego 500px a la altura actual de la tabla. Hago esto porque Datatables te permite usar páginas de 10, 20, etc. en tu tabla. Entonces necesito calcular dinámicamente la altura de la mesa.
Cuando se muestra el menú desplegable, agrego altura adicional.
Cuando el menú desplegable es oculto, restablezco la altura de la tabla original.
$(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");
})
})
Y el HTML
<div class="table-responsive" id="table-responsive-cliente">
<table class="table-striped table-hover">
....
....
</table>
</div>
Había tomado un enfoque diferente, había separado el elemento del padre y lo había establecido con la posición absoluta por jQuery
Trabajo JS Fidle: http://jsfiddle.net/s270Lyrd/
La solución JS que estoy 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'');
}
});
La respuesta de Burebistaruler funciona bien para mí en ios8 (iphone4s) pero no funciona en Android antes de que funcionara. Lo que he donne que funciona para mí en ios8 (iphone4s) y andoir es:
$(''.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" );
})
La solución recomendada y elegida, no siempre es la mejor solución. Desafortunadamente es la solución que LinkedIn utilizó recientemente y crea múltiples barras de desplazamiento en la página según la situación.
Mi método fue ligeramente diferente.
Contuve el div sensible a la tabla en otro div. Luego apliqué la altura al 100%, el ancho: 100%, el bloque de visualización y la posición absoluta, por lo que el alto y el ancho se basan en el tamaño de la página y establezco el desbordamiento en oculto.
Luego, en la tabla responsive div agregué una altura mínima 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%;">
Como puede ver en el siguiente ejemplo de trabajo, sin barras de desplazamiento agregadas, sin comportamiento divertido, y prácticamente como sus porcentajes de uso, debería funcionar independientemente del tamaño de la pantalla. Sin embargo, no he probado esto para eso. Si eso falla por alguna razón, uno puede reemplazar el 100% con 100vh y 100vw respectivamente.
<!-- 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>
Limpió la solución @Wazime un poco. Funciona muy bien como una solución general.
$(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'');
});
Me resolví esto y puse la respuesta en el alcance para ayudar a otros usuarios que tienen el mismo problema: tenemos un evento en el arranque y podemos usar ese evento para establecer el overflow: inherited
pero esto funcionará si no tiene la propiedad css en su contenedor principal
$(''.table-responsive'').on(''show.bs.dropdown'', function () {
$(''.table-responsive'').css( "overflow", "inherit" );
});
$(''.table-responsive'').on(''hide.bs.dropdown'', function () {
$(''.table-responsive'').css( "overflow", "auto" );
})
info:
En este violín, el ejemplo funciona de manera extraña y no estoy seguro de por qué, pero en mi proyecto funciona muy bien.
Solucionamos este problema aquí en el trabajo aplicando una clase .dropup al menú desplegable cuando el menú desplegable está cerca de la parte inferior de una tabla. enter image description here
Tengo una solución que usa solo CSS, simplemente use la posición relativa para los menús desplegables dentro de la tabla sensible:
@media (max-width: 767px) {
.table-responsive .dropdown-menu {
position: relative; /* Sometimes needs !important */
}
}
Una solución CSS única es permitir que el eje y se desborde.
http://www.bootply.com/YvePJTDzI0
.table-responsive {
overflow-y: visible !important;
}
EDITAR
Otra solución exclusiva de CSS es aplicar responsivamente el desbordamiento basado en el ancho de la ventana gráfica:
@media (max-width: 767px) {
.table-responsive .dropdown-menu {
position: static !important;
}
}
@media (min-width: 768px) {
.table-responsive {
overflow: inherit;
}
}
mi solución global rápida 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);
})
})();
Explicaciones: cuando se muestra un menú desplegable dentro de un ''.table-responsive'', calcula la altura de la tabla y la expande (con relleno) para que coincida con la altura requerida para mostrar el menú. El menú puede ser de cualquier tamaño.
En mi caso, esta no es la tabla que tiene la clase ''.table-responsive'', es un div que se envuelve:
<div class="table-responsive" style="overflow:auto;">
<table class="table table-hover table-bordered table-condensed server-sort">
¡Entonces la var de $ table en el script es en realidad un div! (solo para ser claro ... o no) :)
Nota: lo envuelvo en una función para que mi IDE pueda colapsar la función;) ¡pero no es obligatorio!
Simplemente use esto
.table-responsive {
overflow: inherit;
}
Funciona en Chrome, pero no en IE10 o Edge porque heredar propiedad no es compatible