Jquery - Sum of each same class li value - javascript

Currently I'm Developing an Invoice app with php , mysql & jquery. I want to show some details with jquery. I have dynamically created tables with dynamic data.
<table class="report_table">
<tr>
<td class="items_id">
<ul>
<li class="KKTF0">KKTF0</li>
<li class="PEN01">PEN01</li>
</ul>
</td>
<td class="items_qty">
<ul>
<li class="KKTF0">1</li>
<li class="PEN01">2</li>
</ul>
</td>
</tr>
</table>
<table class="report_table">
<tr>
<td class="items_id">
<ul>
<li class="BKK01">BKK01</li>
<li class="KKTF0">KKTF0</li>
<li class="PEN01">PEN01</li>
</ul>
</td>
<td class="items_qty">
<ul>
<li class="BKK01">4</li>
<li class="KKTF0">2</li>
<li class="PEN01">3</li>
</ul>
</td>
</tr>
</table>
li classes are dynamically created. my jquery code
jQuery(document).ready(function() {
$('.report_table').each(function() {
$('.items_id ul li').each(function() {
$(this).addClass($(this).text());
var className = $(this).attr("class");
$(this).parents('tr').find('td.items_qty li').eq($(this).index()).addClass(className);
});
});
});
I want this result
<table>
<tr>
<th>Item Id</th>
<th>Sum of Item</th>
</tr>
<tr>
<td>KKTF0</td>
<td>3</td>
</tr>
<tr>
<td>PEN01</td>
<td>5</td>
</tr>
<tr>
<td>BKK01</td>
<td>4</td>
</tr>
</table>
I don't have any idea. please help me... Thanks.

Pretty short solution:
var data = {};
$('.report_table .items_qty li').each(function() {
data[this.className] = (data[this.className] || 0) + +$(this).text();
});
var table = '<table class="result"><tr><tr><th>Item Id</th><th>Sum of Item</th></tr>' +
$.map(data, function(qty, key) {
return '<td>' + key + '</td><td>' + qty + '</td>';
}).join('</tr><tr>') + '</tr></table>';
http://jsfiddle.net/VF7bz/
Brief explanation:
1). each collects the data into an object:
{"KKTF0":3,"PEN01":5,"BKK01":4}
2). map creates an array:
["<td>KKTF0</td><td>3</td>","<td>PEN01</td><td>5</td>","<td>BKK01</td><td>4</td>"]
3). array items are joined into a string using </tr><tr> as separator.

Create an array of "items" and increment the associated quantity of each as you loop through every li. Then output the table.
function sum() {
// This will hold each category and value
var sums = new Array();
$('li').each(function() {
var item = new Object();
// Get category
item.category = $(this).attr('class');
// Get count
if (isFinite($(this).html())) {
item.count = parseInt($(this).html());
}
else {
// Skip if not a number
return;
}
// Find matching category
var exists = false;
for (var i = 0; i < sums.length; i++) {
if (sums[i].category == item.category) {
exists = true;
break;
}
}
// Increment total count
if (exists) {
sums[i].count += item.count;
}
else {
// Add category if it doesn't exist yet
sums.push(item);
}
});
var table = '<table><tr><th>Item Id</th><th>Sum of Item</th></tr><tbody>';
// Add rows to table
for (var i = 0; i < sums.length; i++) {
table += '<tr><td>' + sums[i].category + '</td><td>'
+ sums[i].count + '</td></tr>';
}
// Close table
table += '</tbody></table>';
// Append table after the last table
$('table :last').after(table);
}

Please omit the jquery code that you have posted in your question and use the one below:
Complete Jquery Solution:
Tested and Working
$(document).ready(function() {
//Create table to fill with data after last report table
$('<table id="sumtable"><th>Item Id</th><th>Sum of Item</th></table>').insertAfter($('.report_table').last());
//Loop through each report table, fetch amount and update sum in '#sumtable'
$('.report_table').each(function(){
var currtable = $(this);
$(this).find('.items_id ul li').each(function(){
//cache obj for performance
var curritem = $(this);
var itemid = curritem.html();
var itemvalue = parseInt(currtable.find('.items_qty ul li:eq('+curritem.index()+')').html());
var sumrow = $('#sumtable tbody').find('tr.'+itemid);
if(sumrow.length == 0){
//no rows found for this item id in the sum table, let's insert it
$('#sumtable tbody').append('<tr class="'+itemid+'"><td>'+itemid+'</td><td>'+itemvalue+'</td></tr>');
} else {
//Row found, do sum of value
sumrow.find('td').eq(1).html(parseInt(sumrow.find('td').eq(1).html())+itemvalue);
console.log(sumrow.find('td').eq(1).html());
}
});
})
});
DEMO: http://jsfiddle.net/N3FdB/

