Wrong array method sort() logic - javascript

I Cannot understand the array method sort() logic. I had to write an eventListener for the two elements Age and Letter. By clicking on them we can sort our table by age and letter.
All works fine, but I see something strange in the sort() logic. By clicking on the Letter - table must sort by alphabet for elements in the column Letter. By clicking on the Age - table must sort by digits order for elements in the column Age. But it does not sort right.
tbody = document.getElementById('grid');
function tableSort(event) {
var target = event.target;
var action = target.getAttribute('data-type');
var arr = [].slice.call(grid.rows, 1);
var self = this;
this.number = function() {
arr.sort(function(a, b) { // sort by digits in the column "Age"
a.cells[0].innerHTML;
b.cells[0].innerHTML;
return a - b;
});
grid.appendChild(...arr);
}
this.string = function() {
arr.sort(function(a, b) { // sort by words in the column "Letter"
a.cells[1].innerHTML;
b.cells[1].innerHTML;
return a > b;
});
grid.appendChild(...arr);
}
if (action) {
self[action]();
}
}
tbody.addEventListener('click', tableSort);
th {
cursor: pointer;
}
<table id="grid">
<thead>
<tr>
<th data-type="number">Age</th>
<th data-type="string">Letter</th>
</tr>
</thead>
<tbody>
<tr>
<td>5</td>
<td>BBBBB</td>
</tr>
<tr>
<td>12</td>
<td>AAAAA</td>
</tr>
<tr>
<td>1</td>
<td>DDDDD</td>
</tr>
<tr>
<td>9</td>
<td>CCCCC</td>
</tr>
<tr>
<td>2</td>
<td>KKKKK</td>
</tr>
</tbody>
</table>
<script>
</script>

Modified your code and got it working. Here if you need it:
function tableSort(event) {
var target = event.target;
var action = target.getAttribute("data-type");
var arr = [].slice.call(grid.rows, 1);
var self = this;
this.number = function() {
arr.sort(function(a, b) {
// sort by digits in the column "Age"
return Number(a.cells[0].innerHTML) - Number(b.cells[0].innerHTML);
});
arr.forEach(function(item, index) {
grid.appendChild(item);
});
};
this.string = function() {
arr.sort(function(a, b) {
// sort by words in the column "Letter"
var str1 = a.cells[1].innerHTML;
var str2 = b.cells[1].innerHTML;
return str1.localeCompare(str2);
});
arr.forEach(function(item, index) {
grid.appendChild(item);
});
};
if (action) {
self[action]();
}
}
tbody.addEventListener("click", tableSort);

How about this stackoverflow post Sorting HTML table with JavaScript for clarification and the original external article in which I found it with a full example?
Sorting tables with VanillaJS or JQuery
Example:
/**
* Modified and more readable version of the answer by Paul S. to sort a table with ASC and DESC order
* with the <thead> and <tbody> structure easily.
*
* https://stackoverflow.com/a/14268260/4241030
*/
var TableSorter = {
makeSortable: function(table){
// Store context of this in the object
var _this = this;
var th = table.tHead, i;
th && (th = th.rows[0]) && (th = th.cells);
if (th){
i = th.length;
}else{
return; // if no `<thead>` then do nothing
}
// Loop through every <th> inside the header
while (--i >= 0) (function (i) {
var dir = 1;
// Append click listener to sort
th[i].addEventListener('click', function () {
_this._sort(table, i, (dir = 1 - dir));
});
}(i));
},
_sort: function (table, col, reverse) {
var tb = table.tBodies[0], // use `<tbody>` to ignore `<thead>` and `<tfoot>` rows
tr = Array.prototype.slice.call(tb.rows, 0), // put rows into array
i;
reverse = -((+reverse) || -1);
// Sort rows
tr = tr.sort(function (a, b) {
// `-1 *` if want opposite order
return reverse * (
// Using `.textContent.trim()` for test
a.cells[col].textContent.trim().localeCompare(
b.cells[col].textContent.trim()
)
);
});
for(i = 0; i < tr.length; ++i){
// Append rows in new order
tb.appendChild(tr[i]);
}
}
};
window.onload = function(){
TableSorter.makeSortable(document.getElementById("myTable"));
};
table thead th {
cursor: pointer;
}
<table id="myTable">
<thead>
<th data-type="string">Name</th>
<th data-type="number">Age</th>
</thead>
<tbody>
<tr>
<td>John</td>
<td>42</td>
</tr>
<tr>
<td>Laura</td>
<td>39</td>
</tr>
<tr>
<td>Fred</td>
<td>18</td>
</tr>
<tr>
<td>Bod</td>
<td>26</td>
</tr>
</tbody>
</table>

