Place parallel table columns that are inside separate div's aligned - javascript

I have two div's, one above the other and both have a table inside them with the same amount of columns. I want the columns to be the same width size in both and aligned. If a columns in on div expands, i want the column parallel in the other div to expand to the same with.
NB: The Columns have no width.
Link to the HTML code below:
HTML:
<div id="A">
<table>
<tbody>
<tr>
<th></th>
<th>Blah! Blah</th>
<th>adsdsdadasdasdasdasd</th>
</tr>
</tbody>
</table>
</div>
<br/>
<div id="B">
<table>
<tr>
<th>left head</th>
<td class="col1"></td>
<td class="col2">Hello World!</td>
</tr>
<tr>
<th>left head</th>
<td class="col1">Hello World!</td>
<td class="col2">dsfsdfgdsgdsgdsfgdsgdsgfdfgdf</td>
</tr>
</table>
</div>
JQuery:
$(document).ready(function() {
$('#updatetopdiv').click(function(){
//Properly align parallel div's top to bottom
var tbl1 = $("#A table tr td");
var tbl2 = $("#B table tr td");
tbl1.each(function(i) {
if (tbl2.eq(i).width() < $(this).width()) {
tbl2.eq(i).width($(this).width());
} else {
$(this).width(tbl2.eq(i).width());
}
});
});
});​
​

​$(document).ready(function(){
var tbl1 = $("#A table tr td");
var tbl2 = $("#B table tr td");
tbl1.each(function(i){
if (tbl2.eq(i).width() < $(this).width()){
tbl2.eq(i).width($(this).width());
} else {
$(this).width(tbl2.eq(i).width());
}
});
});​
This works, though it doesn't run until load.
Also placed here: http://jsfiddle.net/gwUFb/3/
EDIT:
I know you said you already got it working, but here's my original code, edited for your use case:
$(document).ready(function(){
var tbl1 = $("#A table tr th");
var tbl2 = $("#B table tr td,#B table tr th");
tbl1.each(function(i){
if (tbl2.eq(i).width() < $(this).width()){
tbl2.eq(i).width($(this).width());
} else {
$(this).width(tbl2.eq(i).width());
}
});
});​

html will be:
<div id="A">
<table class="fixed-table">
<tr>
<td class="column-a">Hello World!</td>
<td class="column-b"></td>
</tr>
</table>
</div>
<br/>
<div id="B">
<table class="fixed-table">
<tr>
<td class="column-a"></td>
<td class="column-b">Hello World!</td>
</tr>
</table>
</div>
css will be
.fixed-table {
table-layout: fixed;
}
.column-a {
width: 50%;
}
.column-b {
width: 50%;
}
this is a fixed solution, not dynaimic, if any div scroll appears, alignment break. for this you have to use javascript.

Related

How to create a JavaScript loop that adds DOM properties to attributes?

