Jquery Column toggle based on index() and custom attr issue - javascript

I have a table with two rows in header first row having colspan and second row having the second row headers see image below
I have a jquery function which takes all the table cell values from the second header row and adds it a div with checkboxes along with index numbers later which is used to toggle. 1st Column, 2nd Column and 3rd Column goes to separate div's named speed, cons, dest
Now the toggle works ok it checks the index number for the column and adds hidden to it and accordingly the colspan reduces to match the table format.
But whenever the 2nd Column and 3rd Column's first checkbox is clicked the table breaks I am trying to figure out the issue but not able to make it work. Any suggestions ?
Here is the fiddle please suggest
Below is the filter toggle for one of the div
$('.dest input[type=checkbox]').click(function() {
var index = $(this).attr('index');
$('.table thead .this_h th').eq(index).toggleClass('hidden');
var hidden = $('.table thead th.hidden')
$.each(hidden, function() {
var idx = $(this).index() + 1;
$.each($('.table tbody tr'), function() {
$(this).find('td').eq(idx).hide();
});
});
var visible = $('.table thead .this_h th:not(.hidden)');
$.each(visible, function() {
var idx = $(this).index() + 1;
$.each($('.table tbody tr'), function() {
$(this).find('td').eq(idx).show();
});
});
var length = 0;
var temp_name = '';
$(".table thead tr:nth-child(2)").find('th').each(function(e, a) {
if (temp_name == $(a).attr('name')) {
console.log($(a).attr('name'));
if ($(a).is(':visible')) {
length = length + 1;
}
}
else
{
console.log(temp_name);
$(".table thead tr:nth-child(1)").find("th[name=" + temp_name + "]").attr('colspan', length);
if ($(a).is(':visible')) {
length = 1;
temp_name = $(a).attr('name');
} else {
length = 0;
}
}
})
});

Here you are.
var tableArr = new Array();
var flag = 0;
var speed = new Array();
var speed_index = new Array();
var cons = new Array();
var cons_index = new Array();
var dest = new Array();
var dest_index = new Array();
// Gets the values from the table cell and creates the checkboxes
function get_values() {
if (flag == 0) {
flag = 1;
$.each(speed, function(i) {
$(".top-filter .speed").append('<input type=\'checkbox\' index=' + speed_index[i] + '> ' + speed[i] + '<br/>');
});
$.each(cons, function(i, val) {
$(".top-filter .cons").append('<input type=\'checkbox\' index=' + cons_index[i] + '> ' + cons[i] + '<br/>');
});
$.each(dest, function(i, val) {
$(".top-filter .dest").append('<input type=\'checkbox\' index=' + dest_index[i] + '> ' + dest[i] + '<br/>');
});
}
};
$(document).ready(function() {
// to push the values from cell to array
$('.table thead tr:nth-child(2) th').each(function(e, a) {
if ($(a).attr('name') == 'speed') {
speed.push($(this).text());
speed_index.push($(this).index());
} else if ($(a).attr('name') == 'cons') {
cons.push($(this).text());
cons_index.push($(this).index());
} else {
dest.push($(this).text());
dest_index.push($(this).index());
}
});
get_values();
$('input[type=checkbox]').click(function() {
var index = $(this).attr('index');
var name = $(this).parent().attr("class");
$('.table thead .this_h th').eq(index).toggleClass('hidden');
var hidden = $('.table thead th.hidden')
$.each(hidden, function() {
var idx = $(this).index() + 1;
$.each($('.table tbody tr'), function() {
$(this).find('td').eq(idx).hide();
});
});
var visible = $('.table thead .this_h th:not(.hidden)');
$.each(visible, function() {
var idx = $(this).index() + 1;
$.each($('.table tbody tr'), function() {
$(this).find('td').eq(idx).show();
});
});
var length = $(".table thead tr:nth-child(2)").find("th[name=" + name + "]").filter(':visible').length;
if (length === 0) {
$(".table thead tr:nth-child(1)").find("th[name=" + name + "]").addClass("hidden");
} else {
$(".table thead tr:nth-child(1)").find("th[name=" + name + "]").removeClass("hidden").attr('colspan', length);
}
});
});
.hidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<table class="table table-condensed table-striped table-bordered">
<thead>
<tr>
<th rowspan="2">Name</th>
<th name="speed" colspan="3">1st Column</th>
<th name="cons" colspan="4">2st Column</th>
<th name="dest" colspan="3">3st Column</th>
</tr>
<tr class="this_h">
<th name="speed">A</th>
<th name="speed">B</th>
<th name="speed">C</th>
<th name="cons">D</th>
<th name="cons">E</th>
<th name="cons">F</th>
<th name="cons">G</th>
<th name="dest">H</th>
<th name="dest">I</th>
<th name="dest">J</th>
</tr>
</thead>
<tbody>
<tr>
<td>John Doe</td>
<td>22</td>
<td>02</td>
<td>05</td>
<td>2</td>
<td>52</td>
<td>47</td>
<td>22</td>
<td>02</td>
<td>05</td>
<td>2</td>
</tr>
</tbody>
</table>
<div class="row top-filter">
<div class="col-xs-3">
<div class="speed">
</div>
</div>
<div class="col-xs-3">
<div class="cons">
</div>
</div>
<div class="col-xs-3">
<div class="dest">
</div>
</div>
</div>

