JQuery unmerge table rows and populate with values - javascript

I have HTML table with merged rows. I need to unmerge them and fill with related values.
|column 1|column 2|column 3|column 4|column 5|column 6|
-------------------------------------------------------
| | Green |apples | | cow | 23 |
------------------ -------------------
| John | Red |Oranges |February| lion | 18 |
------------------ -------------------
| | |apples | | | 45 |
--------- ------------------ ----------
| | Blue |oranges | April | cow | 23 |
------------------ ----------
| Mary | | | May | | 49 |
-------- ----------------------------
| | green | apples | June | cat | 67 |
-------- ----------------------------
| | red | | July | mouse | 32 |
-------------------------------------------------------
At the end is should look like this:
|column 1|column 2|column 3|column 4|column 5|column 6|
-------------------------------------------------------
| John | Green |apples |February| cow | 23 |
-------------------------------------------------------
| John | Red |Oranges |February| lion | 18 |
-------------------------------------------------------
| John | Blue |apples |February| cow | 45 |
-------------------------------------------------------
| Mary | Blue |oranges | April | cow | 23 |
-------------------------------------------------------
| Mary | Blue |apples | May | dog | 49 |
-------------------------------------------------------
| Mary | green |apples | June | cat | 67 |
-------------------------------------------------------
| Mary | red |apples | June | mouse | 32 |
-------------------------------------------------------
I have no idea how to do this.
table, td{
border:1px solid grey;
margin:2em
}
td {
padding: 1em;
border-collapse: collapse;
}
<table>
<tbody>
<tr>
<td>column 1</td>
<td>column 2</td>
<td>column 3</td>
<td>column 4</td>
<td>column 5</td>
</tr>
<tr>
<td rowspan="2">John</td>
<td>green</td>
<td>apples</td>
<td rowspan="2">February</td>
<td>cow</td>
</tr>
<tr>
<td>red</td>
<td>oranges</td>
<td>lion</td>
</tr>
<tr>
<td rowspan="2">Mary</td>
<td>blue</td>
<td rowspan="2">meat</td>
<td rowspan="2">May</td>
<td>dog</td>
</tr>
<tr>
<td>white</td>
<td>cat</td>
</tr>
</tbody>
</table>

