23

Using jQuery, how can I find the column index of an arbitrary table cell in the example table below, such that cells spanning multiple columns have multiple indexes?

HTML

<table>
  <tbody>
    <tr>
      <td>One</td>
      <td>Two</td>
      <td id="example1">Three</td>
      <td>Four</td>
      <td>Five</td>
      <td>Six</td>
    </tr>
    <tr>
      <td colspan="2">One</td>
      <td colspan="2">Two</td>
      <td colspan="2" id="example2">Three</td>
    </tr>
    <tr>
      <td>One</td>
      <td>Two</td>
      <td>Three</td>
      <td>Four</td>
      <td>Five</td>
      <td>Six</td>
    </tr>
  </tbody>
</table>

jQuery

var cell = $("#example1");
var example1ColIndex = cell.parent("tr").children().index(cell);
// == 2. This is fine.

cell = $("#example2");
var example2ColumnIndex = cell.parent("tr").children().index(cell);
// == 2. It should be 4 (or 5, but I only need the lowest). How can I do this?
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Brant Bobby
  • 14,956
  • 14
  • 78
  • 115

5 Answers5

29

Here's a plugin which can calculate the 'noncolspan' index.

$(document).ready(
        function()
        {
        console.log($('#example2').getNonColSpanIndex()); //logs 4
        console.log($('#example1').getNonColSpanIndex()); //logs 2
    }

);

$.fn.getNonColSpanIndex = function() {
    if(! $(this).is('td') && ! $(this).is('th'))
        return -1;

    var allCells = this.parent('tr').children();
    var normalIndex = allCells.index(this);
    var nonColSpanIndex = 0;

    allCells.each(
        function(i, item)
        {
            if(i == normalIndex)
                return false;

            var colspan = $(this).attr('colspan');
            colspan = colspan ? parseInt(colspan) : 1;
            nonColSpanIndex += colspan;
        }
    );

    return nonColSpanIndex;
};
SolutionYogi
  • 31,807
  • 12
  • 70
  • 78
  • 1
    consider changing the first line in the function to (to support table headers) if(! $(this).is('td') && ! $(this).is('th')) – Andre Haverdings Mar 04 '10 at 15:13
  • @SolutionYogi, I think your updated code as if(! $(this).is('td') || ! $(this).is('th')) instead of if(! $(this).is('td') && ! $(this).is('th')) – Gennady Shumakher Apr 14 '10 at 10:51
  • Gennady, I think I have the correct code in there. If the current element is not TD or TH, I want to return -1 as I can not determine col span index for non TD/TH elements. – SolutionYogi Apr 15 '10 at 17:11
  • 1
    SolutionYogi, the problem is the current condition says 'if the current element is not TD or is not TH' which always results to true for any element... – Gennady Shumakher Apr 20 '10 at 17:58
  • 1
    Gennaldy, you are right. I don't know what I was thinking! Thank you for the correction. – SolutionYogi Apr 20 '10 at 19:01
  • Nice plugin - just what I needed. I've also created one to go from col number to cell: $.fn.getNonColSpanCell = function (col) { var currentCol = 0; var cells = $(this).children('td'); for (var i = 0; i < cells.length; i++) { var colspan = $(cells[i]).attr('colspan'); colspan = colspan ? parseInt(colspan) : 1; currentCol += colspan; if (currentCol >= col) { break; } } return $(cells[currentCol]); } – Kim R Oct 28 '11 at 10:17
5

Mine is quite similar to SolutionYogi's, minus the creation of a plugin. It took me a bit longer... but I'm still proud of it so here it is :)

cell = $("#example2");
var example2ColumnIndex2 = 0;

cell.parent("tr").children().each(function () {
    if(cell.get(0) != this){
        var colIncrementor = $(this).attr("colspan");
        colIncrementor = colIncrementor ? colIncrementor : 1;
        example2ColumnIndex2 += parseInt(colIncrementor);
    }
});
console.log(example2ColumnIndex2);
phairoh
  • 10,485
  • 4
  • 23
  • 18
4

There is a more concise answer here: Get Index of a td considering the colspan using jquery

In short:

var index = 0;
$("#example2").prevAll("td").each(function() {
    index += this.colSpan;
});
console.log(index);
Community
  • 1
  • 1
Alan B. Dee
  • 5,490
  • 4
  • 34
  • 29
2

You could do something like this:

 var index = 0;
 cell.parent('tr').children().each( 
     function(idx,node) { 
           if ($(node).attr('colspan')) {
             index+=parseInt($(node).attr('colspan'),10); 
           } else {
              index++;
           }

         return !(node === cell[0]);
     }
 );
 console.log(index);

It'd probably make sense to do it as a plugin or via extend.

seth
  • 36,759
  • 7
  • 60
  • 57
0

Slightly modified version is here: http://jsfiddle.net/Lijo/uGKHB/13/

//INDEX
alert ( GetNonColSpanIndex ('Type'));

function GetNonColSpanIndex(referenceHeaderCellValue) {

    var selectedCell = $("th").filter(function (i) {
        return ($.trim($(this).html()  )) == referenceHeaderCellValue;

    });

    alert(selectedCell.html());

    var allCells = $(selectedCell).parent('tr').children();
    var normalIndex = allCells.index($(selectedCell));
    var nonColSpanIndex = 0;

    allCells.each(
    function (i, item) {
        if (i == normalIndex)
            return false;

        var colspan = $(selectedCell).attr('colspan');
        colspan = colspan ? parseInt(colspan) : 1;
        nonColSpanIndex += colspan;
    }
    );

    return nonColSpanIndex;
};

LCJ
  • 22,196
  • 67
  • 260
  • 418