Related

How to sort table by date column

I have a table and I want to sort Date column ascending and descending.
I have tried the code below but its not working. Its work when sorting the numbers only.
function sortColumn() {
var table, rows, switching, i, x, y, shouldSwitch;
table = document.getElementById("example");
switching = true;
while (switching) {
switching = false;
rows = table.rows;
for (i = 1; i < (rows.length - 1); i++) {
shouldSwitch = false;
x = rows[i].getElementsByTagName("TD")[6];
y = rows[i + 1].getElementsByTagName("TD")[6];
if (parseInt(x.innerHTML.toLowerCase()) > parseInt(y.innerHTML.toLowerCase())) {
shouldSwitch = true;
break;
}
}
if (shouldSwitch) {
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
}
}
}
Here is a more complex example than you might have been looking for. It makes use of the Array Sort function, which can make use of an optional compareFunction to perform the sort comparison.
$(function() {
function tableToArray(tObj) {
var result = [];
var keys = [];
$("thead th", tObj).each(function(i, el) {
keys.push($(el).text().trim());
});
$("tbody tr").each(function(i, row) {
var temp = {};
$.each(keys, function(j, k) {
temp[k] = $("td", row).eq(j).text().trim();
});
result.push(temp);
});
return result;
}
function replaceTableData(tObj, data) {
var b = $("tbody", tObj);
b.html("");
$.each(data, function(i, row) {
var r = $("<tr>").appendTo(b);
$.each(row, function(j, cell) {
$("<td>").html(cell).appendTo(r);
});
});
}
function compare(a, b) {
var dateA = a.Date;
var dateB = b.Date;
var result = 0;
if (dateA > dateB) {
result = 1;
} else {
result = -1;
}
return result;
}
function sortTable() {
var tData = tableToArray($("table"));
tData.sort(compare);
replaceTableData($("table"), tData);
}
$(".sort-column").click(sortTable);
});
.sort-column {
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>ID</th>
<th class="sort-column" data-sort-order="null">Date</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>17/12/1989</td>
<td>Homer</td>
</tr>
<tr>
<td>2</td>
<td>07/09/2019</td>
<td>Marge</td>
</tr>
<tr>
<td>3</td>
<td>01/09/2019</td>
<td>Bart</td>
</tr>
<tr>
<td>4</td>
<td>04/09/2019</td>
<td>Lisa</td>
</tr>
<tr>
<td>5</td>
<td>14/09/2019</td>
<td>Maggie</td>
</tr>
</tbody>
</table>
This sorts based on the text in the Date column. You could get more complex and parse the Date into a Date Object when you compare. But with this date format, it's not really needed.
Update
Moved code into function so it can be called in a Click event. This is a really simple example and if you need more complex actions, consider how that might work or DataTables.

Stripe table JavaScript

I am trying to make a table which will display colours for odd and even table rows, not sure where I'm going wrong
HTML:
<table id="tableStyles" border="1">
<th>Heading 1</th>
<th>Heading 2</th>
<th>Heading 3</th>
<tr>
<td>Odd</td>
<td>Odd</td>
<td>Odd</td>
</tr>
<tr>
<td>Even</td>
<td>Even</td>
<td>Even</td>
</tr>
<tr>
<td>Odd</td>
<td>Odd</td>
<td>Odd</td>
</tr>
<tr>
<td>Odd</td>
<td>Odd</td>
<td>Odd</td>
</tr>
</table>
JS:
var isEven = function(someNumber) {
return (someNumber%2 == 0) ? true : false;
};
if isEven = true {
var styletab = document.getElementsByTagName("tableStyles");
var cells = table.getElementsByTagName("td");
for (var i = 0; i < styletab.length; i++) {
styletab[i].style.fontSize = "12px";
styletab[i].style.color = "blue";
}
} else {
var styletab = document.getElementsByTagName("tableStyles");
var cells = table.getElementsByTagName("td");
for (var i = 0; i < styletab.length; i++) {
styletab[i].style.fontSize = "12px";
styletab[i].style.color = "red";
}
}
I'd suggest:
Array.prototype.forEach.call(document.querySelectorAll('#tableStyles tr'), function (tr) {
tr.classList.add((tr.rowIndex%2 === 0 ? 'even' : 'odd'));
});
This presumes you have styles set, in CSS, for tr.odd and tr.even; also that you're using a relatively up-to-date browser; Internet Explorer 8+ for document.querySelectorAll(), and Internet Explorer 9+ for Array.prototype.forEach().
Array.prototype.forEach.call(document.querySelectorAll('#tableStyles tr'), function(tr) {
// rowIndex is the index of the current <tr> in the table element:
tr.classList.add((tr.rowIndex % 2 === 0 ? 'even' : 'odd'));
});
.even {
color: red;
}
.odd {
color: blue;
}
<table id="tableStyles" border="1">
<th>Heading 1</th>
<th>Heading 2</th>
<th>Heading 3</th>
<tr>
<td>Odd</td>
<td>Odd</td>
<td>Odd</td>
</tr>
<tr>
<td>Even</td>
<td>Even</td>
<td>Even</td>
</tr>
<tr>
<td>Odd</td>
<td>Odd</td>
<td>Odd</td>
</tr>
<tr>
<td>Odd</td>
<td>Odd</td>
<td>Odd</td>
</tr>
</table>
Alternatively, if you wanted to stripe only those elements selected (without reference to the rowIndex):
Array.prototype.forEach.call(document.querySelectorAll('#tableStyles tbody tr'), function(tr, collectionIndex) {
// collectionIndex (regardless of name, it's the second argument) is
// the index of the current array-element in the array/collection:
tr.classList.add((collectionIndex % 2 === 0 ? 'even' : 'odd'));
});
Array.prototype.forEach.call(document.querySelectorAll('#tableStyles tbody tr'), function(tr, collectionIndex) {
tr.classList.add((collectionIndex % 2 === 0 ? 'even' : 'odd'));
});
.even {
color: red;
}
.odd {
color: blue;
}
<table id="tableStyles" border="1">
<thead>
<tr>
<th>Heading 1</th>
<th>Heading 2</th>
<th>Heading 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Odd</td>
<td>Odd</td>
<td>Odd</td>
</tr>
<tr>
<td>Even</td>
<td>Even</td>
<td>Even</td>
</tr>
<tr>
<td>Odd</td>
<td>Odd</td>
<td>Odd</td>
</tr>
<tr>
<td>Odd</td>
<td>Odd</td>
<td>Odd</td>
</tr>
</tbody>
</table>
From the code I can see that you are new to JS. So I think it is good to point out where you are going wrong, than fixing the whole thing for you.
//Here you are creating a function to return true or false using a function which
//already returning true or false.
var isEven = function(someNumber) {
return (someNumber%2 == 0) ? true : false;
};
//above can be reduced to this.
(someNumber%2==0); //will return true if even and false if odd.
// The syntax of if statement is wrong. It should be if (statement) { do stuff here...}
// Notice the difference between '=' and '=='. The first assigns value and the second checks if both sides are same.
// The isEven function should have an input to give either true or false.
// Finally you should first get the rows in the table as an array and loop through it and then do this if statement.
if isEven = true {
var styletab = document.getElementsByTagName("tableStyles");
var cells = table.getElementsByTagName("td");
for (var i = 0; i < styletab.length; i++) {
styletab[i].style.fontSize = "12px";
styletab[i].style.color = "blue";
}
} else {
var styletab = document.getElementsByTagName("tableStyles");
var cells = table.getElementsByTagName("td");
for (var i = 0; i < styletab.length; i++) {
styletab[i].style.fontSize = "12px";
styletab[i].style.color = "red";
}
}
// the above should be organised in the format below.
var table = ;//get the table here.
var rows = ;//get the rows in the table here.
for (i in rows) {
var row = rows[i]; //get the current row
var cells = ;//get cells from the current row
if(i%2==0) {
//set formatting for the cells here if the row number is even.
} else {
//set formatting for the cells here if the row number is odd.
}
}
Make sure you are absolutely sure of how the selectors (getElementById etc) work and what do they return so that you can use them correctly. for example getElementsByTagName searches based on the tag name ('div' 'table' etc) but getElementById searches by the id of the tags - 'tableStyles' in this case. Hope I pointed you in the right direction.
Final Correct answer provided by Balamurugan Soundarara
//Here we are searching for the document for element with the id 'tableStyles'. This returns only one DOM element.
var table = document.getElementById("tableStyles");
//Here we are searching the table element for all elements of the tag 'tbody'. This returns an array of elements. Here there is only one so we just use the first one (hence the [0] at the end)
var body = table.getElementsByTagName("tbody")[0];
//Here we are searching the body element for all elements of the tag 'tr'. This returns an array of row elements.
var rows = body.getElementsByTagName("tr");
//Here we are looping through the elements in the rows array.
for (var i=0 ; i<rows.length; i++) {
//Here we select the nth row in the array based on the loop index.
var row = rows[i];
//Here we are searching the row element for all elements of the tag 'td'. This returns an array of cells in the row.
var cells = row.getElementsByTagName("td");
//We are looping through all the cells in the array.
for(var j=0; j<cells.length; j++) {
//set the fontsize
cells[j].style.fontSize = "12px";
//check if the row is even. see how we dont need the isEven function. you can directly use the == function with the modulo operator.
if( i%2==0 ) {
//if it is even then the color is set to blue
cells[j].style.color = "blue";
} else {
//if it is even then the color is set to blue
cells[j].style.color = "red";
}
}
}
http://jsfiddle.net/ar5suz2g/4/

Javascript highest number in each tr, skip 3 columns

I have a table, that will add a class to the highest number in each tr.
I want it to skip the first 3 columns and not search them. And then if there are multiple of the highest then bold those too.
I will paste code here as well as fiddle.
HTML
<style>
.highest {
font-weight: bold;
}
</style>
<table width="300">
<tr>
<th>no</th>
<th>no</th>
<th>no</th>
<th>yes</th>
<th>yes</th>
<th>yes</th>
</tr>
<tr>
<td>150</td>
<td>name</td>
<td>10.5</td>
<td>1.5</td>
<td>12</td>
<td>9.3</td>
</tr>
<tr>
<td>12.0</td>
<td>name</td>
<td>150</td>
<td>150</td>
<td>13.5</td>
<td>150</td>
</tr>
<tr>
<td>160</td>
<td>name</td>
<td>115</td>
<td>15</td>
<td>11</td>
<td>160</td>
</tr>
<tr>
<td>145</td>
<td>name</td>
<td>151</td>
<td>12</td>
<td>18</td>
<td>18</td>
</tr>
</table>
JAVASCRIPT
jQuery(function($) {
$.fn.max = function(callback) {
var max = null,
maxIndex = null;
this.each(function() {
var value = callback.call(this);
if (+value === value) {
if (!max || value > max) {
max = value;
maxIndex = $(this).index();
}
}
});
return max !== null ? this.eq(maxIndex) : $();
};
}(jQuery));
$('tr').each(function()
$(this).children('td').max(function() {
var value = +$(this).text();
if (!isNaN(value)) {
return value;
}
}).addClass('highest');
});
FIDDLE
http://jsfiddle.net/65S7N/96/
Just add a selector as a parameter to the plugin, and filter by that :
jQuery(function($) {
$.fn.max = function(selector) {
var elems = $();
this.each(function() {
var max = 0,
ele = $(this).find(selector).each(function(i,el) {
var n = parseFloat($(el).text());
if ( n > max ) max = n;
}).filter(function() {
return parseFloat($(this).text()) === max;
});
elems = elems.add(ele);
});
return elems;
};
}(jQuery));
$('tr').max('td:gt(2)').addClass('highest');
FIDDLE
To skip the first 3 columns, use:
$(this).children('td').filter(function(i) {
return i > 2;
}).max(...)
The filter function receives the zero-based position of the element within the collection.
If you want to highlight multiple entries that have the max value, maxIndex needs to be an array, not a single value. When value === max, push the current index onto the array. Or make it a jQuery collection of elements, rather than indexes, and add the current element to it.
$('tr').each(function(){
var this = $(this);
var max = -Infinity;
var indexes = [];
this.find('td:gt(2)').each(function(index){
var this_num = ($(this).text() >> 0);
if ( max < this_num ) {
max = this_num;
indexes = [index];
} else if (max == this_num ) {
indexes.push(this_num);
}
});
$(indexes).each(function(index){
this.find('td:eq('+index+')').addClass('highest');
});
});
should work.. haven't tested :|

