ng-repeat table with one nested col - javascript

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 |
-------------------------------------

Related

JQuery unmerge table rows and populate with values

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>

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();

AngularJs - Reference the same scope property from multiple ngRepeat's

I have multiple ngRepeats generate table contents, depending on the view the user wants to see, a different ngRepeat is used to generate the table. When the user switches their view, and one of the following is removed from the DOM and another added, the new ngRepeat does not reference to the same pagination.filteredData array.
Example: Main is my controller, using controller as syntax.
<tr ng-if="Main.tableConfig.programGranularity == 'overall'" ng-repeat="item in Main.pagination.filteredData = ( Main.data.overallData | filterByDateRange | filter: Main.tableConfig.generalSearch | orderBy: ['Date', 'Name']) | startFrom: Main.pagination.startAtIndex | limitTo: Main.pagination.pageSize">
<td ng-repeat="column in Main.tableConfig.columnsConfig | selectColumnsByGranularity: Main.tableConfig.programGranularity">
<span ng-if="!column.isDate" ng-bind="item[column.dataValue] | ifEmpty: 0"></span>
<span ng-if="column.isDate" ng-bind="item[column.dataValue] | date:'MM/dd/yyyy': 'UTC' | ifEmpty: 0"></span>
</td>
</tr>
<tr ng-if="Main.tableConfig.programGranularity == 'team'" ng-repeat="item in Main.pagination.filteredData = ( Main.data.teamData | filterByDateRange | filter: Main.tableConfig.generalSearch | orderBy: ['Date', 'Name']) | startFrom: Main.pagination.startAtIndex | limitTo: Main.pagination.pageSize">
<td ng-repeat="column in Main.tableConfig.columnsConfig | selectColumnsByGranularity: Main.tableConfig.programGranularity">
<span ng-if="!column.isDate" ng-bind="item[column.dataValue] | ifEmpty: 0"></span>
<span ng-if="column.isDate" ng-bind="item[column.dataValue] | date:'MM/dd/yyyy': 'UTC' | ifEmpty: 0"></span>
</td>
</tr>
<tr ng-if="Main.tableConfig.programGranularity == 'colleague'" ng-repeat="item in Main.pagination.filteredData = ( Main.data.parsedData | filterByDateRange | filter: Main.tableConfig.generalSearch | orderBy: ['Date', 'Name']) | startFrom: Main.pagination.startAtIndex | limitTo: Main.pagination.pageSize">
<td ng-repeat="column in Main.tableConfig.columnsConfig | selectColumnsByGranularity: Main.tableConfig.programGranularity">
<span ng-if="!column.isDate" ng-bind="item[column.dataValue] | ifEmpty: 0"></span>
<span ng-if="column.isDate" ng-bind="item[column.dataValue] | date:'MM/dd/yyyy': 'UTC' | ifEmpty: 0"></span>
</td>
</tr>
I want the same pagination.filteredData array to be set by each of the ngRepeat directives. However, only the first ngRepeat that runs sets the value and no other ngRepeat will set it again.
I've tried ngInit and initializing an object with pagination inside of it, and referencing that in my ngRepeat. I have also tried using $parent.pagination.filteredData.
Using AngularJS v1.5.0
How do I get this to work?
Similar to https://stackoverflow.com/questions/38235907/angularjs-service-variable-not-being-set-inside-of-ngrepeat but reworded and fundamentally different. Solving the same problem though.
Edit: Refactored to utilize the controller as syntax, the problem still persists. To me it seems that when I switch to a different ngRepeat, a new array and reference is created, instead of overwriting the current arrays values.
Okay, I have spent some time putting together a demo replicating (as best I could) the code that you have provided <-- Broken, and I think I understand your issue. You say "the first ng-repeat that runs sets the value", and I think it's actually the LAST ng-repeat that runs that is setting it. It's not having a problem setting the value, the problem is that all 3 ng-repeats run every time, so it's always the last one that wins.
The reason this happens is because ng-repeat executes BEFORE ng-if for the common case of <element ng-if="item.showMe" ng-repeat="item in Main.items"></element>
That being said, even though your ng-if condition is false, so the <tr> does not get displayed, the ng-repeat has already run, and already set Main.pagination.filteredData
I think your best course of action would be to move your ng-if up one level to the <tbody>. It would look like the following:
WORKING DEMO <-- Working
<table>
<thead>
<tr>
<th>Name</th>
<th>Data</th>
<th>Date</th>
</tr>
</thead>
<tbody ng-if="Main.tableConfig.programGranularity == 'overall'" >
<tr ng-repeat="item in Main.pagination.filteredData = (Main.data.overallData | filterByDateRange | orderBy: ['date', 'name']) | startFrom: Main.pagination.startAtIndex | limitTo: Main.pagination.pageSize">
<td ng-bind="item.name"></td>
<td ng-bind="item.overall"></td>
<td ng-bind="item.date"></td>
</tr>
</tbody>
<tbody ng-if="Main.tableConfig.programGranularity == 'team'" >
<tr ng-repeat="item in Main.pagination.filteredData = (Main.data.teamData | filterByDateRange | orderBy: ['date', 'name']) | startFrom: Main.pagination.startAtIndex | limitTo: Main.pagination.pageSize">
<td ng-bind="item.name"></td>
<td ng-bind="item.team"></td>
<td ng-bind="item.date"></td>
</tr>
</tbody>
</table>

