I have a table in HTML, which has 616 rows. However, I would like to add an extra column, and each of the rows for that column would contain the same element. Is there a way with JS to do that? What I would like to add on each row for that column is this symbol
Which is just an add button that goes in every element.
Here is my code:
<div class="scrollingTable">
<div class="row justify-content-center">
<div class="col-md-8 col-lg-8 mb-8">
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<table id="myTable" cellspacing="0" cellpadding="1" border="1" width="300">
<thead>
<tr>
<th title="Field #1">drinkName</th>
<th title="Field #2">drinkSizeInFlOz</th>
<th title="Field #3">calories</th>
<th title="Field #4">caffeineInMg</th>
<th title="Field #5">caffeineInMgPerFloz</th>
<th title="Field #6">type</th>
</tr>
</thead>
<tbody>
<tr>
<td>28 Black Energy Drink</td>
<td>8.46</td>
<td align="right">125</td>
<td align="right">80</td>
<td align="right">9.5</td>
<td>ED</td>
<td><button type="submit" id="myButton">+</button></td>
</tr>
<tr>
<td>3 Water </td>
<td>16.9</td>
<td align="right">0</td>
<td align="right">50</td>
<td align="right">3.0</td>
<td>W</td>
<td><button type="submit" id="myButton">+</button></td>
</tr>
<tr>
<td>3D Energy Drink</td>
<td>16</td>
<td align="right">15</td>
<td align="right">200</td>
<td align="right">12.5</td>
<td>ED</td>
<td><button type="submit" id="myButton">+</button></td>
</tr>
<tr>
<td>4 Purpose Energy Drink</td>
<td>8.46</td>
<td align="right">70</td>
<td align="right">70</td>
<td align="right">8.3</td>
<td>ED</td>
<td><button type="submit" id="myButton">+</button></td>
</tr>
<tr>
<td>4C Energy Drink Mix</td>
<td>16.9</td>
<td align="right">15</td>
<td align="right">170</td>
<td align="right">10.1</td>
<td>ED</td>
<td><button type="submit" id="myButton">+</button></td>
</tr>
<tr>
<td>5 Hour Energy</td>
<td>1.93</td>
<td align="right">4</td>
<td align="right">200</td>
<td align="right">103.6</td>
<td>ES</td>
<td><button type="submit" id="myButton">+</button></td>
</tr>
<tr>
<td>5 Hour Energy Extra Strength</td>
<td>1.93</td>
<td align="right">0</td>
<td align="right">230</td>
<td align="right">119.2</td>
<td>ES</td>
<td><button type="submit" id="myButton">+</button></td>
</tr>
<tr>
I created the jsfiddle for your problem.
var trs = document.querySelectorAll("#myTable tbody tr");
for (var tr of trs) {
let td = document.createElement("td");
let btn = document.createElement("button");
btn.innerHTML = "+";
btn.type = "submit";
td.appendChild(btn);
tr.appendChild(td);
}
<html>
<body>
<div class="scrollingTable">
<div class="row justify-content-center">
<div class="col-md-8 col-lg-8 mb-8" >
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name" >
<table id="myTable" cellspacing="0" cellpadding="1" border="1" width="300">
<thead>
<tr>
<th title="Field #1">drinkName</th>
<th title="Field #2">drinkSizeInFlOz</th>
<th title="Field #3">calories</th>
<th title="Field #4">caffeineInMg</th>
<th title="Field #5">caffeineInMgPerFloz</th>
<th title="Field #6">type</th>
</tr>
</thead>
<tbody>
<tr>
<td>28 Black Energy Drink</td>
<td>8.46</td>
<td align="right">125</td>
<td align="right">80</td>
<td align="right">9.5</td>
<td>ED</td>
</tr>
<tr>
<td>3 Water </td>
<td>16.9</td>
<td align="right">0</td>
<td align="right">50</td>
<td align="right">3.0</td>
<td>W</td>
</tr>
<tr>
<td>3D Energy Drink</td>
<td>16</td>
<td align="right">15</td>
<td align="right">200</td>
<td align="right">12.5</td>
<td>ED</td>
</tr>
<tr>
<td>4 Purpose Energy Drink</td>
<td>8.46</td>
<td align="right">70</td>
<td align="right">70</td>
<td align="right">8.3</td>
<td>ED</td>
</tr>
<tr>
<td>4C Energy Drink Mix</td>
<td>16.9</td>
<td align="right">15</td>
<td align="right">170</td>
<td align="right">10.1</td>
<td>ED</td>
</tr>
<tr>
<td>5 Hour Energy</td>
<td>1.93</td>
<td align="right">4</td>
<td align="right">200</td>
<td align="right">103.6</td>
<td>ES</td>
</tr>
<tr>
<td>5 Hour Energy Extra Strength</td>
<td>1.93</td>
<td align="right">0</td>
<td align="right">230</td>
<td align="right">119.2</td>
<td>ES</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
There are a lot of ways to insert a column into each row of a table.
It all depends on what libraries you are using.
I will assume that you are using vanilla Javascript, (i.e: no external libraries).
Here is one way to insert a column, and control the content of each cell,
including detecting if you are currently on the table header, or normal cell.
const btn = document.getElementById('my-button');
btn.addEventListener('click', function(){
const tr = document.querySelectorAll('#my-table tr');
tr.forEach((row,index) => {
let cell;
if(index===0) {
cell = document.createElement('th');
cell.innerText = "fourth column";
} else {
cell = document.createElement('td');
cell.innerText = `row ${index},4`;
}
row.appendChild(cell);
});
});
table, td, th
{
border: 1px solid grey;
border-collapse: collapse;
}
td, th
{
padding: 1em;
}
button
{
margin-top: 2em;
}
<button id="my-button">Insert missing column</button>
<table id="my-table">
<thead>
<tr>
<th>first column</th>
<th>second column</th>
<th>third column</th>
</tr>
</thead>
<tbody>
<tr>
<td>row 1, 1</td>
<td>row 1, 2</td>
<td>row 1, 3</td>
</tr>
<tr>
<td>row 2, 1</td>
<td>row 2, 2</td>
<td>row 2, 3</td>
</tr>
<tr>
<td>row 3, 1</td>
<td>row 3, 2</td>
<td>row 3, 3</td>
</tr>
</tbody>
</table>
const rows = document.getElementsByTagName("table")[0].rows; //Get all rows
for (let i = 1; i < rows.length; i++) { // Iterate rows of body
const row = rows[i]; // Get row
const button = document.createElement("button"); // Create button
button.innerHTML = "+"; // Set text of button
const cell = document.createElement("td"); // Create column
cell.appendChild(button); // Add button to column
row.appendChild(cell); // Add column to row
}
<div class="scrollingTable">
<div class="row justify-content-center">
<div class="col-md-8 col-lg-8 mb-8">
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<table id="myTable" cellspacing="0" cellpadding="1" border="1" width="300">
<thead>
<tr>
<th title="Field #1">drinkName</th>
<th title="Field #2">drinkSizeInFlOz</th>
<th title="Field #3">calories</th>
<th title="Field #4">caffeineInMg</th>
<th title="Field #5">caffeineInMgPerFloz</th>
<th title="Field #6">type</th>
</tr>
</thead>
<tbody>
<tr>
<td>28 Black Energy Drink</td>
<td>8.46</td>
<td align="right">125</td>
<td align="right">80</td>
<td align="right">9.5</td>
<td>ED</td>
</tr>
<tr>
<td>3 Water </td>
<td>16.9</td>
<td align="right">0</td>
<td align="right">50</td>
<td align="right">3.0</td>
<td>W</td>
</tr>
<tr>
<td>3D Energy Drink</td>
<td>16</td>
<td align="right">15</td>
<td align="right">200</td>
<td align="right">12.5</td>
<td>ED</td>
</tr>
<tr>
<td>4 Purpose Energy Drink</td>
<td>8.46</td>
<td align="right">70</td>
<td align="right">70</td>
<td align="right">8.3</td>
<td>ED</td>
</tr>
<tr>
<td>4C Energy Drink Mix</td>
<td>16.9</td>
<td align="right">15</td>
<td align="right">170</td>
<td align="right">10.1</td>
<td>ED</td>
</tr>
<tr>
<td>5 Hour Energy</td>
<td>1.93</td>
<td align="right">4</td>
<td align="right">200</td>
<td align="right">103.6</td>
<td>ES</td>
</tr>
<tr>
<td>5 Hour Energy Extra Strength</td>
<td>1.93</td>
<td align="right">0</td>
<td align="right">230</td>
<td align="right">119.2</td>
<td>ES</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
IMPORTANT!
#IDs ARE UNIQUE!
Do not have more than one of the same #id on a page because it's:
invalid HTML
semantically gross
behavior becomes unpredictable
JavaScript if not immediately but eventually break
the terrorists win
There's like a ton of these in OP:
<button type="submit" id="myButton">+</button> <!--👎-->
Try to avoid using #id at all -- use .class instead.
In the example below the function insertCol() is versatile and reusable. The <table> has a <tfoot> for demonstration purposes. Details are commented in the example.
// This object stores content for insertCol() to fill a table
let content = {
cap: {
text: 'TEXT',
side: '',
act: 0 // 1='use data' 0='skip data'
},
tH: {
th: 'tH',
act: 0
},
tB: {
th: '',
td: `<td><button class="btn btn-sm btn-info add">âž•</button></td>`,
act: 1
},
tF: {
td: 'tF',
act: 0
}
};
/**
* #desc - Inserts a column into a given table
* #param {number} index - Index to inert new column at
* #param {object} content - Object that stores content
* #param {string<selector>} selector - CSS Selector of a
* tag if undefined #default is "table"
*/
function insertCol(index, content, selector = 'table') {
// Reference <table>
const table = document.querySelector(selector);
// Collect all <tr> into an array
const rowArray = [...table.rows];
let cols = rowArray[0].cells.length;
let size = rowArray.length;
//console.log(size);
//console.log(cols);
/*
If content.tB is active (1)...
... .foreach() <tr> add <td> and content at the index
*/
if (content.tB.act) {
rowArray.forEach(tr => {
tr.insertCell(index).innerHTML = content.tB.td;
});
}
/*
If there's a <thead> AND content.tH.act === 1...
... .removeCell() at index...
... add <th> with content
*/
if (table.tHead && content.tH.act) {
rowArray[0].deleteCell(index);
rowArray[0].insertCell(index).outerHTML = `<th>${content.tH.th}</th>`;
}
// The same as above for <tfoot>
if (table.tFoot && content.tF.act) {
rowArray[size - 1].deleteCell(index);
rowArray[size - 1].insertCell(index).innerHTML = content.tF.td;
}
// This block is for <caption>
if (table.caption && content.cap.act) {
table.caption.innerHTML = content.cap.text;
table.caption.style.captionSide = content.cap.side;
}
}
// -1 is the index after the last index
insertCol(-1, content);
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<style></style>
</head>
<body>
<main class="container scrollingTable">
<section class="row justify-content-center">
<div class="col-md-8 col-lg-8 mb-8">
<label class='form-label' for='search'>Search</label>
<input id="search" class='form-control mb-2' type="text" placeholder="Search for names..">
<table class='table table-striped table-hover'>
<caption></caption>
<thead>
<tr>
<th title="Field #1">drinkName</th>
<th title="Field #2">drinkSizeInFlOz</th>
<th title="Field #3">calories</th>
<th title="Field #4">caffeineInMg</th>
<th title="Field #5">caffeineInMgPerFloz</th>
<th title="Field #6">type</th>
</tr>
</thead>
<tbody>
<tr>
<td>28 Black Energy Drink</td>
<td>8.46</td>
<td>125</td>
<td>80</td>
<td>9.5</td>
<td>ED</td>
</tr>
<tr>
<td>3 Water </td>
<td>16.9</td>
<td>0</td>
<td>50</td>
<td>3.0</td>
<td>W</td>
</tr>
<tr>
<td>3D Energy Drink</td>
<td>16</td>
<td>15</td>
<td>200</td>
<td>12.5</td>
<td>ED</td>
</tr>
<tr>
<td>4 Purpose Energy Drink</td>
<td>8.46</td>
<td>70</td>
<td>70</td>
<td>8.3</td>
<td>ED</td>
</tr>
<tr>
<td>4C Energy Drink Mix</td>
<td>16.9</td>
<td>15</td>
<td>170</td>
<td>10.1</td>
<td>ED</td>
</tr>
<tr>
<td>5 Hour Energy</td>
<td>1.93</td>
<td>4</td>
<td>200</td>
<td>103.6</td>
<td>ES</td>
</tr>
<tr>
<td>5 Hour Energy Extra Strength</td>
<td>1.93</td>
<td>0</td>
<td>230</td>
<td>119.2</td>
<td>ES</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>FOOT</td>
<td>FOOT</td>
<td>FOOT</td>
<td>FOOT</td>
<td>FOOT</td>
<td>FOOT</td>
</tr>
</tfoot>
</table>
</div>
</section>
</main>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script></script>
</body>
</html>
Related
On my html I have multiple tables, which are for different valuations. The results of those valuations are supposed to be in another table. The text of valuation_all in the tables.taglist should be transferred into another table. I'm really lost here. Newby with this topic so I'll appreciate every help!
Table for summary results
<table id="results" class="summary">
<th>Test</th>
<th>result</th>
<tr>
<td>E-01</td>
<td>text</td>
</tr>
<tr>
<td>E-02</td>
<td>text</td>
</tr>
</table>
Tables of valuation
<p>
<table id="results1" class="taglist">
<th>Name</th>
<th>result</th>
<tr>
<td class="valuation">FAIL</td>
<td rowspan=2 class="valuation_all">FAIL</td>
</tr>
<tr>
<td class="valuation">PASS</td>
</tr>
</table>
</p>
<p>
<table id="results2" class="taglist">
<th>Name</th>
<th>result</th>
<tr>
<td class="valuation">x</td>
<td class="valuation_all" rowspan=2>OPEN</td>
</tr>
<tr>
<td class="valuation">x</td>
</tr>
</table>
</p>
Assuming your results list tables are ordered the same way you ordered rows in your global results table, you can perform a forEach on all .valuation_all, and then mirror each text on the global results table:
const resTables = document.querySelectorAll('.valuation_all')
const results = document.querySelectorAll('#results tr > td + td')
resTables.forEach( function(el, i) {
results[i].textContent = el.textContent
})
<table id="results" class="summary">
<tr>
<th>Test</th><th>result</th>
</tr>
<tr>
<td>E-01</td><td>text</td>
</tr>
<tr>
<td>E-02</td><td>text</td>
</tr>
</table>
<hr>
<table id="results1" class="taglist">
<tr>
<th>Name</th><th>result</th>
</tr>
<tr>
<td class="valuation">FAIL</td><td rowspan="2" class="valuation_all">FAIL</td>
</tr>
<tr>
<td class="valuation">PASS</td>
</tr>
</table>
<table id="results2" class="taglist">
<tr>
<th>Name</th><th>result</th>
</tr>
<tr>
<td class="valuation">x</td><td class="valuation_all" rowspan="2">OPEN</td>
</tr>
<tr>
<td class="valuation">x</td>
</tr>
</table>
Please consider using data attributes for better matching.
https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes
I need to access the cell of an HTML Table and change Its value. The method I tried didn't worked out. Refer the screenshot as well.
Cannot use the following method, since there were multiple with same value in some cases. I need to access the specific marked cell.
$('td:contains("1200")').text('....');
Cell need to access and Change the amount
<table class="table table-striped">
<thead>
<tr>
<th>Loan amount</th>
<th>New loan installment amount (first installment)</th>
<th>DSCR (both new and existing)</th>
</tr>
</thead>
<tbody>
<tr>
<td id="ValueOne">LKR 12000</td>
<td>Doe</td>
<td>john#example.com</td>
</tr>
<tr>
<td>Mary</td>
<td>Moe</td>
<td>mary#example.com</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>july#example.com</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>july#example.com</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>july#example.com</td>
</tr>
</tbody>
</table>
Accessing by ID And changing the value didn't worked.
document.getElementById("ValueOne").innerHTML = 'New Value';
Since you kindly provided us with an ID. Simply use:
Javascript:
document.getElementById("ValueOne").innerHTML = "LKR 100"
JQuery:
$("#ValueOne").text("LKR 100")
Demo: https://jsfiddle.net/fme8v6oa/
Options:
document.getElementsByTagName("td")[0].innerHTML = "LKR 100"
Your javascript code works, make sure to run your script after the page is loaded.
Here is an example using a button:
<table class="table table-striped">
<thead>
<tr>
<th>Loan amount</th>
<th>New loan installment amount (first installment)</th>
<th>DSCR (both new and existing)</th>
</tr>
</thead>
<tbody>
<tr>
<td id="ValueOne">LKR 12000</td>
<td>Doe</td>
<td>john#example.com</td>
</tr>
<tr>
<td>Mary</td>
<td>Moe</td>
<td>mary#example.com</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>july#example.com</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>july#example.com</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>july#example.com</td>
</tr>
</tbody>
</table>
<button onclick="changeme()">Change</button>
<script>
function changeme(){
document.getElementById("ValueOne").innerHTML = 'New Value';
}
</script>
Using jquery :
$('#mytable tr').each(function() {
$(this).find("#ValueOne").html("new value");
});
where mytable is the Id of your table
Demo : https://jsfiddle.net/xLz6f49h/4/
<html>
<body>
<table class="table table-striped">
<thead>
<tr>
<th>Loan amount</th>
<th>New loan installment amount (first installment)</th>
<th>DSCR (both new and existing)</th>
</tr>
</thead>
<tbody>
<tr>
<td id="Value1">LKR 12000</td>
<td id="Value2">Doe</td>
<td id="Value2">john#example.com</td>
</tr>
<tr>
<td id="Value3">Mary</td>
<td id="Value4">Moe</td>
<td id="Value5">mary#example.com</td>
</tr>
<tr>
<td id="Value6">July</td>
<td id="Value7">Dooley</td>
<td id="Value8">july#example.com</td>
</tr>
<tr>
<td id="Value9">July</td>
<td id="Value10">Dooley</td>
<td id="Value11">july#example.com</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>july#example.com</td>
</tr>
</tbody>
</table>
CELL id: <input type="text" name="celliD" id="input1"><br><br>
New CELL Value: <input type="text" name="celliD" id="input2"><br>
<button onclick="changeCellValue()">Change Value</button>
<script>
function changeCellValue(){
var inputVal = document.getElementById('input1').value;
var newVal = document.getElementById('input2').value;
if(inputVal == null || inputVal == "" && newVal == null || newVal == ""){
alert("value is required");
} else {
var changeVal = document.getElementById(inputVal).innerHTML = newVal;
}
}
</script>
<body>
</html>
I need to show another tbody of table on Click. I have following table which is in foreach so there will be multiple buttons.:
<table class="table" id="call-table">
<tr>
<th>Show more buttons</th>
</tr>
<tbody>
<tr>
<td class="show-more-button">Show more</td> //It will open first tbody
<tr>
<tr>
<td class="show-more-button">Show more</td> //It will open second tbody
<tr>
<tbody class="show-more"> //First tbody
<tr>
<th scope="col">Data</th>
<th scope="col">Value</th>
</tr>
<tr>
<td>Some data....</td>
<td>A value..</td>
</tr>
</tbody>
<tbody class="show-more"> //Second tbody
<tr>
<th scope="col">Data</th>
<th scope="col">Value</th>
</tr>
<tr>
<td>Some more data....</td>
<td>Another value..</td>
</tr>
</tbody>
</tbody>
I'm using python with DjangoFramework. And that's the script i came up with. But it only works for changing the 's text but doesn't show the tbody.
<script>
$(document).on("click", ".show-more-button", function() {
if ($(this).text() == "Show more") {
$(this).text("Show less");
$(this).parent().children(".show-more").style.display = "block";
} else {
$(this).text("Show more");
$(this).parent().children(".show-more").style.display = "block";
}
});
</script>
and in CSS:
.show-more {
display: none;
}
What error do i have in my script?
Because $(this).parent() will be <tr>. For example you might use closest and find first parent table and there will be able using .children('.show-more'). See an example below.
$(document).on("click", ".show-more-button", function() {
if ($(this).text() == "Show more") {
$(this).text("Show less");
$(this).closest('table').children(".show-more").css('display', 'block');
} else {
$(this).text("Show more");
$(this).closest('table').children(".show-more").css('display', 'none');
}
});
.show-more { display: none; }
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<table>
<thead>
<tr>
<th>Name</th>
<th>Lastname</th>
<th>Age</th>
</tr>
</thead>
<tr>
<td class="show-more-button">Show more</td>
<tr>
<tbody class="show-more">
<tr>
<td>John</td>
<td>Doe</td>
<td>27</td>
</tr>
<tr>
<td>Alice</td>
<td>Lo</td>
<td>43</td>
</tr>
<tr>
<td>Linda</td>
<td>Morrison</td>
<td>45</td>
</tr>
</tbody>
</table>
Example changed and i prepared new solution.
$(document).on("click", ".show-more-button", function() {
var forId = $(this).data('more-for');
var $showMoreElement = $(this).closest('table').children('.show-more[data-more-id="' + forId + '"]');
if ($(this).text() == "Show more") {
$(this).text("Show less");
$showMoreElement.css('display', 'block');
} else {
$(this).text("Show more");
$showMoreElement.css('display', 'none');
}
});
.show-more {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table" id="call-table">
<tr>
<th>Show more buttons</th>
</tr>
<tbody>
<tr>
<!--It will open first tbody -->
<td class="show-more-button" data-more-for="1">Show more</td>
</tr>
<tr>
<!--It will open second tbody -->
<td class="show-more-button" data-more-for="2">Show more</td>
</tr>
</tbody>
<!--First tbody -->
<tbody class="show-more" data-more-id="1">
<tr>
<th scope="col">Data</th>
<th scope="col">Value</th>
</tr>
<tr>
<td>Some data....</td>
<td>A value..</td>
</tr>
</tbody>
<!--Second tbody-->
<tbody class="show-more" data-more-id="2">
<tr>
<th scope="col">Data</th>
<th scope="col">Value</th>
</tr>
<tr>
<td>Some more data....</td>
<td>Another value..</td>
</tr>
</tbody>
</table>
Here two ways. Choose anyone. It works well:
$(function(){
$('.show-more-button').click(function(){
var b_id = $(this).data('id');
var b_text = $(this).text() == "Show more" ? "Show less" : "Show more";
$(this).text(b_text);
$('.shm'+b_id).toggle();
});
$('.show-more-button2').click(function(){
var b_id = $(this).data('id');
var b_text = $(this).text() == "Show more" ? "Show less" : "Show more";
$(this).text(b_text);
$('.shm'+b_id+'_2').toggle();
th_sh();
});
})
function th_sh(){
var o = 0;
$('#call-table2').find('.shows').each(function(){
var u = $(this).css('display') == 'table-row' ? 1 : 0;
o = o + u;
});
o>0 ? $('.th_disp').css('display','block') : $('.th_disp').css('display','none');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-striped" id="call-table">
<thead>
<tr>
<th>Show more buttons</th>
<th></th>
</tr>
</thead>
<tr>
<td class="show-more-button" data-id="1">Show more</td> <!--//It will open first tbody-->
<td></td>
<tr>
<tr>
<td class="show-more-button" data-id="2">Show more</td><!--//It will open second tbody -->
<td></td>
<tr>
<tr>
<td class="show-more-button" data-id="3">Show more</td><!--//It will open second tbody -->
<td></td>
<tr>
<tbody>
<!--<tbody class="show-more"> //First tbody-->
<tr class="shm1" style="display:none;">
<th scope="col">Data1</th>
<th scope="col">Value</th>
</tr>
<tr class="shm1" style="display:none;">
<td>Some data..1..</td>
<td>A value..</td>
</tr>
<!--</tbody>//Second tbody-->
<tr class="shm2" style="display:none;">
<th scope="col">Data2</th>
<th scope="col">Value</th>
</tr>
<tr class="shm2" style="display:none;">
<td>Some data..2..</td>
<td>A value..</td>
</tr>
<!--</tbody>//Second tbody-->
<tr class="shm3" style="display:none;">
<th scope="col">Data3</th>
<th scope="col">Value</th>
</tr>
<tr class="shm3" style="display:none;">
<td>Some data..3..</td>
<td>A value..</td>
</tr>
</tbody>
</table>
<br><hr><br>
<table class="table table-striped" id="call-table2">
<thead>
<tr>
<th>Show more buttons</th>
<th></th>
</tr>
</thead>
<tr>
<td class="show-more-button2" data-id="1">Show more</td> <!--//It will open first tbody-->
<td></td>
<tr>
<tr>
<td class="show-more-button2" data-id="2">Show more</td><!--//It will open second tbody -->
<td></td>
<tr>
<tr>
<td class="show-more-button2" data-id="3">Show more</td><!--//It will open second tbody -->
<td></td>
<tr>
<tbody>
<!--<tbody class="show-more"> //First tbody-->
<tr class="th_disp" style="display:none;">
<th scope="col">Data</th>
<th scope="col">Value</th>
</tr>
<tr class="shm1_2 shows" style="display:none;">
<td>Some data..1..</td>
<td>A value..</td>
</tr>
<!--</tbody>//Second tbody-->
<tr class="shm2_2 shows" style="display:none;">
<td>Some data..2..</td>
<td>A value..</td>
</tr>
<!--</tbody>//Second tbody-->
<tr class="shm3_2 shows" style="display:none;">
<td>Some data..3..</td>
<td>A value..</td>
</tr>
</tbody>
</table>
I have table with some data in an array to be displayed as below. In this example, I display 2 table datas but it can be more than 2. I have to calculate the column population, collection 1 and collection 2 of each table and show then at the end of each table.
So far I have tried following code to calculate where I first calcuate the number of tables available by counting array.
<script type="text/javascript">
var count = <?php echo json_encode(count($lists)); ?>;
var total = 0;
for(var i = 1; i <= count; i++)
{
var available = $(".used-community .plant_counter_"+i);
$.each(available, function(key, value)
{
total+=parseInt(available[key].innerText);
});
console.log(total);//edit variable name - totala changed to total
}
</script>
<table class="table" border="1">
<thead>
<tr class="titlerow">
<th>Name</th>
<th>Address</th>
<th>Population</th>
<th>Collection 1</th>
<th>collection 2</th>
</tr>
</thead>
<tbody class="used-community">
<tr id="47" class="rowList middle">
<td>Wangkha</td>
<td>Soi Wangkha 3</td>
<td class="plant_counter_1">100000</td>
<td>31</td>
<td>11315</td>
</tr>
<tr id="43" class="rowList middle">
<td>one</td>
<td>one address</td>
<td class="plant_counter_1">35000</td>
<td>7</td>
<td>2555</td>
</tr>
<tr id="46" class="rowList middle">
<td>Bang</td>
<td>Bang khuwang Rd</td>
<td class="plant_counter_1">6000</td>
<td>2</td>
<td>730</td>
</tr>
<tr bgcolor="#66CCFF">
<td></td>
<td></td>
<td></td>
<td class="col"></td>
<td class="cap"></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<table class="table" border="1">
<thead>
<tr class="titlerow">
<th>Name</th>
<th>Address</th>
<th>Population</th>
<th>Collection 1</th>
<th>collection 2</th>
</tr>
</thead>
<tbody class="used-community">
<tr id="45" class="rowList middle">
<td>sap</td>
<td>sap thawi</td>
<td class="plant_counter_2">80000</td>
<td>15</td>
<td>5475</td>
</tr>
<tr id="44" class="rowList middle">
<td>two-nonthaburi</td>
<td>nonthaburi</td>
<td class="plant_counter_2">69000</td>
<td>11</td>
<td>4015</td>
</tr>
<tr bgcolor="#66CCFF">
<td></td>
<td></td>
<td></td>
<td class="col"></td>
<td class="cap"></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
My code is calculating the row with class "plant_counter_1" correctly but for next table it continue adding the sum of table 1 as well. Can anybody teach me where I did mistake and I how can I find out the sum of other two columns
Thank You
Loop over each table and work within that table instance. The total data count is not really needed since it doesn't break down the number of tables.
Since you can easily isolate table instances I would suggest you use common class names across all tables and don't use incremental ones
$('table').each(function(){
var $table =$(this),
$rows = $table.find('tbody tr'),
$lastRowCells = $rows.last().children(),
collectionTotals = $rows.not(':last').map(function(){
var $cells = $(this).children()
return [[+$cells[3].textContent, +$cells[4].textContent]]
}).get()
.reduce(function(a,c){
$.each(c,function(i, val){
a[i] += val;
});
return a;
},[0,0]);
$lastRowCells.eq(3).text(collectionTotals[0]);
$lastRowCells.eq(4).text(collectionTotals[1]);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table" border="1">
<thead>
<tr class="titlerow">
<th>Name</th>
<th>Address</th>
<th>Population</th>
<th>Collection 1</th>
<th>collection 2</th>
</tr>
</thead>
<tbody class="used-community">
<tr id="47" class="rowList middle">
<td>Wangkha</td>
<td>Soi Wangkha 3</td>
<td class="plant_counter">100000</td>
<td>31</td>
<td>11315</td>
</tr>
<tr id="43" class="rowList middle">
<td>one</td>
<td>one address</td>
<td class="plant_counter">35000</td>
<td>7</td>
<td>2555</td>
</tr>
<tr id="46" class="rowList middle">
<td>Bang</td>
<td>Bang khuwang Rd</td>
<td class="plant_counter">6000</td>
<td>2</td>
<td>730</td>
</tr>
<tr bgcolor="#66CCFF">
<td></td>
<td></td>
<td></td>
<td class="col"></td>
<td class="cap"></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<table class="table" border="1">
<thead>
<tr class="titlerow">
<th>Name</th>
<th>Address</th>
<th>Population</th>
<th>Collection 1</th>
<th>collection 2</th>
</tr>
</thead>
<tbody class="used-community">
<tr id="45" class="rowList middle">
<td>sap</td>
<td>sap thawi</td>
<td class="plant_counter">80000</td>
<td>15</td>
<td>5475</td>
</tr>
<tr id="44" class="rowList middle">
<td>two-nonthaburi</td>
<td>nonthaburi</td>
<td class="plant_counter">69000</td>
<td>11</td>
<td>4015</td>
</tr>
<tr bgcolor="#66CCFF">
<td></td>
<td></td>
<td></td>
<td class="col"></td>
<td class="cap"></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
Just a small modification to your code and it will work. Since you need multiple results, your total needs to be an array. Please run attached code snippet for clarity.
var count =2;//change back to your php <?php echo json_encode(count($lists)); ?>;
var total = new Array();
total.push(0);
for(var i = 1; i <= count; i++)
{
total.push(0);
var available = $(".used-community .plant_counter_"+i);
$.each(available, function(key, value)
{
total[i]+=parseInt(available[key].innerText);
});
total.push(0);
console.log(total[i]);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table" border="1">
<thead>
<tr class="titlerow">
<th>Name</th>
<th>Address</th>
<th>Population</th>
<th>Collection 1</th>
<th>collection 2</th>
</tr>
</thead>
<tbody class="used-community">
<tr id="47" class="rowList middle">
<td>Wangkha</td>
<td>Soi Wangkha 3</td>
<td class="plant_counter_1">100000</td>
<td>31</td>
<td>11315</td>
</tr>
<tr id="43" class="rowList middle">
<td>one</td>
<td>one address</td>
<td class="plant_counter_1">35000</td>
<td>7</td>
<td>2555</td>
</tr>
<tr id="46" class="rowList middle">
<td>Bang</td>
<td>Bang khuwang Rd</td>
<td class="plant_counter_1">6000</td>
<td>2</td>
<td>730</td>
</tr>
<tr bgcolor="#66CCFF">
<td></td>
<td></td>
<td></td>
<td class="col"></td>
<td class="cap"></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<table class="table" border="1">
<thead>
<tr class="titlerow">
<th>Name</th>
<th>Address</th>
<th>Population</th>
<th>Collection 1</th>
<th>collection 2</th>
</tr>
</thead>
<tbody class="used-community">
<tr id="45" class="rowList middle">
<td>sap</td>
<td>sap thawi</td>
<td class="plant_counter_2">80000</td>
<td>15</td>
<td>5475</td>
</tr>
<tr id="44" class="rowList middle">
<td>two-nonthaburi</td>
<td>nonthaburi</td>
<td class="plant_counter_2">69000</td>
<td>11</td>
<td>4015</td>
</tr>
<tr bgcolor="#66CCFF">
<td></td>
<td></td>
<td></td>
<td class="col"></td>
<td class="cap"></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
to make things a little bit of fun
(I assumed the total rows have two extra misplaced columns)
;$(function() {
var tables = $('table > tbody');
var totals = new Array(tables.length);
tables.each(function(nt,t) {
var rows = $('tr',t);
var totalElement = rows.splice(-1);
rows = rows.map(function(nr, r) {
return [$('td',$(r)).slice(-3)
.map( function(nc,c) {
return parseInt($(c).text()) || 0; }).toArray()];
}).toArray();
totals[nt] = rows.reduce( function(a, b) {
return a.map(function(v,n) { return v + b[n]; });
}, [0,0,0] );
$('td',totalElement[0]).splice(-3).forEach(function(c,n) {
$(c).text(totals[nt][n]); });
});
console.log(totals);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table" border="1">
<thead>
<tr class="titlerow">
<th>Name</th>
<th>Address</th>
<th>Population</th>
<th>Collection 1</th>
<th>collection 2</th>
</tr>
</thead>
<tbody class="used-community">
<tr id="47" class="rowList middle">
<td>Wangkha</td>
<td>Soi Wangkha 3</td>
<td class="plant_counter_1">100000</td>
<td>31</td>
<td>11315</td>
</tr>
<tr id="43" class="rowList middle">
<td>one</td>
<td>one address</td>
<td class="plant_counter_1">35000</td>
<td>7</td>
<td>2555</td>
</tr>
<tr id="46" class="rowList middle">
<td>Bang</td>
<td>Bang khuwang Rd</td>
<td class="plant_counter_1">6000</td>
<td>2</td>
<td>730</td>
</tr>
<tr bgcolor="#66CCFF">
<td></td>
<td></td>
<td></td>
<td class="col"></td>
<td class="cap"></td>
</tr>
</tbody>
</table>
<table class="table" border="1">
<thead>
<tr class="titlerow">
<th>Name</th>
<th>Address</th>
<th>Population</th>
<th>Collection 1</th>
<th>collection 2</th>
</tr>
</thead>
<tbody class="used-community">
<tr id="45" class="rowList middle">
<td>sap</td>
<td>sap thawi</td>
<td class="plant_counter_2">80000</td>
<td>15</td>
<td>5475</td>
</tr>
<tr id="44" class="rowList middle">
<td>two-nonthaburi</td>
<td>nonthaburi</td>
<td class="plant_counter_2">69000</td>
<td>11</td>
<td>4015</td>
</tr>
<tr bgcolor="#66CCFF">
<td></td>
<td></td>
<td></td>
<td class="col"></td>
<td class="cap"></td>
</tr>
</tbody>
</table>
Well if I understand you correctly. You can store the total sum of each table into array. I think the code explain alone... But I declare an array named
'total' outside of the for statement that contain the total of each table. When the foreach finish to sum all the values in tempTotal, then do a push to total array and save the operation of the first loop. and the second... third... etc
var total = [];
for(var i = 1; i <= 2; i++)
{
var tempTotal = 0;
var available = $(".used-community .plant_counter_"+i);
$.each(available, function(key, value)
{
tempTotal = tempTotal + parseInt(available[key].innerText);
});
total.push(tempTotal);
}
console.log(total);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table" border="1">
<thead>
<tr class="titlerow">
<th>Name</th>
<th>Address</th>
<th>Population</th>
<th>Collection 1</th>
<th>collection 2</th>
</tr>
</thead>
<tbody class="used-community">
<tr id="47" class="rowList middle">
<td>Wangkha</td>
<td>Soi Wangkha 3</td>
<td class="plant_counter_1">100000</td>
<td>31</td>
<td>11315</td>
</tr>
<tr id="43" class="rowList middle">
<td>one</td>
<td>one address</td>
<td class="plant_counter_1">35000</td>
<td>7</td>
<td>2555</td>
</tr>
<tr id="46" class="rowList middle">
<td>Bang</td>
<td>Bang khuwang Rd</td>
<td class="plant_counter_1">6000</td>
<td>2</td>
<td>730</td>
</tr>
<tr bgcolor="#66CCFF">
<td></td>
<td></td>
<td></td>
<td class="col"></td>
<td class="cap"></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<table class="table" border="1">
<thead>
<tr class="titlerow">
<th>Name</th>
<th>Address</th>
<th>Population</th>
<th>Collection 1</th>
<th>collection 2</th>
</tr>
</thead>
<tbody class="used-community">
<tr id="45" class="rowList middle">
<td>sap</td>
<td>sap thawi</td>
<td class="plant_counter_2">80000</td>
<td>15</td>
<td>5475</td>
</tr>
<tr id="44" class="rowList middle">
<td>two-nonthaburi</td>
<td>nonthaburi</td>
<td class="plant_counter_2">69000</td>
<td>11</td>
<td>4015</td>
</tr>
<tr bgcolor="#66CCFF">
<td></td>
<td></td>
<td></td>
<td class="col"></td>
<td class="cap"></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
I currently have a multiple column table with one column being a column full of checkboxes. Whenever I check a checkbox, I want an extra cell to appear on the right side of the table. Currently, when I check a checkbox, it displays the entire column, but I am wanting it to only display the cell that is in the corresponding row.
How can I do this?
My PHP/HTML code:
<table id="merchTable" cellspacing="5" class="sortable">
<thead>
<tr class="ui-widget-header">
<th class="sorttable_nosort"></th>
<th class="sorttable_nosort">Loc</th>
<th class="merchRow">Report Code</th>
<th class="merchRow">SKU</th>
<th class="merchRow">Special ID</th>
<th class="merchRow">Description</th>
<th class="merchRow">Quantity</th>
<th class="sorttable_nosort">Unit</th>
<th style="display: none;" class="num">Quantity #</th>
</tr>
</thead>
<tbody>
<?php foreach ($dbh->query($query) as $row) {?>
<tr>
<td><input type="checkbox" class="check" name="check"></td>
<td class="loc"></td>
<td class="rp-code" align="center"></td>
<td class="sku"></td>
<td class="special-id" align="center"></td>
<td class="description"></td>
<td class="quantity" align="center"></td>
<td class="unit"></td>
<td style="display: none;" class="quantity_num"></td>
</tr>
<?php } ?>
</tbody>
</table>
My JavaScript Code:
$(function () {
$(".check").change(function(){
$("#merchTable th.num").toggle(this.checked);
$("#merchTable td.quantity_num").toggle(this.checked);
});
});
I have changed my code to make it work with a JSFiddle so you can see something for an example of what I currently have and what is going on:
https://jsfiddle.net/d8494316/
Change your JS code to this:
$(function () {
$(".check").change(function(){
$(this).closest('tr').find('td.quantity_num').toggle(this.checked)
});
});
Here's a snippet:
$(function () {
$(".check").change(function(){
$(this).closest('tr').find('td.quantity_num').toggle(this.checked);
console.log($('input.check').is(':checked'))
if($('input.check').is(':checked'))
$(this).closest('table').find('th.num').toggle(true);
else
$(this).closest('table').find('th.num').toggle(false);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="merchTable" cellspacing="10" class="sortable">
<thead>
<tr class="ui-widget-header">
<th class="sorttable_nosort"></th>
<th class="sorttable_nosort">Loc</th>
<th class="merchRow">Report Code</th>
<th class="merchRow">SKU</th>
<th class="merchRow">Special ID</th>
<th class="merchRow">Description</th>
<th class="merchRow">Quantity</th>
<th class="sorttable_nosort">Unit</th>
<th style="display: none;" class="num">Quantity #</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" class="check" name="check"></td>
<td class="loc">Ex. 1</td>
<td class="rp-code" align="center">Ex. 2</td>
<td class="sku">Ex. 3</td>
<td class="special-id" align="center">Ex. 4</td>
<td class="description">Ex. 5</td>
<td class="quantity" align="center">Ex. 6</td>
<td class="unit">Ex. 7</td>
<td style="display: none;" class="quantity_num">Ex. 8</td>
</tr>
<tr>
<td><input type="checkbox" class="check" name="check"></td>
<td class="loc">Ex. 1</td>
<td class="rp-code" align="center">Ex. 2</td>
<td class="sku">Ex. 3</td>
<td class="special-id" align="center">Ex. 4</td>
<td class="description">Ex. 5</td>
<td class="quantity" align="center">Ex. 6</td>
<td class="unit">Ex. 7</td>
<td style="display: none;" class="quantity_num">Ex. 8</td>
</tr>
<tr>
<td><input type="checkbox" class="check" name="check"></td>
<td class="loc">Ex. 1</td>
<td class="rp-code" align="center">Ex. 2</td>
<td class="sku">Ex. 3</td>
<td class="special-id" align="center">Ex. 4</td>
<td class="description">Ex. 5</td>
<td class="quantity" align="center">Ex. 6</td>
<td class="unit">Ex. 7</td>
<td style="display: none;" class="quantity_num">Ex. 8</td>
</tr>
</tbody>
</table>
It's enough to change this line:
$("#merchTable td.quantity_num").toggle(this.checked);
to:
$(this).closest('td').nextAll(" td.quantity_num").toggle(this.checked);
In order to preserve the first column toggled if there are more than one checked element you can change:
$("#merchTable th.num").toggle(this.checked);
to:
$("#merchTable th.num").toggle($("#merchTable td.quantity_num:visible").length > 0);
This line must be added as last line.
Updated jsfiddle