24

I have a HTML table like this:

<table border="1">
    <tbody>
        <tr>
            <td><a href="#" class="delete">DELETE ROW</a>COL 1</td>
            <td><a href="#" class="delete">DELETE COL</a>COL 2</td>
            <td><a href="#" class="delete">DELETE COL</a>COL 3</td>
            <td><a href="#" class="delete">DELETE COL</a>COL 4</td>
            <td><a href="#" class="delete">DELETE COL</a>COL 5</td>
            <td><a href="#" class="delete">DELETE COL</a>COL 6</td>
        </tr>
        <tr>
            <td>ROW 1</td>
            <td>ROW 1</td>
            <td>ROW 1</td>
            <td>ROW 1</td>
            <td>ROW 1</td>
            <td>ROW 1</td>
        </tr>
        <tr>
            <td>ROW 2</td>
            <td>ROW 2</td>
            <td>ROW 2</td>
            <td>ROW 2</td>
            <td>ROW 2</td>
            <td>ROW 2</td>
        </tr>
    </tbody>
</table>

I need a function to remove the specified column when I click on the link with the class "delete". Can you help ?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Manny Calavera
  • 6,815
  • 20
  • 60
  • 85

11 Answers11

50

After a few years, it's probably time to update the answer on this question.

// Listen for clicks on table originating from .delete element(s)
$("table").on("click", ".delete", function ( event ) {
    // Get index of parent TD among its siblings (add one for nth-child)
    var ndx = $(this).parent().index() + 1;
    // Find all TD elements with the same index
    $("td", event.delegateTarget).remove(":nth-child(" + ndx + ")");
});
Sampson
  • 265,109
  • 74
  • 539
  • 565
  • This delete the row, doesn't delete the column – Daniel Moura Jul 01 '09 at 12:30
  • Works, yeah. Could be cleaned up a bit though :) – Sampson Jul 01 '09 at 13:03
  • Like the fun part! Adding a .css("white-space", "nowrap") before the .animate({width: "0"} would be nice – Tim Büthe Jul 01 '09 at 13:32
  • Tim, in my own personal copy I did that. But didn't paste it over :) Definitely makes the animation smoother. – Sampson Jul 01 '09 at 13:33
  • I have tested the new method right now and after each column I remove, it leaves an empty there that has border and it's growing from column to column as I remove them.. any ideas ? – Manny Calavera Jul 01 '09 at 21:23
  • You mean if you delete all of the columns? – Sampson Jul 01 '09 at 21:37
  • A quick-fix would be to remove all TR's having no TD's – Sampson Jul 01 '09 at 21:38
  • Actually, I think it leaves the border from each .. Take a look at this screenshot: http://img509.imageshack.us/img509/124/tdborder.jpg What do you think ? Thanks. – Manny Calavera Jul 02 '09 at 09:06
  • Nevermind... It was the table's cellpadding/cellspacing... I have set them to 0 from the start... Any other solution ? – Manny Calavera Jul 02 '09 at 09:08
  • Many, do you have firebug installed? If so, please explore the table structure after deleting a row. I am unable to replicate the issue you're having. – Sampson Jul 02 '09 at 10:25
  • Yes, I have Firebug. There are no firebug-visible elements after the remove. As you saw in the screenshot, the border kinda unites there. With border=1 and cellpadding=0, cellspacing=0 this issue is not present... dunno.. This only happens in FireFox. In IE7 it doesn't appear.. – Manny Calavera Jul 02 '09 at 14:14
  • What happens if you have style="border-collapse:collapse;" on the table and td's? – Sampson Jul 02 '09 at 14:20
  • The border is thinner but it still remains after the remove... I mean, same problem, just thinner... It's ok though, you've helped enough already. It's not really a BIG problem. I'll leave the cellpadding/spacing to 0 and deal with it. Thank you very much! – Manny Calavera Jul 02 '09 at 14:28
  • I was looking for some table column manipulation with jQuery and I found a lot of great teaching code about jQuery selectors and DOM browsing functions. +1 from me, of course. – Erik Escobedo Jul 08 '10 at 18:42
17

A generic way (not tested):

$("a.delete").click(function() {
   var colnum = $(this).closest("td").prevAll("td").length;

   $(this).closest("table").find("tr").find("td:eq(" + colnum + ")").remove();
}

No need to change markup.

Andre Figueiredo
  • 12,930
  • 8
  • 48
  • 74
Philippe Leybaert
  • 168,566
  • 31
  • 210
  • 223
12

This is how I would do it.

Assign each cell in a column with the same class name. Then with jQuery, remove all tags that have that class name.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
2

@Jonathan Sampson's answer, I modified the code to handle table markup containing a <thead> element and provide a nice fade effect:

$(document).ready(function(){
    $("a.delete").live("click", function(){
    /* Better index-calculation from @activa */
    var myIndex = $(this).closest("th").prevAll("th").length;
    $(this).parents("table").find("tr").each(function(){
      $(this).find("td:eq("+myIndex+"), th:eq("+myIndex+")").fadeOut('slow', function() {
        $(this).remove();
        fixTitles();
      });
    });
  });
});
function fixTitles() {
  $("tr:eq(0) td").each(function(a){
    $(this).html("<a href='#' class='delete'>Delete Row</a> COL " + (a+1));
  });
}
chromaloop
  • 222
  • 5
  • 11
2

This old topic came top in google but gives very poor answers. Wasted long time for making this work but the easy solution would be here for example

http://www.devcurry.com/2009/07/hide-table-column-with-single-line-of.html

  $(document).ready(function() {
        $('#btnHide').click(function() {
            $('td:nth-child(2)').hide();
            // if your table has header(th), use this
            //$('td:nth-child(2),th:nth-child(2)').hide();
        });
    });
nonamenoa
  • 21
  • 1
1

I didn't really like any of the solutions from this post, so I came up with my own. Idealy what needed is :nth-of-type selector which would make things way easier. But unfortunately JQuery does not support it "due to their lack of real-world usefulness". Ehh..

So here's my solution which does the trick using :nth-child expression:

$("a.delete").click(function(event) {
   event.preventDefault();

   var current_cell = $(this).closest("td");
   var nb_columns = current_cell.closest('table').find('tr:eq(1) td').length+1;
   var column_to_delete = current_cell.prevAll("td").length+1;

   $('table tr td:nth-child('+(nb_columns+'n-'+(nb_columns-column_to_delete))+')').remove();
});
Pavel Dubinin
  • 2,410
  • 1
  • 24
  • 28
1

I know the topic is old but I think the easiest way is just put: $(".delete").remove();

hugs.

Zanoldor

Zanoldor
  • 15
  • 5
0

jQuery:

   $('.delete').click(function() {
       var colNumber = $(this).parents().find('td').attr('col');
       $('td[col='+colNumber+']').remove();
       return false;
    });

HTML:

<table border="1">
    <tbody>
    <tr>
                <td col='1'><a href="#" class="delete">DELETE COL</a>COL 1</td>
                <td col='2'><a href="#" class="delete">DELETE COL</a>COL 2</td>
            <td col='3'><a href="#" class="delete">DELETE COL</a>COL 3</td>
            <td col='4'><a href="#" class="delete">DELETE COL</a>COL 4</td>
            <td col='5'><a href="#" class="delete">DELETE COL</a>COL 5</td>
            <td col='6'><a href="#" class="delete">DELETE COL</a>COL 6</td>
        </tr>
        <tr>
                <td col='1'>ROW 1</td>
                <td col='2'>ROW 1</td>
            <td col='3'>ROW 1</td>
            <td col='4'>ROW 1</td>
            <td col='5'>ROW 1</td>
            <td col='6'>ROW 1</td>
        </tr>
        <tr>
                <td col='1'>ROW 2</td>
                <td col='2'>ROW 2</td>
            <td col='3'>ROW 2</td>
            <td col='4'>ROW 2</td>
            <td col='5'>ROW 2</td>
            <td col='6'>ROW 2</td>
        </tr>
    </tbody>
</table>
Daniel Moura
  • 7,816
  • 5
  • 35
  • 60
0

Try this:

    $("a.delete").click(function(){
        var td=$(this).parent();
        var col=$(td).text();
        col=col.substring(col.length-2)*1;
        var f="td:nth-child("+col+")";
        var tbl=$(td).parent().parent();

        $(tbl).find("tr").each(function(){
            $(this).find(f).hide();
        });

Tested in FF3.5.

there is one concern though getting column number. If number of columns excede 2 digits it will not work. It would be better if you put custom attribute and assign it position of column.

   <a class="delete" href="#" col="2">...</a>

remember with nth-child index starts at 1

TheVillageIdiot
  • 40,053
  • 20
  • 133
  • 188
0

Try this, i got the exact out put

var colnum = $(e.target).closest("td").length;
$(e.target).closest("table").find("tr").each(function(){ 
$(this).find("td:eq(" + colnum + ")").remove()});
Naveenbos
  • 2,532
  • 3
  • 34
  • 60
0

When I've read this post I tried the first solution using jQuery's remove function. But it seems to have a problem with this function when using it on a table row to delete cell. The problem is bind to a concurrent modification. In the exemple with this reponse if you try to use the index() function it will not work because cell index is changing each time you remove a cell. One solution could be to use the hide() function on the cell you want to delete. But if you really need to delete the column (remove it from the DOM) the way which has worked for me were to use the javascript native to remove the column.

$(function() {      
    $('table tr').each(function(e, row) {
    var i = 0;
    $(row).find('td, th').each(function(e, cell) {          
        if (i == 1)  { 
           row.removeChild(cell);  
        }   
        i++;                    
    });
});

In this example you delete the second column of the table : i == 1 ...

websoft102030
  • 55
  • 1
  • 4