tags:

views:

110

answers:

2

Hello!

I am looking for a way to do the following with a normal HTML table using jQuery.

  1. Extracting the index of the clicked cell and the index of the row it belongs too.
  2. Highlight the selected cell and remove the highlight when it is clicked again.
  3. Keep track of which cells that are selected so that I can save them into a database.

This is what I have done so far:

$("#frame td").click(function(e) {

    var RowSelected = $(this).parent().parent().children().index($(this).parent());
    var CellSelected = e.target.cellIndex;

    $(this).toggleClass("selected", this.clicked);

    $("#cells").append("R" + RowSelected + "C" + CellSelected + ", ");

});

Please help!

+1  A: 

You could do this by attempting to count the rows, etc., but one approach that I like when I'm writing my tabled programmatically is to add classes to each cell as I write them out so that each cell has a class that tells me where it is, and so that I can address it very quickly:

<table>
   <tr class="row1">
      <td class="row1 col1">Something</td>
      <td class="row1 col2">Something else</td>
      ...
      <td class="row1 col10">Final thing</td>
   </tr>

   <tr class="row2">
      <td class="row2 col1">Something</td>
      <td class="row2 col2">Something else</td>
      ...
      <td class="row2 col10">Final thing</td>
   </tr>

   <tr class="row3">
      <td class="row3 col1">Something</td>
      <td class="row3 col2">Something else</td>
      ...
      <td class="row3 col10">Final thing</td>
   </tr>
</table>

Now, in your jQuery:

$('td').click(function() {
   var classes = $(this).attr('class').split(/\s+/),
       col,
       row,
       i;

   for (i in classes) {
      if (classes[i].substring(0,2) == 'col') { col = classes[i].substring(3); }
      if (classes[i].substring(0,2) == 'row') { row = classes[i].substring(3); }
   }

   alert('You clicked the cell on row ' + row + ' and column ' + col);
});

This looks a little unwieldy, but what I like about it is I can address each cell in the table very quickly with something like:

$('td.row2.col3').text(); // will quickly grab the contents of cell r2,c3

I hope this is helpful.

mkoistinen
Looks fine! I also need to keep track of which cells that are selected and hightlight them, then if someone deselects a cell it should no longer be highlighten and should not be present in the list of selected cells. How is this done?
Jonathan Clark
`for...in` isn't a good way to iterate an `Array`. Incidentally, you can address each cell quite easily using plain DOM collections: `tableobj.rows[1].cells[2]`.
bobince
Jonathan $('td').click(function() { $(this).toggle('hilight'); }); Then be sure to define the class .hilight in your CSS to hilight your cells. You can also test for that class and set a flag when sending the cells to your server for saving.
mkoistinen
@Bobince very true. It's late here :)
mkoistinen
+3  A: 

DOM gives you rowIndex as well as cellIndex, there is no need for the crazy jQuery index work.

Also if you postpone the generation of the list-of-selected-cells until submit-time you won't have to try to keep track of them by adding and removing elements on click:

$('#frame td').click(function() {
    $(this).toggleClass('selected');
});

$('#someform').submit(function() {
    $('#cells').val(
        $('#frame td.selected').map(function() {
            return 'R'+this.parentNode.rowIndex+'C'+this.cellIndex;
        }).get().join(', ')
    );
});

assuming #cells is a hidden input you're using to pass the information.

bobince
This is the approach I was about to type up, but more concise :)
RickF
Looks very interesting. I created a form and the #cells field but it is not populated when I click on submit.
Jonathan Clark
@Jonathan: works for me, how are you attaching the `submit` event to the form?
bobince
<form id="someform"><input type="text" id="cells" /><input type="submit" /></form>
Jonathan Clark
@bobince do you have a complete html page with your code anywhere that is working? For example like this: http://jsbin.com/inaje3/2
Jonathan Clark
@bobince. I have "uploaded" my code to http://jsbin.com/ebiha3. Can you please see what is wrong with it and perhaps change it? Thanks!!
Jonathan Clark
Ah, sorry, there was a stray semicolon after `join(';')` that shouldn't have been there.
bobince