Question

Let's say there are 6 th elements

    <thead>
      <tr><th></th><th></th><th></th> <th></th><th></th><th></th></tr>
    </thead>

and I want to iterate over the first 4 only. How do I get an iterable list of these elements so I can do something like this:

    while (i < myLimit) {
          th = thlist[i];
          // do something : if somecondition myLimit +=1;
          i++;
    }
    return i;

The th elements are decorated, some of them, with style="display:none" and I'm trying to figure out how many such decorated th elements there are to the left of an arbitrarily chosen one.

NOTE: myLimit may have to be increased during the iteration!!

Was it helpful?

Solution

You can use getElementByTagName javascript pure function, like this:

function getStyle(elem, cssprop, cssprop2){
 // IE
 if (elem.currentStyle) {
   return elem.currentStyle[cssprop];

 // other browsers
 } else if (document.defaultView &&
                   document.defaultView.getComputedStyle) {
   return document.defaultView.getComputedStyle(elem,
null).getPropertyValue(cssprop2);

 // fallback
 } else {
   return null;
 }
}


var ths = document.getElementsByTagName('th');
var myLimit = 4;

var max = ths.length;

if (myLimit>max)
    myLimit = max;

for (var i = 0;i < myLimit; i++) {
    // do something with myarray[i]
    var th = ths[i];
    if (getStyle(th,'display','display')=='none')
        alert('th in position '+i+' is decorated with display:none');
}

here is a live example working http://jsfiddle.net/aJ8MS/

OTHER TIPS

An easy way to access rows and cells in a table is to use the built in properties. Usually the headers are found in the first row (it is the case in your question), so the ths are the cells contained in table.rows[0]:

var table=document.getElementById("myTable"),
    i=0,
    count=0,
    myLimit=4;
while (i < myLimit) {
    if (table.rows[0].cells[i].style.display=="none") { count ++; }
    i++;
}
return count;

I started with sandino's solution and used Christophe's check for the display none style.

The tricksy thing about this situation is that I'm using a kendo grid, which splits the grid into two tables, one for the header and another for the body rows. The two tables can have a different number of columns if some columns are hidden because the body-grid contains only the visible columns whereas the header-grid has definitions even for the invisible columns.

Let's say there are 12 columns in the grid and the first 7 are hidden. The header-grid contains all 12, with the first 7 decorated with display:none. The content-grid contains only the 5 visible columns. So when the user clicks on the first visible column, index 0, that actually corresponds to the 8th column in the header grid (0-based, so index = 7).

To find the column-header that corresponds to the VisibleIndex 0, we have to add to the index of the clicked cell the number of hidden columns that are to the left of it. We add 7 to 0 to get 7.

 function countHiddenColumnHeadersLeft(id, clickedCellIndex) {    
    var ths = document.getElementById(id).getElementsByClassName('k-header');
    var myLimit = clickedCellIndex;   


    var invisicount = 0;

    for (var i = 0; (i < myLimit) ; i++) {        
      var th = ths[i];
      if (th.style.display == 'none') {
            invisicount++;
            myLimit++;
        }        
    }
    return invisicount;
}

You can gather the first 4 (or n) elements like this:

var limit = 4,
    $ths = $('th:not(:nth-child('+limit+') ~ th)', 'thead');

then iterate for example with .each():

$ths.each(function() {
  console.log(this);
});

jsfiddle

or another approach:

var limit = 4,
    $ths = $('th', 'thead');

$ths.each( function() {
    var id = $(this).index();
    if(id < limit) {
        console.log(this);
        // increase limit on certain condition
        if(id == 2) limit++;
    }
});

return limit;

jsfiddle

To check if an element has display: none simply:

$this.is(':hidden')
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top