views:

3283

answers:

7

Hello. 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 ?

Thanks.

+5  A: 

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
+11  A: 

Requires 0 changes to your markup, and updates titles after deletion:

$(document).ready(function(){

  $("a.delete").live("click", function(){
    /* Better index-calculation from @activa */
    var myIndex = $(this).closest("td").prevAll("td").length;
    $(this).parents("table").find("tr").each(function(){
      $(this).find("td:eq("+myIndex+")").remove();
      fixTitles();
    });
  });

});

function fixTitles() {
  $("tr:eq(0) td").each(function(a){
    $(this).html("<a href='#' class='delete'>Delete Row</a> COL " + (a+1));
  });
}

Added Fun

Turn this:

      $(this).find("td:eq("+myIndex+")").remove();
      fixTitles();

Into this:

      $(this).find("td:eq("+myIndex+")").animate({width: "0"}, 1000, function(){
        $(this).remove();
        fixTitles();
      });
Jonathan Sampson
This delete the row, doesn't delete the column
Daniel Moura
No, actually it works.
Manny Calavera
Works, yeah. Could be cleaned up a bit though :)
Jonathan Sampson
Like the fun part! Adding a .css("white-space", "nowrap") before the .animate({width: "0"} would be nice
Tim Büthe
Tim, in my own personal copy I did that. But didn't paste it over :) Definitely makes the animation smoother.
Jonathan Sampson
Thank you. It's nice.
Manny Calavera
I have tested the new method right now and after each column I remove, it leaves an empty <tr> there that has border and it's growing from column to column as I remove them.. any ideas ?
Manny Calavera
You mean if you delete all of the columns?
Jonathan Sampson
A quick-fix would be to remove all TR's having no TD's
Jonathan Sampson
How would I do that ? =/
Manny Calavera
$("tr:empty").remove(); should do the trick.
Jonathan Sampson
Actually, I think it leaves the border from each <td> .. Take a look at this screenshot: http://img509.imageshack.us/img509/124/tdborder.jpgWhat do you think ? Thanks.
Manny Calavera
Nevermind... It was the table's cellpadding/cellspacing... I have set them to 0 from the start... Any other solution ?
Manny Calavera
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.
Jonathan Sampson
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
Very strange indeed.
Jonathan Sampson
What happens if you have style="border-collapse:collapse;" on the table and td's?
Jonathan Sampson
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
Sorry, man. I wish we could have resolved it. Best of luck.
Jonathan Sampson
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
+4  A: 

A generic way (not tested):

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

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

No need to change markup.

Philippe Leybaert
This is very cool.
Daniel A. White
Excellent index-calculation concept. +1
Jonathan Sampson
+1  A: 

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
A: 

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
+1  A: 

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
+1  A: 

@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