Related

Unselect highlighted row

I have this table, and I can't seem to find out how to unselect marked field, if it's clicked again? So a double-click on id 2 would select->unselect.
function highlight_row() {
var table = document.getElementById('testresultsTable');
var cells = table.getElementsByTagName('td');
for (var i = 0; i < cells.length; i++) {
// Take each cell
var cell = cells[i];
// do something on onclick event for cell
cell.onclick = function () {
// Get the row id where the cell exists
var rowId = this.parentNode.rowIndex;
var rowsNotSelected = table.getElementsByTagName('tr');
for (var row = 0; row < rowsNotSelected.length; row++) {
rowsNotSelected[row].style.backgroundColor = "";
rowsNotSelected[row].classList.remove('selected');
}
var rowSelected = table.getElementsByTagName('tr')[rowId];
rowSelected.style.backgroundColor = "yellow";
rowSelected.className += " selected";
}
}
} //end of function
window.onload = highlight_row;
<table id="testresultsTable">
<thead>
<th>ID</th>
<th>Tests</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td>TESTRUN1</td>
</tr>
<tr>
<td>2</td>
<td>TESTRUN2</td>
</tr>
<tr>
<td>3</td>
<td>TESTRUN3</td>
</tr>
</tbody>
</table>
I thought about making some kind of count on the rowID, so if it's clicked more than once after each other, then it would toggle between select/unselect?
You can solve it by doing something similar to this, this will first check the selected row for the selected class and remove it if it is found, otherwise, it'll add it to the row you clicked. After that is done, this function will loop through all other rows, check if they aren't the clicked row and remove the selected state accordingly.
So now once you click, your code will look for selected on the row you clicked, if it is found, it'll remove that class to reset the styling, if it isn't found, it'll add the selected class. After this, the code will check all rows to see if they're not the selected row and style them accordingly.
function highlight_row() {
var table = document.getElementById('testresultsTable');
var cells = table.getElementsByTagName('td');
for (var i = 0; i < cells.length; i++) {
// Take each cell
var cell = cells[i];
// do something on onclick event for cell
cell.onclick = function() {
// Get the row id where the cell exists
var rowId = this.parentNode.rowIndex;
var rowsNotSelected = table.getElementsByTagName('tr');
for (var row = 0; row < rowsNotSelected.length; row++) {
if(row !== rowId) {
rowsNotSelected[row].style.backgroundColor = "";
rowsNotSelected[row].classList.remove('selected');
}
}
var rowSelected = table.getElementsByTagName('tr')[rowId];
if (rowSelected.classList.contains('selected')) {
rowSelected.style.backgroundColor = "";
rowSelected.classList.remove('selected');
} else {
rowSelected.style.backgroundColor = "yellow";
rowSelected.classList.add("selected");
}
}
}
} //end of function
window.onload = highlight_row;
<table id="testresultsTable">
<thead>
<th>ID</th>
<th>Tests</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td>TESTRUN1</td>
</tr>
<tr>
<td>2</td>
<td>TESTRUN2</td>
</tr>
<tr>
<td>3</td>
<td>TESTRUN3</td>
</tr>
</tbody>
</table>
Hope this helps!
function highlight_row() {
var table = document.getElementById('testresultsTable');
var cells = table.getElementsByTagName('td');
for (var i = 0; i < cells.length; i++) {
// Take each cell
var cell = cells[i];
// do something on onclick event for cell
cell.onclick = function () {
// Get the row id where the cell exists
var rowId = this.parentNode.rowIndex;
var rowsNotSelected = table.getElementsByTagName('tr');
for (var row = 0; row < rowsNotSelected.length; row++) {
if(row!==rowId){
rowsNotSelected[row].style.backgroundColor = "white";
rowsNotSelected[row].classList.remove('selected');
}
}
var rowSelected = table.getElementsByTagName('tr')[rowId];
if(rowSelected.classList.contains("selected")) {
rowSelected.style.backgroundColor = "";
rowSelected.classList.remove("selected");
}
else{
rowSelected.style.backgroundColor = "yellow";
rowSelected.classList.add("selected");
}
}
}
} //end of function
window.onload = highlight_row;
<table id="testresultsTable">
<thead>
<th>ID</th>
<th>Tests</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td>TESTRUN1</td>
</tr>
<tr>
<td>2</td>
<td>TESTRUN2</td>
</tr>
<tr>
<td>3</td>
<td>TESTRUN3</td>
</tr>
</tbody>
</table>
I'd do it like this
var selected;
(function () {
var rows = document.querySelectorAll('#testresultsTable > tbody > tr');
rows.forEach(tr => tr.addEventListener('click', () => {
if(selected === tr){
selected.classList.remove('selected');
selected = undefined;
}
else {
if(selected) selected.classList.remove('selected');
selected = tr;
tr.classList.add('selected');
}
}));
})();
tbody > tr {
cursor: pointer;
user-select: none;
}
tr.selected {
background-color: yellow;
}
<table id="testresultsTable">
<thead><th>ID</th><th>Tests</th></thead>
<tbody>
<tr><td>1</td><td>TESTRUN1</td></tr>
<tr><td>2</td><td>TESTRUN2</td></tr>
<tr><td>3</td><td>TESTRUN3</td></tr>
</tbody>
</table>