Iterate over table cells, re-using rowspan values

I have a simple HTML table, which uses rowspans in some random columns. An example might look like
A | B |
---|---| C
D | |
---| E |---
F | | G
I'd like to iterate over the rows such that I see rows as A,B,C, D,E,C, then F,E,G.
I think I can probably cobble together something very convoluted using cell.index() to check for "missed" columns in later rows, but I'd like something a little more elegant...
without jquery:
function tableToMatrix(table) {
var M = [];
for (var i = 0; i < table.rows.length; i++) {
var tr = table.rows[i];
M[i] = [];
for (var j = 0, k = 0; j < M[0].length || k < tr.cells.length;) {
var c = (M[i-1]||[])[j];
// first check if there's a continuing cell above with rowSpan
if (c && c.parentNode.rowIndex + c.rowSpan > i) {
M[i].push(...Array.from({length: c.colSpan}, () => c))
j += c.colSpan;
} else if (tr.cells[k]) {
var td = tr.cells[k++];
M[i].push(...Array.from({length: td.colSpan}, () => td));
j += td.colSpan;
}
}
}
return M;
}
var M = tableToMatrix(document.querySelector('table'));
console.table(M.map(r => r.map(c => c.innerText)));
var pre = document.createElement('pre');
pre.innerText = M.map(row => row.map(c => c.innerText).join('\t')).join('\n');
document.body.append(pre);
td {
border: 1px solid rgba(0,0,0,.3);
}
<table>
<tr>
<td colspan=2>A</td>
<td rowspan=2>B</td>
</tr>
<tr>
<td>C</td>
<td rowspan=3>D</td>
</tr>
<tr>
<td rowspan=2>E</td>
<td rowspan=4>F</td>
</tr>
<tr></tr>
<tr>
<td rowspan=2 colspan=2>G</td>
</tr>
<tr></tr>
<tr>
<td rowspan=3 colspan=3>H</td>
</tr>
<tr></tr>
<tr></tr>
<tr>
<td colspan=3>I</td>
</tr>
</table>
Try this:
<table id="tbl">
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td colspan="2" rowspan="2">A</td>
<td rowspan="2">C</td>
</tr>
<tr>
<td rowspan="2">E</td>
</tr>
<tr>
<td>F</td>
<td>G</td>
</tr>
</table>
Script:
var finalResult = '';
var totalTds = $('#tbl TR')[0].length;
var trArray = [];
var trArrayValue = [];
var trIndex = 1;
$('#tbl TR').each(function(){
var currentTr = $(this);
var tdIndex = 1;
trArray[trIndex] = [];
trArrayValue[trIndex] = [];
var tdActuallyTraversed = 0;
var colspanCount = 1;
$('#tbl TR').first().children().each(function(){
if(trIndex > 1 && trArray[trIndex - 1][tdIndex] > 1)
{
trArray[trIndex][tdIndex] = trArray[trIndex - 1][tdIndex] - 1;
trArrayValue[trIndex][tdIndex] = trArrayValue[trIndex - 1][tdIndex];
finalResult = finalResult + trArrayValue[trIndex][tdIndex];
}
else
{
if(colspanCount <= 1)
{
colspanCount = currentTr.children().eq(tdActuallyTraversed).attr('colspan') != undefined ? currentTr.children().eq(tdActuallyTraversed).attr('colspan') : 1;
}
if(colspanCount > 1 && tdIndex > 1)
{
trArray[trIndex][tdIndex] = currentTr.children().eq(tdActuallyTraversed + colspanCount).attr('rowspan') != undefined ?currentTr.children().eq(tdActuallyTraversed + colspanCount).attr('rowspan') : 1;
trArrayValue[trIndex][tdIndex] = trArrayValue[trIndex][tdIndex - 1];
colspanCount--;
}
else
{
trArray[trIndex][tdIndex] = currentTr.children().eq(tdActuallyTraversed).attr('rowspan') != undefined ?currentTr.children().eq(tdActuallyTraversed).attr('rowspan') : 1;
trArrayValue[trIndex][tdIndex] = currentTr.children().eq(tdActuallyTraversed).html();
tdActuallyTraversed++;
}
finalResult = finalResult + trArrayValue[trIndex][tdIndex];
}
tdIndex++;
});
trIndex++;
});
alert(finalResult);
Fiddle
i am not sure about the performance, but it works well.
what I understood with your question is: You want to split the merged cell with same value and then iterate the table simply by row.
I've created a JSFiddle that will split the merged cells with the same value. Then you'll have a table that can be iterated simply by rows to get the desired output that you specified.
See it running here http://jsfiddle.net/9PZQj/3/
Here's the complete code:
<table id="tbl" border = "1">
<tr>
<td>A</td>
<td>B</td>
<td rowspan="2">C</td>
</tr>
<tr>
<td>D</td>
<td rowspan="2">E</td>
</tr>
<tr>
<td>F</td>
<td>G</td>
</tr>
</table>
<br>
<div id="test"> </div>
Here's the jquery that is used to manipulate the table's data.
var tempTable = $('#tbl').clone(true);
var tableBody = $(tempTable).children();
$(tableBody).children().each(function(index , item){
var currentRow = item;
$(currentRow).children().each(function(index1, item1){
if($(item1).attr("rowspan"))
{
// copy the cell
var item2 = $(item1).clone(true);
// Remove rowspan
$(item1).removeAttr("rowspan");
$(item2).removeAttr("rowspan");
// last item's index in next row
var indexOfLastElement = $(currentRow).next().last().index();
if(indexOfLastElement <= index1)
{
$(currentRow).next().append(item2)
}
else
{
// intermediate cell insertion at right position
$(item2).insertBefore($(currentRow).next().children().eq(index1))
}
}
});
console.log(currentRow)
});
$('#test').append(tempTable);
You can use this Gist. It supports all the requirements by W3C, even "rowspan=0" (which seems to be only supported by Firefox).

Finding column index using jQuery when table contains column-spanning cells

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?
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;
};
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);
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);
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.
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;
};
​

Categories

Resources