I have a table with cells that are not contentEditable. However, using a JavaScript loop or function, I would like to make them so.
I understand that it is very simple to do this manually for each cell, and this would probably be easier for a table with only a few cells, but I would like to quicken this process with a loop/function for the table could become much larger, and the time spent manually setting each cell to be contentEditable would be tedious.
Below is a quick example that displays a table calculator, un-editable at present. But using a loop or function, I'd like to make every cell in the right column set to .contentEditable = true in the DOM. I imagine that the parameters would look something like (var i = 0; l != rows.length; i < l; i+2), but I'm struggling with what the statements following the argument would have to be for the loop/function to work. Any help would be much appreciated!
function myFunction() {
var jack2 = document.getElementById("jack").innerText;
var john2 = document.getElementById("john").innerText;
var joe2 = document.getElementById("joe").innerText;
var total2 = (parseInt(jack2) || 0) + (parseInt(john2) || 0) + (parseInt(joe2) || 0);
document.getElementById("total").innerHTML = total2;
}
table {
width: 100%;
}
table,
tr,
th,
td {
border: 1px solid gray;
border-collapse: collapse;
font-family: Arial;
margin: 5px;
}
<table>
<caption>Weight Calculator</caption>
<tr class="cell">
<th>Person</th>
<th>Weight (kg)</th>
</tr>
<tr class="cell">
<td>Jack</td>
<td id="jack" oninput="myFunction()">1</td>
</tr>
<tr class="cell">
<td>John</td>
<td id="john" oninput="myFunction()">2</td>
</tr>
<tr class="cell">
<td>Joe</td>
<td id="joe" oninput="myFunction()">3</td>
</tr>
<tr class="cell">
<td>Total</td>
<td id="total"></td>
</tr>
</table>
Get all cell in the tabel that have a left neigbour (the header is not effected because there are th and not td). Add to each of these cells your attribute.
Edited: For getting the totalsum add an eventlistener on each td that calls the calc-function if the content changes.
function myFunction() {
let weightCells = document.querySelectorAll("table tr:not(:last-child) td ~ td");
weightCells.forEach(td => {
td.setAttribute('contentEditable', true);
td.addEventListener ("change", calcSum());
});
}
function calcSum() {
let sum=0;
let weightCells = document.querySelectorAll("table tr td ~ td");
let count = weightCells.length-1;
for (i=0; i<count; i++) {
sum += parseInt(weightCells[i].innerHTML) || 0;
}
weightCells[count].innerHTML = sum;
}
myFunction();
table {
width: 100%;
}
table,
tr,
th,
td {
border: 1px solid gray;
border-collapse: collapse;
font-family: Arial;
margin: 5px;
}
<table>
<caption>Weight Calculator</caption>
<tr class="cell">
<th>Person</th>
<th>Weight (kg)</th>
</tr>
<tr class="cell">
<td>Jack</td>
<td id="jack" oninput="myFunction()">1</td>
</tr>
<tr class="cell">
<td>John</td>
<td id="john" oninput="myFunction()">2</td>
</tr>
<tr class="cell">
<td>Joe</td>
<td id="joe" oninput="myFunction()">3</td>
</tr>
<tr class="cell">
<td>Total</td>
<td id="total"></td>
</tr>
</table>
You can select the whole table, then use querySelectorAll to get all rows then for each rows change the contenteditable for the second td like this
codepen
let table = document.getElementById('table')
let rows = table.querySelectorAll('tr')
rows.forEach(row => {
let tds = row.querySelectorAll('td')
// all the cells of the row
if (tds.length > 0) { // if it is not the header
tds[1].contentEditable = true
// change the contenteditable
}
})
(you need to add an id to your table in case you have more than one table)
<table id="table">
...
</table>

How to get td innerHTML per row and then set div css per row based on this value