Find values in table cells with Javascript

I'm using a dynamic table in HTML, but I need to verify the values are not repeated. I'm trying to do it with the value inside the cell rather than the text. These are the values and what I have so far:
var tBody = $("#tablaAplicaciones > TBODY")[0];
//Add Row.
var row = tBody.insertRow(-1);
//Add Name cell.
var cell = $(row.insertCell(-1));
cell.html(nameCountry);
cell.val(idCountry);
//Add Country cell.
cell = $(row.insertCell(-1));
cell.html(nameCompany);
cell.val(idCompany);
if (($('#tablaApp tr > td:contains(' + countryName + ') + td:contains(' + companyName + ')').length) == 1) {
.
.
.
}
Welcome to Stack Overflow. Consider the following code.
$(function() {
var idCountry = "9";
var nameCountry = "United States";
var idCompany = "9";
var nameCompany = "Genentech";
var tBody = $("#tablaAplicaciones > tbody");
//Create Row
var row = $("<tr>");
//Add Country cell to Row
$("<td>", {
class: "name-country"
})
.data("id", idCountry)
.html(nameCompany)
.appendTo(row);
//Add Company cell to Row
$("<td>", {
class: "name-company"
})
.data("id", idCompany)
.html(nameCompany)
.appendTo(row);
// Assume vales are not in the table
var found = -1;
$("tr", tBody).each(function(i, el) {
// Test each row, if value is found set test to tue
if ($(".name-country", el).text().trim() == nameCountry) {
found = i;
}
if ($(".name-company", el).text().trim() == nameCompany) {
found = i;
}
});
if (found == -1) {
// If test is false, append the row to table
row.appendTo(tBody);
console.log("Row Added", row);
} else {
console.log("Values already in Table, row: " + found);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tablaAplicaciones">
<thead>
<tr>
<th>Country</th>
<th>Company</th>
</tr>
</thead>
<tbody>
<tr>
<td data-id="1" class="name-country">United States</td>
<td data-id="1" class="name-company">Apple Inc.</td>
</tbody>
</table>
Using .each(), you can iterate over each row and compare the values. A variable can be used as a flag to indicate if the needle was found in the haystack. If not found, you can append the row. Otherwise, do not add the row.
Hope that helps.

How to add the values to td of each row?

I have a values on hiddenTableRecord. Then I split the values by $$$ symbol. Then I want to add the value in td.
Here is what I tried
//Value i
$("#hiddenTableRecord").val("tq.StoreID$$$ IN('1001')$$$AND item.ItemLookupCode$$$ IN('115152')$$$AND item.ExtendedDescription$$$ IN('dsfdsfa')$$$");
if ($("#hiddenTableRecord").val().length > 0) {
var filterArray = $("#hiddenTableRecord").val().split('$$$');
var selectField;
var filterCommaValue;
alert(filterArray);
for (var i = 0; i < filterArray.length; i++) {
if (filterArray[i].length != 0) {
if (i % 2 == 0) {
selectField = filterArray[i];
//alert(selectField)
}
else {
filterCommaValue = filterArray[i];
}
$("#queryTable > tbody:last-child").append('<tr><td class="FieldNameID">' + selectField + '</td><td class="OperatorID"> IN(' + filterCommaValue + ')</td></tr>');
}
//alert(selectField);
}
}
Aspx code
<table class="table table-hover FilterTable" id="queryTable">
<thead>
<tr>
<th>Field Name</th>
<th>Values</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<asp:HiddenField ID="hiddenTableRecord" runat="server" />
But I didn't get the proper output like what i expect. I don't where i did mistake.
Expecting Result
tq.StoreID IN('1001')
AND item.ItemLookupCode IN('115152')
AND item.ExtendedDescription IN('dsfdsfa')
I want result like this.
Try the following code:
$("#hiddenTableRecord").val("tq.StoreID$$$ IN('1001')$$$AND item.ItemLookupCode$$$ IN('115152')$$$AND item.ExtendedDescription$$$ IN('dsfdsfa')");
if ($("#hiddenTableRecord").val().length > 0) {
var filterArray = $("#hiddenTableRecord").val().split('$$$');
for (i = 0; i < filterArray.length; i=i+2) {
var tr = document.createElement('TR');
var td1 = document.createElement('TD')
var td2 = document.createElement('TD')
td1.appendChild(document.createTextNode(filterArray[i]));
td2.appendChild(document.createTextNode(filterArray[i+1]));
tr.appendChild(td1);
tr.appendChild(td2)
$("#queryTable").append(tr);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="hiddenTableRecord" style="height:100px; width:250px;"></textarea>
<table id="queryTable">
<tr>
<th>Field Name</th>
<th>Values</th>
</tr>
</table>

Loop through html cells and perform a function if conditionals are met

var tableBody = document.getElementById("firstTableBody"),
secondTable = document.getElementById("secondTable");
function insertRow() {
var Row = tableBody.insertRow();
for (var c = 0; c < 3; c += 1) {
Row.insertCell(c);
}
var Fruits = ["Apples", "Oranges", "Strawberries"],
random_Fruits = Fruits[Math.floor(Math.random() * Fruits.length)];
Row.cells[0].innerHTML = random_Fruits;
Row.cells[1].innerHTML = 100;
var Sellbtn = document.createElement('button');
Sellbtn.innerHTML = "Sell"
Sellbtn.onclick = function Sell() {
if (secondTable.rows.length < 1) {
var Row = secondTable.insertRow();
for (var f = 0; f < 2; f += 1) {
Row.insertCell(f);
}
Row.cells[0].innerHTML = this.parentNode.parentNode.cells[0].innerHTML;
Row.cells[1].innerHTML = this.parentNode.parentNode.cells[1].innerHTML;
} else {
for (var i = 0; i < secondTable.rows.length; i += 1) {
if (secondTable.rows[i].cells[0].innerHTML === this.parentNode.parentNode.cells[0].innerHTML) {
secondTable.rows[i].cells[1].innerHTML = +this.parentNode.parentNode.cells[1].innerHTML;
} else {
var Rowz = secondTable.insertRow();
for (var k = 0; k < 4; k += 1) {
Rowz.insertCell(k);
}
Rowz.cells[0].innerHTML = this.parentNode.parentNode.cells[0].innerHTML;
Rowz.cells[1].innerHTML = this.parentNode.parentNode.cells[1].innerHTML;
}
}
}
}
Row.cells[2].appendChild(Sellbtn);
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<table border="1">
<thead>
<th>Item</th>
<th>Sold</th>
<th>
<button onclick="insertRow()">Insert</button>
</th>
</thead>
<tbody id="firstTableBody">
</tbody>
</table>
<table border="1">
<thead>
<th>Item</th>
<th>Sold</th>
</thead>
<tbody id="secondTable">
</tbody>
</table>
</body>
I insert a row with randomly inserted fruit name and a dynamically added button called sell. When I click on sell it should check if the fruit name of that row exists in the second table or not if so then it should add the sold amount in the row that's in the second table that has the same name. If not then simply add a new row in the second table with the name and sold amount. jQuery is ok.
here is a possible solution, replacement for your function Sell()
Sellbtn.onclick = function Sell() {
var found = false,
rows = secondTable.rows,
numrows = rows.length,
tofind = this.parentNode.parentNode.cells[0].innerHTML,
foundin,
numToAdd = parseInt(this.parentNode.parentNode.cells[1].innerHTML),
num,
x;
for(x=0;x<numrows;x++){
if(rows[x].cells[0].innerHTML === tofind){
found = true;
foundin = x;
}
}
if(found){
num = parseInt(rows[foundin].cells[1].innerHTML) + numToAdd;
rows[foundin].cells[1].innerHTML = num;
}
else{
var Row = secondTable.insertRow();
for (var f = 0; f < 2; f += 1) {
Row.insertCell(f);
}
Row.cells[0].innerHTML = this.parentNode.parentNode.cells[0].innerHTML;
Row.cells[1].innerHTML = this.parentNode.parentNode.cells[1].innerHTML;
}
}
is this what you're looking for?
$(document).ready(function() {
$('.insert').on('click', function() {
var Fruits = ["Apples", "Oranges", "Strawberries"];
var random_Fruit = Fruits[Math.floor(Math.random() * Fruits.length)];
var clone = $('#template').clone(true).attr('id', '');
clone.css('display', '');
clone.closest('tr').find('.item').html(random_Fruit);
clone.appendTo('#firstTableBody');
});
$('#firstTableBody').on('click', '.sell', function(e) {
e.preventDefault();
var item = $(this).closest('tr').find('.item').html();
var add = parseInt($(this).closest('tr').find('.number').html());
var inTable2 = [];
$('#secondTable tr').each(function() {
var fruit = $(this).find('.item').html();
inTable2.push(fruit);
});
console.log(inTable2);
if ($.inArray(item, inTable2) > -1) {
console.log('in array');
$('#secondTable tr').each(function() {
var fruitIn2 = $(this).find('.item').html();
if (fruitIn2 == item) {
var sold = parseInt($(this).find('.number').html());
$(this).find('.number').html(sold + add);
}
});
}
else {
console.log('add');
var clone = $('#template').clone(true).attr('id', '');
clone.css('display', '');
clone.closest('tr').find('.item').html(item);
clone.closest('tr').find('.sellTd').remove();
clone.appendTo('#secondTable');
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table border="1">
<thead>
<th>Item</th>
<th>Number</th>
<th>
<button class="insert">Insert</button>
</th>
</thead>
<tbody id="firstTableBody">
<tr id="template" class="fruit" style="display:none;">
<td class="item"></td>
<td class="number">100</td>
<td class="sellTd"><button class="sell">Sell</button></td>
</tr>
</tbody>
</table>
<br/><br/>
<table border="1">
<thead>
<th>Item</th>
<th>Sold</th>
</thead>
<tbody id="secondTable">
</tbody>
</table>
sorry i kinda used all jquery cause it makes it simpler for me to code in and think xp but it works :D

Finding a colSpan Header for one of the cells or td's is Spans

I have multiple column headers that spans of multiple column and I would like to find the correct header number/count for the columns.
I want to enter a column number and get the header: example column 5 is RDataTest6 $('td.eq(5)) and its header is HTest3 $('th.eq(2))
Example:
<table>
<tr>
<th>HTest1</th>
<th colSpan="2">HTest2</th>
<th colSpan="4">HTest3</th>
<th colSpan="2">HTest4</th>
</tr>
<tr>
<td>RDataTest1</td>
<td>RDataTest2</td>
<td>RDataTest3</td>
<td>RDataTest4</td>
<td>RDataTest5</td>
<td>RDataTest6</td>
<td>RDataTest7</td>
<td>RDataTest8</td>
<td>RDataTest9</td>
</tr>
</table>
​
Edit: You should implement a simple array that hold the header location, see below,
var thLocator = [], colCount = 1;
$table.find('tr:first th').each(function () {
for (var i = 0; i < this.colSpan; i++) {
thLocator.push(colCount);
}
colCount++;
});
$table.find('td').click(function () {
alert(thLocator[$(this).index()]);
});
And then anytime You can get the location of a td column. See DEMO -> Click on any TD to identify its col head position.
I am not sure which count you want so I wrote down all col count. See DEMO
$(function() {
var $table = $('table');
alert('Table Header Count ' + $table.find('tr:first th').length);
var thCount = 0;
$table.find('tr:first th').each(function () {
thCount += this.colSpan;
});
alert('Computed TH Count ' + thCount );
alert('Table TD Col Count ' + $table.find('tr:eq(1) td').length);
});
That's easy, as long as you don't have any rowspans:
function getCell(tr, col) {
var cell = tr.firstElementChild;
while (cell && (col -= cell.colSpan || 1)>=0)
cell = cell.nextElementSibling;
return cell;
}
See demonstration.

Categories