Pregunta

Tengo una tabla HTML con varias columnas y necesito implementar un selector de columnas usando jquery. Cuando un usuario hace clic en una casilla de verificación, quiero ocultar / mostrar la columna correspondiente en la tabla. Me gustaría hacer esto sin adjuntar una clase a cada td en la tabla, ¿hay alguna manera de seleccionar una columna completa usando jquery? A continuación se muestra un ejemplo del HTML.

<table>
    <thead>
        <tr><th class="col1">Header 1</th><th class="col2">Header 2</th><th class="col3">Header 3</th></tr>
    </thead>
    <tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
    <tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
    <tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
    <tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
</table>

<form>
    <input type="checkbox" name="col1" checked="checked" /> Hide/Show Column 1 <br />
    <input type="checkbox" name="col2" checked="checked" /> Hide/Show Column 2 <br />
    <input type="checkbox" name="col3" checked="checked" /> Hide/Show Column 3 <br />
</form>
¿Fue útil?

Solución

  

Me gustaría hacer esto sin adjuntar una clase a cada td

Personalmente, iría con el enfoque class-on-each-td / th / col. Luego, puede activar y desactivar columnas utilizando una sola escritura en className en el contenedor, asumiendo reglas de estilo como:

table.hide1 .col1 { display: none; }
table.hide2 .col2 { display: none; }
...

Esto será más rápido que cualquier enfoque de bucle JS; para tablas realmente largas puede marcar una diferencia significativa en la capacidad de respuesta.

Si puede salirse con la suya al no admitir IE6, podría usar selectores de adyacencia para evitar tener que agregar los atributos de clase a tds. O, alternativamente, si su preocupación es hacer que el marcado sea más limpio, puede agregarlos desde JavaScript automáticamente en un paso de inicialización.

Otros consejos

Una línea de código usando jQuery que oculta la segunda columna:

$('td:nth-child(2)').hide();

Si su tabla tiene encabezado (th), use esto:

$('td:nth-child(2),th:nth-child(2)').hide();

Fuente: Ocultar una columna de tabla con una sola línea de código jQuery

jsFiddle para probar el código: http://jsfiddle.net/mgMem/1/


Si desea ver un buen caso de uso, eche un vistazo a mi publicación de blog:

Ocultar una columna de tabla y colorear las filas según en valor con jQuery .

podría usar colgroups:

<table>
    <colgroup>
       <col class="visible_class"/>
       <col class="visible_class"/>
       <col class="invisible_class"/>  
    </colgroup>
    <thead>
        <tr><th class="col1">Header 1</th><th class="col2">Header 2</th><th class="col3">Header 3</th></tr>
    </thead>
    <tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
    <tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
    <tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
    <tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
</table>

su script podría cambiar solo la clase de deseo <col>.

Lo siguiente debería hacerlo:

$("input[type='checkbox']").click(function() {
    var index = $(this).attr('name').substr(2);
    $('table tr').each(function() { 
        $('td:eq(' + index + ')',this).toggle();
    });
});

Este es un código no probado, pero el principio es que elige la celda de la tabla en cada fila que corresponde al índice elegido extraído del nombre de la casilla de verificación. Por supuesto, podría limitar los selectores con una clase o una ID.

Aquí hay una respuesta un poco más completa que proporciona cierta interacción del usuario por columna. Si esto va a ser una experiencia dinámica, debe haber un botón de clic en cada columna que indique la capacidad de ocultar la columna, y luego una forma de restaurar columnas previamente ocultas.

Eso se vería así en JavaScript:

$('.hide-column').click(function(e){
  var $btn = $(this);
  var $cell = $btn.closest('th,td')
  var $table = $btn.closest('table')

  // get cell location - https://stackoverflow.com/a/4999018/1366033
  var cellIndex = $cell[0].cellIndex + 1;

  $table.find(".show-column-footer").show()
  $table.find("tbody tr, thead tr")
        .children(":nth-child("+cellIndex+")")
        .hide()
})

$(".show-column-footer").click(function(e) {
    var $table = $(this).closest('table')
    $table.find(".show-column-footer").hide()
    $table.find("th, td").show()

})

Para respaldar esto, agregaremos algunas marcas a la tabla. En cada encabezado de columna, podemos agregar algo como esto para proporcionar un indicador visual de algo cliqueable

<button class="pull-right btn btn-default btn-condensed hide-column" 
            data-toggle="tooltip" data-placement="bottom" title="Hide Column">
    <i class="fa fa-eye-slash"></i>  
</button>

Permitiremos al usuario restaurar columnas a través de un enlace en el pie de página de la tabla. Si no es persistente de manera predeterminada, entonces activarlo dinámicamente en el encabezado podría moverse alrededor de la mesa, pero realmente puede colocarlo en cualquier lugar que desee:

<tfoot class="show-column-footer">
   <tr>
    <th colspan="4"><a class="show-column" href="#">Some columns hidden - click to show all</a></th>
  </tr>
</tfoot>

Esa es la funcionalidad básica. Aquí hay una demostración a continuación con un par de cosas más desarrolladas. También puede agregar una información sobre herramientas al botón para ayudar a aclarar su propósito, diseñar el botón un poco más orgánicamente en el encabezado de una tabla y contraer el ancho de la columna para agregar algunas animaciones CSS (algo inestables) para hacer la transición un poco menos nervioso.

 Captura de pantalla de demostración