I have a table as per the below and I want to use javascript or Jquery to get the value from the middle cell of each row. I then want to see the width of a div (id="myprogres") in the last cell to match the percentage that we just got.
My problems that I know of are
my td tags don't have an id or anything unique to identify them by. So identifying the 3rd td on each row isn't as simple as getElementById
I want to get the value on each row, and then set the corresponding myprogress width based upon that value.
myprogress is not a unique id, it's the same id per row.
This is a simplified version of the table so I appreciate the full css isn't there.
<table>
<tr>
<td>Hard drive</td>
<td>Usage</td>
<td>25</td>
<td>
<div style="width:100%">
<div id="myprogress"></div>
</div>
</td>
</tr>
<tr>
<td>Memory</td>
<td>Usage</td>
<td>50</td>
<td>
<div style="width:100%">
<div id="myprogress"></div>
</div>
</td>
</tr>
<tr>
<td>Brain Power</td>
<td>Usage</td>
<td>75</td>
<td>
<div style="width:100%">
<div id="myprogress"></div>
</div>
</td>
</tr>
</table>
My td tags don't have an id or anything unique to identify them by.
This isn't a problem as you can loop over the progress bars directly.
I want to get the value on each row, and then set the corresponding myprogress width based upon that value.
As above, you can loop over the progress bars and use DOM traversal methods to get the related value from the previous td cell to set as the width of the bar. Specifically the closest() and prev() methods.
myprogress is not a unique id, it's the same id per row.
This is invalid HTML and needs to be fixed. Use a class instead.
With all that said, try this:
$('.myprogress').css('width', function() {
return $(this).closest('td').prev().text() + '%';
});
table {
width: 100%;
}
table td {
width: 25%;
}
.myprogress {
height: 20px;
background-color: #C00;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<table>
<tr>
<td>Hard drive</td>
<td>Usage</td>
<td>25</td>
<td><div class="myprogress"></div></td>
</tr>
<tr>
<td>Memory</td>
<td>Usage</td>
<td>50</td>
<td><div class="myprogress"></div></td>
</tr>
<tr>
<td>Brain Power</td>
<td>Usage</td>
<td>75</td>
<td><div class="myprogress"></div></td>
</tr>
</table>
First find all the divs in 4th td of the table
var divs = $("tr td:nth-child(4) div");
run a loop to set the width of the div and get the value from the 3rd td
for(var i=0;i<divs.length;i++) {
$(divs[i]).css({'width': $(divs[i]).parent().prev('td').text() + '%'});
}
Using pure Vanilla JS, you can achieve the result without jquery, with the help of querySelector() method..
const table = document.querySelector('table');
const row = table.querySelectorAll('tr');
row.forEach((tr,i) => {
const width = tr.querySelectorAll("tr td:nth-of-type(3)")[0].textContent;
const progress = tr.querySelectorAll("tr td:nth-of-type(4)")[0];
progress.querySelector('div').style.width = `${width}%`;
})
table td {
width: 10%;
}
#myprogress {
height: 20px;
background-color: green;
}
<table>
<tr>
<td>Hard drive</td>
<td>Usage</td>
<td>25</td>
<td>
<div style="width:100%">
<div id="myprogress"></div>
</div>
</td>
</tr>
<tr>
<td>Memory</td>
<td>Usage</td>
<td>50</td>
<td>
<div style="width:100%">
<div id="myprogress"></div>
</div>
</td>
</tr>
<tr>
<td>Brain Power</td>
<td>Usage</td>
<td>75</td>
<td>
<div style="width:100%">
<div id="myprogress"></div>
</div>
</td>
</tr>
</table>

Collapsing and expanding multiple nested rows in jQuery