Here's is one approach:
Initialize an array of the same size as the target table.
Run through the row of the existing table and populate the array
Use the resulting array to rebuild the desired table
See steps 1 & 2 (& 3) in demo below:
jQuery($ => {
$table = $('table tbody');
let rows = $table.find('tr').length;
let columns = $table.find('tr').not(':has(td[rowspan]').first().find('td').length;
let table = [];
for (let j = 0; j < rows; j++) {
table[j] = [];
for (let l = 0; l < columns; l++) {
table[j][l] = null;
}
}
let row = 0;
$('tr').each(function() {
let column = 0;
$('td', this).each(function() {
while(table[row][column]) {
column++;
}
table[row][column] = $(this).text();
if ($(this).is('[rowspan]')) {
for (let i = 0; i < +$(this).attr('rowspan') - 1; i++) {
let thisrow = row+i+1;
table[thisrow][column] = $(this).text();
}
}
column++;
});
row++;
});
//step 3
//empty the table
$table.empty();
//rebuild the table
for (let k = 0; k < table.length; k++) {
$table.append(
$('<tr/>').append(
table[k].map(col => $('<td/>').text( col ))
)
);
}
});
table, td{
border:1px solid grey;
margin:2em
}
td {
padding: 1em;
border-collapse: collapse;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>column 1</td>
<td>column 2</td>
<td>column 3</td>
<td>column 4</td>
<td>column 5</td>
</tr>
<tr>
<td rowspan="2">John</td>
<td>green</td>
<td>apples</td>
<td rowspan="2">February</td>
<td>cow</td>
</tr>
<tr>
<td>red</td>
<td>oranges</td>
<td>lion</td>
</tr>
<tr>
<td rowspan="2">Mary</td>
<td>blue</td>
<td rowspan="2">meat</td>
<td rowspan="2">May</td>
<td>dog</td>
</tr>
<tr>
<td>white</td>
<td>cat</td>
</tr>
</tbody>
</table>

Related

HTML Table in PDF

I am trying to print HTML table into PDF using JSPdf. My table have 20 columns. Because of that, I couldn't print the entire table. Last 4-6 column always goes hidden. Is there is anyway to make visible or bring down the hidden content ?
HTML
<div class="table-responsive" >
<table class="table table-bordered">
<thead>
<tr>
<th>Year Lease</th>
<th>user Name</th>
<th>Total Rent</th>
<th>Other Income</th>
<th>Total Income</th>
<th>Avg Expenses at 4 %</th>
<th>Value Added Expense</th>
<th>Other Expense</th>
<th>Total Expense</th>
<th>NOI</th>
<th>CAP Rate</th>
<th>Interest Paid</th>
<th>Net Income</th>
<th>Principal</th>
<th>Yearly Cashflow</th>
<th>Yearly</th>
<th>DS Ratio</th>
</tr>
</thead>
<tbody *ngFor="let userInfo of user;index as i">
<tr>
<td>Year {{i+1}} Leased</td>
<td *ngFor="let user of userInfo.user">{{user.amount | currency}}</td>
<td>{{user.grossIncome | currency}}</td>
<td>{{user.otherIncome | currency }}</td>
<td>{{user.totalIncome | currency }}</td>
<td>{{user.totalExpense}}</td>
<td>{{user.valueAddedExpense | currency}}</td>
<td>{{user.otherExpense | currency}}</td>
<td>{{user.totalExpense | currency}}</td>
<td>{{user.netOperatingIncome | currency}}</td>
<td>{{user.capRate}}% </td>
<td>{{user.mortageInterest | currency}}</td>
<td>{{user.netIncome | currency}}</td>
<td>{{user.principle | currency}}</td>
<td>{{user.yearlyCashFlow | currency}}</td>
<td>{{user.yearly}} %</td>
<td>{{user.deptServiceRatio}} %</td>
</tr>
</tbody>
</table>
</div>
TS
var pdf = new jsPDF('p','pt', 'a3');
pdf.internal.scaleFactor = 1.40;
pdf.addHTML(this.print.nativeElement, 0, 0, {
pagesplit: true
}, ()=> {
pdf.save('Report-' + new Date() + '.pdf');
});
Issue
There are still 4 more column left after CAP Rate. Please help me out
Y must set your pdf height like this:
var width = pdf.internal.pageSize.getWidth();
var height = pdf.internal.pageSize.getHeight();

Grouping HTML table rows with rowspan

I am struggling with this issue for a while and really appreciate if someone can give some idea on how I can move forward with.
The idea is to reduce the number of rows in the table by grouping the relevant data in the below format.
I need to convert the JSON response coming from server (non-grouped data) to a particular format so that I can paint the table with the grouped data.
**Initial Layout**
+------------+-----------+--------+------------+
| Category | Product | Size | Shipping
+------------+-----------+--------+------------+
| Category 1 | Product 1 | Big | Free |
| Category 1 | Product 2 | Small | Free |
| Category 1 | Product 3 | Big | Free |
| Category 1 | Product 4 | Small | Free |
+------------+-----------+--------+-------------
**Expected Result**
+------------+----------------------+--------+-----------
| Category | Product | Size | Shipping
+------------+----------------------+--------+------------
| Category 1 | Product 1, Product 3 | Big | Free |
| | Product 2, Product 4 | Small | Free |
+------------+----------------------+--------+----------
More details in the jsfiddle:
https://jsfiddle.net/zy8kj2tb/2/
// please see the code in jsfiddle
<h3>
Initial layout:
</h3>
<h6>
<p>
Category = Category 1, Category 2, etc or "blank"
</p>
<p>
Product = Product 1, Product 2, etc or "blank"
</p>
<p>
Size = Big, Small, XL, etc or "blank"
</p>
<p>
Shipping = Free, Standard, Expedited, etc or "blank"
</p>
<p>
dont group blank rows with cat, prod, size = make it as individual row
</p>
</h6>
<div id="initialLayout">
</div>
<h3>Expected result:</h3>
<table id="expectedTable" border="1" cellpadding="3" cellspacing="0">
<tr>
<th>Category</th>
<th>Product</th>
<th>Size</th>
<th>Shipping</th>
</tr>
<tr>
<td rowspan=2>Category 1</td>
<td rowspan="2">Product 1, Product 3 <br>Product 2, Product 4</td>
<td rowspan="2">Big <br>Small</td>
<td rowspan="2">Free</td>
</tr>
</table>
<br/>
Just replace your HTML with this one, I did two things -
Changed first row with -
<td rowspan="2">Product 1, Product 3 <br>Product 2, Product 4</td>
<td rowspan="2">Big <br>Small
</td>
Removed respective td tags from the second row
I just looked at your code
where you have written
<td rowspan=2>Category 1</td>
<td>Product 1, Product 3</td>
<td>Big</td>
<td rowspan=2>Free</td>
It should be
<td rowspan="2">Category 1</td>
<td>Product 1, Product 3</td>
<td>Big</td>
<td rowspan="2">Free</td>
you have just missed some quotes

How to add the count values of similar event id using javascript?

I have a table in which there are three columns i.e. Event id, Event and Counts. There can be multiple rows with same event id having their own counts values under Counts column. I have to find out the distinct Event id and then add up their corresponding count values and display the output table with distinct Event id, Event and Count in which the count value will be total sum of available counts. I tried to show tabular form of what I want to do as following:
+--------+--------------+----------+
| Ashley Janes |
+--------+--------------+----------+
|Eventid | Event | Count |
+--------+--------------+----------+
| 5 | Wash apple | 10 |
| 2 | cook potatoes| 20 |
| 8 | cut chillies | 5 |
+--------+--------------+----------+
| Taylor Perry |
+--------+---------------+---------+
| 2 | cook potatoes | 30 |
| 5 | Wash apple | 40 |
| 8 | cut chillies | 60 |
Now I have to add count values of corresponding event id and display it in a result table as following::
+--------+--------------+----------+
|Eventid | Event | Count |
+--------+--------------+----------+
| 5 | Wash apple | 50 |
| 2 | cook potatoes| 50 |
| 8 | cut chillies | 65 |
+--------+--------------+----------+
so far I have done following:
Response.Write "<div><table><tr>"
Response.Write"<td class='tdcell1'>Event ID</td><td class='tdcell1'>Count</td></tr>"
Response.Write"<tr><td align=center width= '15%'></td><td><div class= 'resultSum'></div></td></tr>"
Response.Write"</table><div>"
<script>
$(function() {
GetEventIds('#displaytable')
});
function GetEventIds(tableIdWithHash) {
var eventIds = [];
var eventSum = Number(0);
var count = Number(0);
$(tableIdWithHash).find('.Idevent').each(function(i){
var eId = $(this).html();
if (eventIds.indexOf(eId) === -1)
eventIds.push($(this).html());
if (eId = eventIds)
count++;
eventSum += Number($(this).html());
$(".resultSum").html(eventSum);
});
alert('EventIds: ' + JSON.stringify(eventIds));
return eventIds;
}
</script>
Code for the table need to be parsed.
<table id= 'displaytable' width='35%' border=1 style= 'margin-bottom:35px; margin-top:35px;'>
<tr>
<td class='tdcell1'>Event ID</td>
<td class='tdcell1'>Event</td>
<td class='tdcell1'>Count</td>
</tr>
<tr style='font-size:13px;'>
<td align='right' class='tdcell1' colspan='3'>Ashley Janes</td>
</tr>
<tr style='font-size:13px;'>
<td align=center class='Idevent' width= '15%'> 5 </td>
<td align=center class='eventNames' width= '35%'> Wash Apple </td>
<td class='eventCounts' align=center width= '15%'>11</td>
</tr>
<tr style='font-size:13px;'>
<td align=center class='Idevent' width= '15%'> 2 </td>
<td align=center class='eventNames' width= '35%'> Cook Potatoes </td>
<td class='eventCounts' align=center width= '15%'>20</td>
</tr>
<tr style='font-size:13px;'>
<td align='right' class='tdcell1' colspan='3'>Taylor Perry</td>
</tr>
<tr style='font-size:13px;'>
<td align=center class='Idevent' width= '15%'> 2 </td>
<td align=center class='eventNames' width= '35%'> Cook Potatoes </td>
<td class='eventCounts' align=center width= '15%'>20</td>
</tr>
<tr style='font-size:13px;'>
<td align=center class='Idevent' width= '15%'> 5 </td>
<td align=center class='eventNames' width= '35%'> Wash Apple </td>
<td class='eventCounts' align=center width= '15%'>106</td>
</tr>
</table>
My code gives me the output for the sum of the event id not the counts. How do I do it using JavaScript? Please help.
Take a look at this code and wether works as you expect it.
$(function() {
GetEventIds('#displaytable')
});
//this is a bad function, because it does way more than it says.
function GetEventIds(tableIdWithHash) {
//a little helper
//convert a value to int32. any non-numeric value -> 0
//only the low 32-bits are kept, if the value exceeds the range
//and removes all bits after the dot (2.9 -> 2 and -2.9 -> -2)
function int(v){ return v|0; }
var eventSum = 0;
var events = {};
$(tableIdWithHash).find('.Idevent').each(function(i){
var $this = $(this);
var eId = $this.text().trim();
//finding the .eventCount-node of this row
var count = int( $this.siblings('.eventCounts').text().trim() );
events[eId] = int( events[eId] ) + count;
//still don't get what #resultSum should contain (logically)
//the total amount of events, independent of the event-id?
eventSum += count;
});
$("#resultSum").html(eventSum);
var eventIds = Object.keys(events);
console.log('EventIds: ', eventIds);
console.log('Event counts by Id: ', JSON.stringify(events));
return eventIds;
}
Still need some info on the purpose/meaning of #resultSum. I made just an assumption on that; am i right?
And as I commented on the function, What is the purpose of this function? It does more than it says. This may lead to confusion/bugs. Maybe you want to split this into multiple functions, or rename it and drop the return-value.
Or maybe you want to parse the table into some data-structure and operate on this? But then again it may be wiser to paste JSON out of the backend, than parsing some markup.

ng-repeat table with one nested col

I have working code:
senderAddress = {
key1 = "val1",
key2 = "val2",
billings = {"bilKey1": "bilVal1", "bilKey2", "bilVal2" ...},
keyN = "valN"
};
<table class="table table-hover" >
<tbody>
<tr ng-repeat="(key, value) in senderAddress">
<td>
<strong translate="senderAddress.details.{{key}}"></strong>
</td>
<td ng-if="key === 'billing'">
<table class="table table-hover">
<tbody>
<tr ng-repeat="(billingKey, billingValue) in value">
<td>
<strong translate="senderAddress.details.billings.{{billingKey}}"></strong>
</td>
<td ng-switch="key">
<span ng-switch-when="expiration_date">{{billingValue | date:'MMM d, y H:mm:ss'}}</span>
<span ng-switch-default="">{{billingValue}}</span>
</td>
</tr>
</tbody>
</table>
<span></span>
</td>
<td ng-if="key !== 'billing'" ng-switch="key">
<span ng-switch-when="created_date" >{{value| date:'MMM d, y H:mm:ss'}}</span>
<span ng-switch-when="last_updated_date" >{{value| date:'MMM d, y H:mm:ss'}}</span>
<span ng-switch-when="birth_date" >{{value| date:'MMM d, y H:mm:ss'}}</span>
<div ng-switch-when="attachments" >
<show-attachments info="value"></show-attachments>
</div>
<span ng-switch-default>{{value}}</span>
</td>
</tr>
</tbody>
</table>
This outputs table as we except:
-------------------------------------
|key1 |val1 |
-------------------------------------
|key2 |val2 |
-------------------------------------
| |bilKey1 | bilVal1| |
|billings|bilKey2 | billVal2 |
| |bilKey2 | billVal2 |
-------------------------------------
|keyN |valN |
-------------------------------------
I need the following output:
-------------------------------------
|key1 |val1 |
-------------------------------------
|key2 |val2 |
-------------------------------------
|billings| |
-------------------------------------
| |bilKey1 |bilVal1 |
| |bilKey2 |bilVal2 |
| |bilKey3 |bilVal3 |
-------------------------------------
|keyN |valN |
-------------------------------------

Insert multiple rows in a cell in HTML Table

I am trying to insert rows within a cell in HTML Table using jquery, I want something like this:
--------------
ID | Sec | Div
--------------
1 | S1 | D1
| S2 | D2
| S3 | D3
--------------
2 | S3 | D3
| S4 | D4
| S5 | D5
--------------
Here is what I have so far:
function insertRows(this){
var Rows1 = '<tr><td> S1 </td></tr><tr><td> S2 </td></tr><tr><td> S3 </td></tr>'
var Rows2 = '<tr><td> S3 </td></tr><tr><td> S4 </td></tr><tr><td> S5 </td></tr>'
this.srcElement.parentElement.nextSibling.outerHTML = Rows1
this.srcElement.parentElement.nextSibling.nextSibling.outerHTML = Rows2
}
What is does is, it inserts all in the same Row, something like this:
---------------------
ID | Sec | Div
---------------------
1 | S1S2S3 | D1D2D3
---------------------
2 | S3S4S5 | D3D4D5
---------------------
How can I make this to work?
You Can Fullfill your requirement without using jquery
just Paste this Code inside body tag
<table>
<tr>
<td >ID</td>
<td>SEC</td>
<td>DIV</td>
</tr>
<tr>
<td rowspan="3">1</td>
<td>S1</td>
<td>D1</td>
</tr>
<tr>
<td>S2</td>
<td>D2</td>
</tr>
<tr>
<td>S3</td>
<td>D3</td>
</tr>
<tr><td colspan="3">---------------------</td></tr>
<tr>
<td>ID</td>
<td>SEC</td>
<td>DIV</td>
</tr>
<tr>
<td rowspan="3">2</td>
<td>S1</td>
<td>D1</td>
</tr>
<tr>
<td>S2</td>
<td>D2</td>
</tr>
<tr>
<td>S3</td>
<td>D3</td>
</tr>
</table>
here you can find live example http://jsfiddle.net/Anujyadav123/AdQy3/
.innerHTML is rather broken when dealing with tables, at least under IE.
Your choices are:
Restrict the use of .innerHTML to only change the contents of a td element.
Use .innerHTML to replace the ENTIRE table structure
Use DOM methods to manipulate table rows and table cells.
https://developer.mozilla.org/en-US/docs/Traversing_an_HTML_table_with_JavaScript_and_DOM_Interfaces
take a look here Add colspan and rowspan on table on the fly
OR
is it important to add row, if not you are able to add your values into cell
Example:
function showP(){
txt1 = $($('#myTable').find('TR').find('TD')[1]).html()+'</br>S1'
txt3 = $($('#myTable').find('TR').find('TD')[3]).html()+'</br>D1'
$($('#myTable').find('TR').find('TD')[1]).html(txt1 )
$($('#myTable').find('TR').find('TD')[3]).html(txt3 )
}

Categories