Demostración de trabajo en jsFiddle & amp; Fragmentos de pila:

$(function() {
  // on init
  $(".table-hideable .hide-col").each(HideColumnIndex);

  // on click
  $('.hide-column').click(HideColumnIndex)

  function HideColumnIndex() {
    var $el = $(this);
    var $cell = $el.closest('th,td')
    var $table = $cell.closest('table')

    // get cell location - https://stackoverflow.com/a/4999018/1366033
    var colIndex = $cell[0].cellIndex + 1;

    // find and hide col index
    $table.find("tbody tr, thead tr")
      .children(":nth-child(" + colIndex + ")")
      .addClass('hide-col');
      
    // show restore footer
    $table.find(".footer-restore-columns").show()
  }

  // restore columns footer
  $(".restore-columns").click(function(e) {
    var $table = $(this).closest('table')
    $table.find(".footer-restore-columns").hide()
    $table.find("th, td")
      .removeClass('hide-col');

  })

  $('[data-toggle="tooltip"]').tooltip({
    trigger: 'hover'
  })

})
body {
  padding: 15px;
}

.table-hideable td,
.table-hideable th {
  width: auto;
  transition: width .5s, margin .5s;
}

.btn-condensed.btn-condensed {
  padding: 0 5px;
  box-shadow: none;
}


/* use class to have a little animation */
.hide-col {
  width: 0px !important;
  height: 0px !important;
  display: block !important;
  overflow: hidden !important;
  margin: 0 !important;
  padding: 0 !important;
  border: none !important;
}
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.7/paper/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>




<table class="table table-condensed table-hover table-bordered table-striped table-hideable">

  <thead>
    <tr>
      <th>
        Controller
        <button class="pull-right btn btn-default btn-condensed hide-column" data-toggle="tooltip" data-placement="bottom" title="Hide Column">
          <i class="fa fa-eye-slash"></i>  
        </button>
      </th>
      <th class="hide-col">
        Action
        <button class="pull-right btn btn-default btn-condensed hide-column" data-toggle="tooltip" data-placement="bottom" title="Hide Column">
          <i class="fa fa-eye-slash"></i>  
        </button>
      </th>
      <th>
        Type
        <button class="pull-right btn btn-default btn-condensed hide-column" data-toggle="tooltip" data-placement="bottom" title="Hide Column">
          <i class="fa fa-eye-slash"></i>  
        </button>
      </th>
      <th>
        Attributes
        <button class="pull-right btn btn-default btn-condensed hide-column" data-toggle="tooltip" data-placement="bottom" title="Hide Column">
          <i class="fa fa-eye-slash"></i>  
        </button>
      </th>
  </thead>
  <tbody>

    <tr>
      <td>Home</td>
      <td>Index</td>
      <td>ActionResult</td>
      <td>Authorize</td>
    </tr>

    <tr>
      <td>Client</td>
      <td>Index</td>
      <td>ActionResult</td>
      <td>Authorize</td>
    </tr>

    <tr>
      <td>Client</td>
      <td>Edit</td>
      <td>ActionResult</td>
      <td>Authorize</td>
    </tr>

  </tbody>
  <tfoot class="footer-restore-columns">
    <tr>
      <th colspan="4"><a class="restore-columns" href="#">Some columns hidden - click to show all</a></th>
    </tr>
  </tfoot>
</table>

Y, por supuesto, la única forma de CSS para navegadores que admiten nth-child:

table td:nth-child(2) { display: none; }

Esto es para IE9 y más reciente.

Para su caso de uso, necesitaría varias clases para ocultar las columnas:

.hideCol1 td:nth-child(1) { display: none;}
.hideCol2 td:nth-child(2) { display: none;}

ect ...

Lo siguiente se basa en el código de Eran, con algunos cambios menores. Lo probé y parece funcionar bien en Firefox 3, IE7.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
                "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<script>
$(document).ready(function() {
    $('input[type="checkbox"]').click(function() {
        var index = $(this).attr('name').substr(3);
        index--;
        $('table tr').each(function() { 
            $('td:eq(' + index + ')',this).toggle();
        });
        $('th.' + $(this).attr('name')).toggle();
    });
});
</script>
<body>
<table>
<thead>
    <tr>
        <th class="col1">Header 1</th>
        <th class="col2">Header 2</th>
        <th class="col3">Header 3</th>
    </tr>
</thead>
<tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
<tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
<tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
<tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
</table>

<form>
    <input type="checkbox" name="col1" checked="checked" /> Hide/Show Column 1 <br />
    <input type="checkbox" name="col2" checked="checked" /> Hide/Show Column 2 <br />
    <input type="checkbox" name="col3" checked="checked" /> Hide/Show Column 3 <br />
</form>
</body>
</html>
<p><input type="checkbox" name="ch1" checked="checked" /> First Name</p>
.... 
<td class="ch1">...</td>

 <script>
       $(document).ready(function() {
            $('#demo').multiselect();
        });


        $("input:checkbox:not(:checked)").each(function() {
    var column = "table ." + $(this).attr("name");
    $(column).hide();
});

$("input:checkbox").click(function(){
    var column = "table ." + $(this).attr("name");
    $(column).toggle();
});
 </script>

¿Sin clase? Puede usar la etiqueta entonces:

var tds = document.getElementsByTagName('TD'),i;
for (i in tds) {
  tds[i].style.display = 'none';
}

Y para mostrarlos use:

...style.display = 'table-cell';            
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top