I am using .each loop on all li and store the values in the Object variable as key-value pairs.
Then, looping over created object properties building the desired table.
var resultObj = {};
$('li').each(function (idx, item) {
var $item = $(item);
var prop = $item.attr('class');
if (!resultObj[prop]) {
resultObj[prop] = 0;
}
var parsedVal = parseInt($item.text(), 10);
resultObj[prop] += isNaN(parsedVal) ? 0 : parsedVal;
});
var $resultTable = $('<table />');
$resultTable.append('<tr><th>Item Id</th><th>Sum of Item</th></tr>');
for (var key in resultObj) {
var $row = $('<tr />');
$row.append($('<td />', {
text: key
}))
.append($('<td />', {
text: resultObj[key]
}));
$resultTable.append($row);
}
$('body').append($resultTable);
Have a look at this FIDDLE.

Related

How to get old value and new value in Javascript?

I have a table grid, which is editable using Javascript, when I click on that particular field. I can change the value and update the old value.
How can I get old value and also the new value for logging purposes?
<s:iterator var="posting" value="PostLookup">
<tr class="update-rel">
<td id="${post.Id}"><input type="checkbox" /></td>
<td class="alignleft">${post.coin}</td>
<td class="alignleft" >${post.rate}</td>
<td class="alignleft">${posting.trainCode}</td>
<td class="alignleft"><fmt:formatDate pattern="HH:mm" value="${posting.postTime}" /></td>
<td class="alignleft">${posting.payMode}</td>
<td class="alignleft">${posting.payModeSub}</td>
</tr>
</s:iterator>
JavaScript Making rows editable
function activateTableEditing() {
$(document).ready(function() {
var rowIndex;
var columnIndex;
// get dynamic values from the server through a json call to be displayed inside the drop down box
var jsonObject = getJSONObject('ajax/fetchpayMode.action', 'Pay Modes');
var payModes = jsonObject.payModes;
$('#tablePostLookup tbody td').on('click', function(e) {
rowIndex = $(this).parent().index('#tablePostLookup tbody tr');
columnIndex = $(this).index('#tablePostLookup tbody tr:eq(' + rowIndex + ') td');
//console.log('Row ' + rowIndex + ' and column ' + columnIndex + ' is clicked ...');
if (columnIndex == 2 || columnIndex == 3 || columnIndex == 4) {
editInputBox(e, $(this).parent(), rowIndex, columnIndex);
}
if (columnIndex == 5) {
editCombobox(e, $(this).parent(), rowIndex, columnIndex, payMode);
}
if (columnIndex == 6) {
var payModes = $(this).parent().children('td:eq(5)').text();
jsonObject = getJSONObject('ajax/fetchpayModeSub.action?payModeSub=' + payMode, 'paymode sub ');
var paymentModeSub = jsonObject.paymentModeSub;
editCombobox(e, $(this).parent(), rowIndex, columnIndex, paymentModeSub);
}
});
});
}
Getting current values - When update button is clicked.
function savePostLookup(e, action) {
var countRowSelected = 0;
$('#tablePostLookup tbody tr').each(function() {
var result = $(this).children('td').eq(0).children('input[type=checkbox]').eq(0).is(':checked');
if (result) {
++countRowSelected;
e.preventDefault();
var id = $(this).find('td:eq(0)').eq(0).attr('id');
var coin = $(this).find('td:eq(1)').text();
var rate = $(this).find('td:eq(2)').text();
var trainCode = $(this).find('td:eq(3)').text();
var postTime = $(this).find('td:eq(4)').text();
var payMode = $(this).find('td:eq(5)').text();
var payModeSub = $(this).find('td:eq(6)').text();
createJSONObject(id, coin, rate, trainCode, postTime, payMode, payModeSub);
}
});
This is what you could potentially do. Create an object with the following key values pair.
{
"td1": [
{
"oldVlaue": "old",
"newValue": "new"
}
],
"td2": [
{
"oldVlaue": "old1",
"newValue": "new1"
}
]
}
So each time you click on some a table value, you can get the value from the event.target and you can also get which table element is clicked. Just update the value in your JSON object with the values you get.
As I said, this could potenitally be a way to keep track of the old or new values. Feel free to try something different or better.

jQuery/Javascript compare two tables against each other

I need to compare two HTML tables' rows assuming that data in first cell can be duplicated but data in second cell is always unique. I need to find whether first cell AND second cell in table1 is the same as data in first cell AND second cell in table2 for instance:
Table1:
<Table>
<tr>
<td>123</td>
<td>321</td>
</tr>
<tr>
<td>545</td>
<td>345</td>
</tr>
<tr>
<td>0</td>
<td>312</td>
</tr>
<tr>
<td>123</td>
<td>323331</td>
</tr>
</Table>
Second table:
<table>
<tr>
<td>545</td>
<td>345</td>
</tr>
<tr>
<td>545</td>
<td>3122</td>
</tr>
<tr>
<td>123</td>
<td>321</td>
</tr>
</table>
The result of this should be:
123 321 - good, do nothing
545 345 - good, do nothing
545 3122 - wrong its not in table1 <-
Here's what I've got so far...
$('#runCheck').click(function(){
var firstTable = $('#firstDiv table tr');
var secondTable = $('#secDiv table tr');
$(secondTable).each(function(index){
var $row = $(this);
var secTableCellZero = $row.find('td')[0].innerHTML;
var secTableCellOne = $row.find('td')[1].innerHTML;
$(firstTable).each(function(indexT){
if ($(this).find('td')[0].innerHTML === secTableCellZero){
if ($(this).find('td')[1].innerHTML !== secTableCellOne){
$('#thirdDiv').append("first: " + secTableCellZero + " second: " + secTableCellOne+"<br>");
}
}
});
});
});
Where am I going it wrong?
Just to clarify once again:
2nd table says :
row1 - john|likesCookies
row2 - peter|likesOranges
1st table says :
row1 - john|likesNothing
row2 - john|likesCookies
row3 - steward|likesToTalk
row4 - peter|likesApples
now it should say :
john - value okay
peter - value fail.
a lot alike =VLOOKUP in excel
Check this working fiddle : here
I've created two arrays which store values in each row of tables 1 and 2 as strings. Then I just compare these two arrays and see if each value in array1 has a match in array 2 using a flag variable.
Snippet :
$(document).ready(function() {
var table_one = [];
var table_two = [];
$("#one tr").each(function() {
var temp_string = "";
count = 1;
$(this).find("td").each(function() {
if (count == 2) {
temp_string += "/";
}
temp_string = temp_string + $(this).text();
count++;
});
table_one.push(temp_string);
});
$("#two tr").each(function() {
var temp_string = "";
count = 1;
$(this).find("td").each(function() {
if (count == 2) {
temp_string += "/";
temp_string = temp_string + $(this).text();
} else {
temp_string = temp_string + $(this).text();
}
count++;
});
table_two.push(temp_string);
});
var message = "";
for (i = 0; i < table_two.length; i++) {
var flag = 0;
var temp = 0;
table_two_entry = table_two[i].split("/");
table_two_cell_one = table_two_entry[0];
table_two_cell_two = table_two_entry[1];
for (j = 0; j < table_one.length; j++) {
table_one_entry = table_one[j].split("/");
table_one_cell_one = table_one_entry[0];
table_one_cell_two = table_one_entry[1];
console.log("1)" + table_one_cell_one + ":" + table_one_cell_two);
if (table_two_cell_one == table_one_cell_one) {
flag++;
if (table_one_cell_two == table_two_cell_two) {
flag++;
break;
} else {
temp = table_one_cell_two;
}
} else {}
}
if (flag == 2) {
message += table_two_cell_one + " " + table_two_cell_two + " found in first table<br>";
} else if (flag == 1) {
message += table_two_cell_one + " bad - first table has " + temp + "<br>";
} else if (flag == 0) {
message += table_two_cell_one + " not found in first table<br>";
}
}
$('#message').html(message);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<hr>
<table id="one">
<tr>
<td>123</td>
<td>321</td>
</tr>
<tr>
<td>545</td>
<td>345</td>
</tr>
<tr>
<td>0</td>
<td>312</td>
</tr>
<tr>
<td>123</td>
<td>323331</td>
</tr>
</table>
<hr>
<table id="two">
<tr>
<td>545</td>
<td>345</td>
</tr>
<tr>
<td>545</td>
<td>3122</td>
</tr>
<tr>
<td>123</td>
<td>321</td>
</tr>
</table>
<hr>
<div id="message">
</div>
</div>
If I understand your requirements, it would be easier to read the first table and store the couples as strings: 123/321, 545/345, etc...
Than you can read the second table and remove from the first list all the rows found in both.
What remains in the list are couples that do not match.
From purely an efficiency standpoint if you loop through the first table just once and create an object using the first cell value as keys and an array of values for second cells, you won't have to loop through that table numerous times
this then makes the lookup simpler also
var firstTable = $('#firstDiv table tr');
var secondTable = $('#secDiv table tr');
var firstTableData = {}
firstTable.each(function() {
var $tds = $(this).find('td'),
firstCellData = $tds.eq(0).html().trim(),
secondCellData == $tds.eq(1).html().trim();
if (!firstTableData[firstCellData]) {
firstTableData[firstCellData] = []
}
firstTableData[firstCellData].push(secondCellData)
})
$(secondTable).each(function(index) {
var $tds = $(this).find('td');
var secTableCellZero = $tds.eq(0).html().trim();
var secTableCellOne = $tds.eq(1).html().trim();
if (!firstTableData.hasOwnProperty(secTableCellZero)) {
console.log('No match for first cell')
} else if (!firstTableData[secTableCellZero].indexOf(secTableCellOne) == -1) {
console.log('No match for second cell')
}
});
I'm not sure what objective is when matches aren't found

How do I select rows that correspond to a rowspan?

I have a dynamically generated table that I am trying to change the background color of certain rows in. Sometimes there are rows with rowspans and I cant figure out how to get all of the rows that correspond to the one "row." I've googled my brains out and found this jsfiddle which is pretty close to what i need (in a logic sense)
http://jsfiddle.net/DamianS1987/G2trb/
basically i have something like this:
and I want to be able to highlight full rows at a time like this:
but the only highlighting i can achieve on rowspan rows is this:
Here is my code (different from jsfiddle but essentially same logic)
CSS:
.highlightedClass{
background-color: #AEAF93;
}
HTML:
<table border="1" class="altTable">
<th>ID</th>
<th>NAME</th>
<th>Miles</th>
<th>WORK</th>
<tbody>
<tr>
<td class="td_id">999B</td>
<td class="td_name ">John</td>
<td class="td_cumMiles">702.4</td>
<td class="td_workEvent">Y</td>
</tr><tr>
<td class="td_id" rowspan="2">111A</td>
<td class="td_name">Tom</td>
<td class="td_cumMiles">446.5</td>
<td class="td_workEvent">Y</td>
</tr><tr>
<td class="td_name">Becky</td>
<td class="td_cumMiles">446.5</td>
<td class="td_workEvent">A</td>
</tr>
</tbody>
JAVASCRIPT:
for(var j=0; j < inspection.length; j++){
var $tr = $('<tr></tr>');
var $td_id = $('<td></td>').addClass('td_id').html(inspection.id);
$tr.append($td_id);
$table.append($tr);
$.each(inspection[i], function(index, value){
var $td_name, $td_miles,$td_workEvent;
if(index > 0){
var $2nd_tr = $('<tr></tr>');
$td_name = $('<td></td>').addClass('td_name').html(value.stationSt);
$td_miles = $('<td></td>').addClass('td_miles').html(value.miles);
$td_workEvent = $('<td></td>').addClass('td_workEvent').html(value.code);
$2nd_tr.append($td_name);
$2nd_tr.append($td_miles);
$2nd_tr.append($td_workEvent);
$table.append($2nd_tr);
$td_id.attr('rowSpan',index+1);
if($td_id.text() === content().id){
$2nd_tr.addClass("highlightedClass");
}else{
if($2nd_tr.hasClass("highlightedClass")){
$2nd_tr.removeClass('highlightedClass');
}
}
$('#workevent').on('click', function(){
$tr.removeClass('highlightedClass');
});
}else{
$td_name = $('<td></td>').addClass('td_name').html(value.stationSt);
$td_miles = $('<td></td>').addClass('td_miles').html(value.miles);
$td_workEvent = $('<td></td>').addClass('td_workEvent').html(value.code);
$tr.append($td_name);
$tr.append($td_miles);
$tr.append($td_workEvent);
$table.append($tr);
if($td_id.text() === content().id){
$tr.addClass("highlightedClass");
}else{
if($tr.hasClass("highlightedClass")){
$tr.removeClass('highlightedClass');
}
}
$('#workevent').on('click', function(){
$tr.removeClass('highlightedClass');
});
}
});
You need to look for any rowspan= attribute in the selected tds and if present, select the subsequent row(s) as well. This example should support any rowspan value (it appends subsequent rows based on the rowspan count):
Final version: JSFiddle: http://jsfiddle.net/TrueBlueAussie/G2trb/22/
$('td').bind('click', function () {
var $row = $(this).closest('tr');
// What row index is the clicked row?
var row = $row.index(); // Subtract heading row
// Does the clicked row overlap anything following?
var rowspan = ~~$row.find('td[rowspan]').attr('rowspan') || 0;
// Get all rows except the heading, up to the last overlapped row
var $rows = $row.parent().children().slice(1, row + rowspan);
row--; // Subtract the heading row we excluded
// Now see if any preceding rows overlap the clicked row
$rows.each(function (i) {
var $tr = $(this);
// Only check first rowspan of a row
var rowspan = ~~$tr.find('td[rowspan]').attr('rowspan') || 0;
// If the rowspan is before the clicked row but overlaps it
// Or it is a row we included after the selection
if ((i < row && ((rowspan + i) > row)) || i > row) {
$row = $row.add($tr);
}
});
$row.toggleClass('green');
});
First attempt JSFiddle: http://jsfiddle.net/TrueBlueAussie/G2trb/18/
$('td').bind('click', function () {
var $td = $(this);
var $row = $td.closest('tr');
var $tds = $row.find('td');
$tds.each(function(){
var rowspan = ~~$(this).attr('rowspan');
while (--rowspan > 0){
$row = $row.add($row.next());
}
});
$row.toggleClass('green');
});
It needs to be tweaked for the child row that sits under a previous rowspan, but am working on that too.
Notes:
~~ is a shortcut to convert a string to an integer.
the || 0 converts undefined values to 0.
$row = $row.add($tr) is appending row elements to a jQuery collection/object.
In fixing my issue (going off what TrueBlueAussie gave me) I came up with the following solution.
CSS:
.highlightedClass{
background-color: #AEAF93;
}
HTML:
<table border="1" class="altTable">
<th>ID</th>
<th>NAME</th>
<th>Miles</th>
<th>WORK</th>
<tbody>
<tr>
<td class="td_id">999B</td>
<td class="td_name ">John</td>
<td class="td_cumMiles">702.4</td>
<td class="td_workEvent">Y</td>
</tr><tr>
<td class="td_id" rowspan="2">111A</td>
<td class="td_name">Tom</td>
<td class="td_cumMiles">446.5</td>
<td class="td_workEvent">Y</td>
</tr><tr>
<td class="td_name">Becky</td>
<td class="td_cumMiles">446.5</td>
<td class="td_workEvent">A</td>
</tr>
</tbody>
JAVASCRIPT:
for(var j=0; j < inspection.length; j++){
var $tr = $('<tr></tr>');
var $td_id = $('<td></td>').addClass('td_id').html(inspection.id);
$tr.append($td_id);
$table.append($tr);
$.each(inspection[i], function(index, value){
var $td_name, $td_miles,$td_workEvent;
if(index > 0){
var $2nd_tr = $('<tr></tr>');
$td_name = $('<td></td>').addClass('td_name').html(value.stationSt);
$td_miles = $('<td></td>').addClass('td_miles').html(value.miles);
$td_workEvent = $('<td></td>').addClass('td_workEvent').html(value.code);
$2nd_tr.append($td_name);
$2nd_tr.append($td_miles);
$2nd_tr.append($td_workEvent);
$table.append($2nd_tr);
$td_id.attr('rowSpan',index+1);
if($td_id.text() === content().td_id){
$2nd_tr.addClass("highlightedClass");
}else{
if($2nd_tr.hasClass("highlightedClass")){
$2nd_tr.removeClass('highlightedClass');
}
}
$('#workevent').on('click', function(){
if($td_id.text() === content().td_id){
$2nd_tr.addClass("highlightedClass");
}else{
if($2nd_tr.hasClass("highlightedClass")){
$2nd_tr.removeClass("highlightedClass");
}
}
});
}else{
$td_name = $('<td></td>').addClass('td_name').html(value.stationSt);
$td_miles = $('<td></td>').addClass('td_miles').html(value.miles);
$td_workEvent = $('<td></td>').addClass('td_workEvent').html(value.code);
$tr.append($td_name);
$tr.append($td_miles);
$tr.append($td_workEvent);
$table.append($tr);
if($td_id.text() === content().id){
$tr.addClass("highlightedClass");
}else{
if($tr.hasClass("highlightedClass")){
$tr.removeClass('highlightedClass');
}
}
}
});
This was in a nested if statement. below like three if statements, i put this:
$('#workevent').on('click', function(){
var flag= false;
$('#altTable > tbody > tr').each(function() {
$td_id= $(this).find('.td_id');
if($td_id.text() === ''){
if(flag === true){
$(this).addClass("highlightedClass");
flag = true;
}
}else{
if(if($td_id.text() === content().idtd_id{){
if($(this).hasClass("highlightedClass")){
flag = true;
}else{
$(this).addClass("highlightedClass");
flag = true;
}
}else{
flag = false;
if($(this).hasClass("highlightedClass")){
$(this).removeClass("highlightedClass");
}
}
}
});
});
This is what worked for me. I selected TrueBlueAussie's answer because it helped get me my specific answer. Hopefully both answers can help someone else in the future.

How to check for duplicate row using javascript

how do I check for duplicate row in a table using javascript? The following is part of my code:
<table id="t1">
<tr>
<td>Text A</td>
<td>Text B</td>
<td>Cbx A</td>
</tr>
<% int count1 = -1;
for(int i=0; i<3; i++) { %>
<tr>
<td><input type="text" id="textA<%=i%>"></td>
<td><input type="text" id="textB<%=i%>"></td>
<td><select name="cbx_A<%=i%>">
<option value="A">Option1</option>
<option value="B">Option2</option>
</select>
</td
</tr>
<%count1 =i;
}%>
<tr>
<td><input type="button" onclick="check(<%=count1%>)" value="Check"></td>
</tr>
</table>
So based on this code, I will have 3 rows of text A,textB and cbxA. With that, how do I check whether user input the same values for 2 of the rows or all three rows?
I tried using servlet but theres too much work involve. So yeah is there a way to do this using java script instead?
Thanks in advance for any possible help.
Using this code it will check for duplication in one table column
then take all rows of table that are duplicated and put their ids in array
so you will get an array of rows id
but ur table has to have an id for each row
var columnNumber = 1;
var table = document.getElementById('t1');
var rowLength = table.rows.length;
var arrReocrds = new Array();
var arrCount = 0;
var listCount = 0;
var arr = new Array();
$('#t1 td:nth-child(' + colNumber + ')').each(function () {
var recordValue = $(this).html().trim();
var flagFirstTime = true;
//loop through table to check redundant of current record value
for (var i = 1; i < rowLength; i += 1) {
{
var row = table.rows[i];
var recordId = //put here row.id or anything that you can put it in the list
var cell = row.cells[colNumber - 1];
var value = cell.innerText.trim();
if (value == recordValue) {
if (!arr.contains(value)) {
if (flagFirstTime != true) {
arrReocrds[arrCount] = recordId;
arrCount++;
}
else
flagFirstTime = false;
}
else
break;
}
}
}
//create list for items in column
//to be sure that the item that has been taken and checked never be checked again by their other redundant records
arr[listCount] = recordValue;
listCount++;
});

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