I need a little help with collapsing and expanding nested rows. Currently my code below expands and collapses as desired at the first level but the subsequent levels also show.
$(document).ready(function(e) {
$('.collapseTitle').click(function() {
$(this).parent()
.parent()
.next('tbody')
.toggleClass('collapsed');
});
});
.collapsed {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<td class="collapseTitle">Title</td>
</tr>
</thead>
<tbody class="collapsed">
<tr>
<td>Level 1</td>
</tr>
<tr>
<td>Level 2</td>
</tr>
</tbody>
</table>
I am trying to achieve that Level 1 expands when "collapseTitle" is clicked and that only when "collapseAccount" is clicked, does Level 2 expand. Now I know that my code should look something like the below, but I am struggling...
<table>
<thead>
<tr>
<td class="collapseTitle">Title</td>
</tr>
</thead>
<tbody>
<tr class="collapsed account">
<td class="collapseAccount">Level 1</td>
</tr>
<tr class="collapsed level">
<td>Level 2</td>
</tr>
</tbody>
</table>
<script>
$(document).ready(function(e) {
$('.collapseTitle').click(function() {
$(this).parent().parent().next('tbody tr').toggleClass('account');
});
});
$(document).ready(function(e) {
$('.collapseAccount').click(function() {
$(this).next('tr').toggleClass('level');
});
});
</script>
Any help would be greatly appreciated.
The following code should do it. I hope it helps with what you want to achieve:
collapses/expands columns when clicking on the header/title of the column and
collapses/expands all rows following the account row when clicking on it (until the next account row)
The only thing you need to do is add the class account to the higher level rows. You can do this pretty easily when you're displaying these with a loop.
.collapsed {
/* using visibility, since display causes layout issues */
/* due to empty rows rows/columns collapsing */
visibility: collapse;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<td>Title1</td>
<td>Title2</td>
</tr>
</thead>
<tbody>
<tr class="account">
<td class="collapsed">Account Summary - Account A</td>
<td class="collapsed">Account Summary - Account A</td>
</tr>
<tr class="collapsed">
<td class="collapsed">Account Details Part I - Account A</td>
<td class="collapsed">Account Details Part I - Account A</td>
</tr>
<tr class="collapsed">
<td class="collapsed">Account Details Part II - Account A</td>
<td class="collapsed">Account Details Part II - Account A</td>
</tr>
<tr class="account">
<td class="collapsed">Account Summary - Account B</td>
<td class="collapsed">Account Summary - Account B</td>
</tr>
<tr class="collapsed">
<td class="collapsed">Account Details Part I - Account B</td>
<td class="collapsed">Account Details Part I - Account B</td>
</tr>
</tbody>
</table>
<script>
$(document).ready(() => {
/* the following handlers expand/collapse the columns */
$('thead > tr > td').each((i, el) => {
$(el).click(() => {
const colIndex = $(el).index() + 1;
const nRows = $('tbody > tr').length;
for (let j = 0; j < nRows; j += 1) {
let cellSelector = `tbody > tr:nth-child(${j+1})`
cellSelector += `> td:nth-child(${colIndex})`;
$(cellSelector).toggleClass('collapsed');
}
})
})
/* the following handlers expand/collapse the account-details rows */
$('tbody > tr.account').each((i, el) => {
$(el).click(() => {
$(el).nextUntil('.account').each((j, ele) => {
$(ele).toggleClass('collapsed');
})
})
})
});
</script>
Your jQuery selectors are just a bit off for the toggleClass. You can use the class names of the row to toggle. Also you should create a class to be toggled that displays the row/hides it. For example:
edit:
I now created the titles and rows dynamically to give you a better idea of how this can be done using data- attributes.
You will have a title td and a row td that match on a data- attribute, so when you click a title and corresponding tr will be shown. So for example if you click title 1 (with a data-index=1) then the tr with the attribute data-rowindex=1 will be shown.
$(document).ready(function(e) {
createTable();
$('.collapseTitle').click(function() {
// grab the data-index value from the clicked title
let index = $(this).attr("data-index");
// find a tr that has the attribute data-rowindex and it matches index
$("tr[data-rowindex='" + index + "']").toggleClass("collapsed");
});
});
function createTable(){
// create the titles and the level rows
for(let i = 0; i < 3; i++){
// create the title row
let $trTitle = $('<tr>');
let $tdTitle = $('<td>', {class: "collapseTitle", text: "Title " + i});
$tdTitle.attr("data-index", i);
let $finalTitleRow = $trTitle.append( $tdTitle );
// create the level row
let $trLevel = $('<tr>', {class: "collapsed account"} );
$trLevel.attr("data-rowindex", i);
let $tdLevel = $('<td>', {text: "Level " + i});
let $finalLevelRow = $trLevel.append( $tdLevel );
// add the title and level row pairs to the head and body
$("#myTableHead").append($finalTitleRow[0]);
$("#myTableBody").append($finalLevelRow[0]);
}
}
.collapsed {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead id="myTableHead">
</thead>
<tbody id="myTableBody">
</tbody>
</table>
I managed to find the answer I was looking for... Thank you to "stackoverfloweth",
Answer To My Question
The snippet of code which has helped me thus far is below,
$('.parent-row').click(function(){
var $element = $(this).next();
while(!$element.hasClass('parent-row')){
$element.toggle();
if($element.next().length >0){
$element = $element.next();
}
else{
return;
}
} });
$('.child-row.has-children').click(function(){
var $element = $(this).next();
while($element.hasClass('child-child-row')){
$element.toggle();
if($element.next().length >0){
$element = $element.next();
}
else{
return;
}
} });

Move and delete data from one table to another table using javascript or jquery

Step 1 : In table 1st table i want to copy table row the 2nd table, when click on the "copy" button after inputting the value in input text field.(value should be copied instead of input text field)
Step 2 : After click on the "copy" button the button should be change to "Undo" to remove the table row from 2nd table.
Step 3 : after deleting the row from 2nd table the button should be changed again to "copy" button with step 1 functionality in table 1.
Step 4 : the copied row in 2nd table should have "Delete" button.When click on the delete button the row should be deleted from 2nd table and the button should be changed again to"copy" button with step 1 functionality in table 1.
$(function() {
$('#myTable tbody tr').each(function(){
$(this).append('<td><button class="copy">Copy</button></td>');
});
$(document).on('click', 'button.copy', function(){
var $tr = $(this).parents('tr:first').clone();
$tr.appendTo($('#stopsTable > tbody'));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div style="height: 700px;width: 100%;overflow: auto; float: left;">
<table id="myTable" border="1px" style="width: 24%; font-size: 10px; float :left;" >
<thead>
<tr>
<th>S No</th>
<th>Stop Name</th>
<th>Longitude</th>
<th>Latitude</th>
<th>ETA</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr >
<td >1</td>
<td>The Indian Heights School</td>
<td><input type="text" width="70"/></td>
<td>77.05249</td>
<td>06:06:12</td>
<td>Ignition_On</td>
</tr>
<tr >
<td >2</td>
<td>The Indian Heights School</td>
<td><input type="text" width="70"/></td>
<td>77.05246</td>
<td>06:06:23</td>
<td>Ignition_On</td>
</tr>
<tr >
<td >3</td>
<td>The Indian Heights School</td>
<td>28.56135</td>
<td>77.05242</td>
<td>06:06:31</td>
<td>Start</td>
</tr>
<tr >
<td >4</td>
<td>The Indian Heights School</td>
<td>28.56139</td>
<td>77.05245</td>
<td>06:06:41</td>
<td>Ignition_On</td>
</tr>
</tbody>
</table>
<table id="stopsTable" border="1px" style="width: 24%; margin-left: 10px; font-size: 10px; float :left;">
<thead>
<tr>
<th>S No</th>
<th>Stop Name</th>
<th>Longitude</th>
<th>Latitude</th>
<th>ETA</th>
<th>Status</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
jsfiddle or codepen example will be very appriciated.Thanks in advance.
not exactly what you wanted but might give you the idea.
Append button 'copy' to table #myTable
copy row from table #myTable to #stopsTable and append button remove while hiding button copy.
add class .remove to button remove with remove() function. (It will remove table row when clicking the remove button.)
$(function() {
$('#myTable tbody tr').each(function() {
$(this).append('<td><button class="copy">Copy</button></td>');
});
$(document).on('click', 'button.copy', function() {
var $tr = $(this).parents('tr:first').clone();
$tr.appendTo($('#stopsTable > tbody'));
$tr.append('<td><button class="remove">Remove</button></td>');
var $td = $('#stopsTable > tbody > tr').find('td:eq(6)').hide();
});
$(document).on('click', 'button.remove', function() {
$(this).closest('tr').remove()
});
});

How to include rowspan and colspan dynamically inside <td> tag based on some conditions

I know I can include <td colspan=10> statically when I want to merge the columns, but if I need to check some conditions and based on that only I need to merge then how this could be done?
My idea was like this:
var span="";
if(some condition)
span="colspan=10";
and then setting this variable inside <td> as:
<td +span+>
but it doesn't work like that… Any suggestion how to do this?
<table id="table" border=2>
<tr id="row1">
<td id="tableCellID">foo</td><td></td>
</tr>
<tr>
<td>foo</td><td>foo</td>
</tr>
</table>
<button onclick="button();" text="Change"/>
<script language="javascript">
var i = 0;
function button(){
var td = document.getElementById("tableCellID");
if(i==0){
td.setAttribute("colspan", 2);
i=1;
}else{
td.setAttribute("colspan", 1);
i=0;
}
}
</script>
This is how you can dynamically set the attribute colspan. You will see that changing the colspan of one cell will effect the layout of the entire table. You will need to deal with each cell in the row.
var span='';
var table='';
if(some condition)
span="colspan=10";
var table="<tr><td"+span+"></td></tr>":
One way to do is, if you able to set an id in your td
<td id="foo">
in your javascript, you can add attributes like this,
document.getElementById("foo").colSpan="10";
document.querySelector("tr.total td").style.backgroundColor = "#ccc";
document.querySelector("tr.grand td:nth-child(1)").colSpan="2";
document.querySelector("tr.grand td:nth-child(2)").remove();
table, table td {border:1px solid #ccc; padding:5px 10px; border-spacing:0px;}
.grand{font-weight:bold;}
<table>
<tr>
<td>Column</td>
<td>Value</td>
</tr>
<tr class="total">
<td>Sub Cost</td>
<td>$500</td>
</tr>
<tr class="grand">
<td>Amount $1000</td>
<td>Remove Me</td>
</tr>
</table>

Categories

Resources