GET http://localhost/Grafica/%7Bd.icon%7D/ 404 (Not Found)

I'm doing a tooltip in a meteogram , and I want to show the image of the state of the sky . This is my code html
<div id="tooltip">
<table class="table table-condensed">
<tr><th>Hora (local)</th><th data-text="d.datetime | date">{d.datetime}</th></tr>
<tr class="avg"><td>Temperatura </td><td data-text="d.temp | temp">{d.temp}</td></tr>
<tr class="rain"><td>Precipitación </td><td data-text="d.rain | rain">{d.rain} </td></tr>
<tr class="wind"><td>Velocidad del viento </td><td data-text="d.wind_speed | wind">{d.wind_speed}</td></tr>
<tr class="wind"><td>Dirección del viento </td><td data-text="d.wind_direcion | degree">{d.wind_direction}</td></tr>
<tr class="pressure"><td>Presión</td><td data-text="d.pressure | pressure">{d.pressure} </td></tr>
<tr class="hum"><td>Humedad</td>><td data-text="d.humidity | percent">{d.humidity} </td></tr>
<tr class="cloud"><td>Nubes</td><td data-text="d.cloud | percent">{d.cloud} %</td></tr>
<tr class="snow"><td>Nieve</td><td data-text="d.snow | snow">{d.snow} mm</td></tr>
<tr class="sky"><td>Estado Cielo</td><td><img src={d.icon}/></td></tr>
</table>
</div>
and this is the part where I link scrip data
var ttobj = {d:{}};
rivets.bind($('#tooltip'), ttobj);
if(config.graphic.tooltip){
d3.select('#tooltip')
.attr('style', 'display: block; top:'+(ty+10)+'px;left:'+(tx+10)+'px');
// update the rivets tt obj
for(key in d) {
var value =0.0;
if(key == 'icon'){
value = "images/icons/"+d[key]+".png";
I have this error GET http://localhost/Grafica/%7Bd.icon%7D/ 404 (Not Found)
and do not know how to put it in the html to leave me the picture
Change this:
<tr class="sky"><td>Estado Cielo</td><td><img src={d.icon}/></td></tr>
to this:
<tr class="sky"><td>Estado Cielo</td><td><img src="{d.icon}"/></td></tr>
You missed out the quotes for the src attribute.

How to display a multi dimensional array as a table?

This problem's been haunting me for days... I have the following JSON that I'm trying to render as a table using Tempo.js but keep getting nothing rendered:
[
{
"id":"xxxxxxxxxxxxxxxxxxxxxxxxxx",
"name":"Family One",
"parents":[
{
"id":"yyyyyyyyyyyyyyyyyyyyyyyyyy",
"name":"John Doe",
"children":[
{
"id":"zzzzzzzzzzzzzzzzzzzzzzzzz",
"name":"Fabrice A",
"description":"Good kid",
"Age":"20",
"Weight":"60"
}
]
},
{
"id":"hhhhhhhhhhhhhhhhhhhhhhhhhh",
"name":"Jane Doe",
"children":[
{
"id":"wwwwwwwwwwwwwwwwwwwwwwww",
"name":"Maurice A",
"description":"Bad kid",
"Age":"22",
"Weight":"50"
}
]
}
]
},
{
"id":"xxxxxxxxxxxxxxxxxxxxxxxxxx2",
"name":"Family Two",
"parents":[
{
"id":"yyyyyyyyyyyyyyyyyyyyyyyyyy2",
"name":"Sonny Doe",
"children":[
{
"id":"zzzzzzzzzzzzzzzzzzzzzzzzz2",
"name":"Juan B",
"description":"Good kid",
"Age":"30",
"Weight":"70"
},
{
"id":"zzzzzzzzzzzzzzzzzzzzzzzzz3",
"name":"Alberto B",
"description":"Fine kid",
"Age":"20",
"Weight":"60"
},
{
"id":"zzzzzzzzzzzzzzzzzzzzzzzzz4",
"name":"Roberto B",
"description":"Medium kid",
"Age":"10",
"Weight":"50"
}
]
}
]
}
]
The table is supposed to look like this:
_______________________________________________________________________________________
| FAMILY NAME | PARENTS | CHILD NAME | CHILD DESCRIPTION | CHILD AGE | CHILD WEIGHT |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
| Family One | John Doe | Fabrice A | Good kid | 20 | 60 |
| |''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
| | Jane Doe | Maurice A | Bad kid | 22 | 50 |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
| Family Two | Sonny Doe | Juan B | Good kid | 30 | 70 |
| | | Alberto B | Fine kid | 20 | 60 |
| | | Roberto B | Medium kid | 10 | 50 |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Please notice how the family cell stretches to house more than one parent rows, and the parent cell streches to house more than one children rows.
I prepare the JSON in js in a variable called familyTree, and then call Tempo.prepare('family-list').render(familyTree);
No I've read all of the documentation for tempo.js (which wasn't too long), but I still haven't found a way of rendering the table properly. Here's what I got so far:
<div id="family-list">
<table id="families">
<tr data-before-template='data-before-template'>
<th>
FAMILY NAME
</th>
<th>
PARENTS
</th>
<th>
CHILD NAME
</th>
<th>
CHILD DESCRIPTION
</th>
<th>
CHILD AGE
</th>
<th>
CHILD WEIGHT
</th>
</tr>
<tr data-template='data-template'>
<td id="family-column">
{{name}}
</td>
<td id="parent-column" data-template-for='parents'>
{{name}}
</td>
<td colspan="4">
<table id='children-table' data-template-for="children">
<tr>
<td>
{{name}}
</td>
<td>
{{description}}
</td>
<td>
{{age}}
</td>
<td>
{{weight}}
</td>
</tr>
</table>
</td>
</tr>
I've used tempo before. I've even mixed it with wkhtmltopdf to render some nice-looking pdf files. But I just cannot solve this. If any of you out there has been through anything similar..would you please share your experience? Thanks so much in advance.
Using tempo.js is not ideal to render hierarchical data in a table. To render hierarchical data, tempo.js requires that the HTML elements also exists in a hierarchy. This is not ideal when dealing with tables, because creatign a table inside a table cell will eventually lead to column alignment issues. You can take care of alignment issues to a certain degree by fixing the width of each column, but this will not be a perfect solution.
Having said above, I've fixed your HTML markup to render your JSON data using tempo.js. See the changes below (jsfiddle here):
<div id="family-list">
<table id="families">
<tr data-before-template='data-before-template'>
<th width="100px">
FAMILY NAME
</th>
<th width="100px">
PARENTS
</th>
<th width="100px">
CHILD NAME
</th>
<th width="150px">
CHILD DESCRIPTION
</th>
<th width="50px">
CHILD AGE
</th>
<th width="50px">
CHILD WEIGHT
</th>
</tr>
<tr data-template='data-template'>
<td id="family-column">
{{name}}
</td>
<td colspan="5">
<table cellpadding="0">
<tr data-template-for='parents'>
<td width="100px">
{{name}}
</td>
<td>
<table id='children-table' cellpadding="0">
<tr data-template-for="children">
<td width="100px">
{{name}}
</td>
<td width="150px">
{{description}}
</td>
<td width="50px">
{{Age}}
</td>
<td width="50px">
{{Weight}}
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>

Categories