How to display data in table for nested json array - html

This is my herolist json:
herolist = [{
sl: 1,
title: 'Batman',
gender: 'male',
firstname: 'Bruce',
lastname: 'Wayne',
city: 'Gotham',
ticketprice: 123.4567,
releasedate: '1/26/2018',
poster: 'assets/images/batman.jpg',
movieslist: [
{
title: 'Batman Begins',
poster: 'assets/images/bat1_tn.jpg'
}, {
title: 'Dark Knight',
poster: 'assets/images/bat2_tn.jpg'
}, {
title: 'Dark Knight Raises',
poster: 'assets/images/bat3_tn.jpg'
}
]
}
I have a nested array as movieslist. I need to display all those tiles inside movie list in the table.
I followed the below approach to display remaining items
<h1>Heroes List Application</h1>
<ul>
<li *ngFor="let hero of herolist">{{hero.title}}</li>
</ul>
<div class="table-responsive">
<table class="table table-striped table table-bordered table table-hover">
<thead class="thead-dark">
<tr>
<th>Sl #</th>
<th>Title</th>
<th>Full Name</th>
<th>Poster</th>
<th>City</th>
<th>Ticket Price</th>
<th>Release Date</th>
<th>Movies List</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let hero of herolist">
<td>{{hero.sl}}</td>
<td>{{hero.title | titlecase }}</td>
<td>{{hero.firstname+' '+hero.lastname}}</td>
<td>
<img width="50" [src]="hero.poster" [alt]="hero.title">
</td>
<td>{{hero.city}}</td>
<td>{{hero.ticketprice | currency : 'INR': 'symbol': '3.2-3'}}</td>
<td>{{hero.releasedate | date }}</td>
**<td>
<span>{{ hero.movieslist.values()}}</span>
</td>**
</tr>
</tbody>
</table>
</div>
`
I need to display the movies list in the column. How should I use the ngFor as it is not the taking movieslist.

Use ngFor like this
<div *ngFor="let movie of hero.movieslist">{{ movie.title}}</div>
Full code
<h1>Heroes List Application</h1>
<ul>
<li *ngFor="let hero of herolist">{{hero.title}}</li>
</ul>
<div class="table-responsive">
<table class="table table-striped table table-bordered table table-hover">
<thead class="thead-dark">
<tr>
<th>Sl #</th>
<th>Title</th>
<th>Full Name</th>
<th>Poster</th>
<th>City</th>
<th>Ticket Price</th>
<th>Release Date</th>
<th>Movies List</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let hero of herolist">
<td>{{hero.sl}}</td>
<td>{{hero.title | titlecase }}</td>
<td>{{hero.firstname+' '+hero.lastname}}</td>
<td>
<img width="50" [src]="hero.poster" [alt]="hero.title">
</td>
<td>{{hero.city}}</td>
<td>{{hero.ticketprice | currency : 'INR': 'symbol': '3.2-3'}}</td>
<td>{{hero.releasedate | date }}</td>
**<td>
<div *ngFor="let movie of hero.movieslist">{{ movie.title}}
<img src={{movie.poster}}/>
</div>
</td>**
</tr>
</tbody>
</table>
</div>

Related

table-striped bootstrap class not working but other classes are working

I have created a table using bootstrap class in a angular project. Only table-striped and table-hover class is not working remaining classes like table-primary is working. and I have not written a single line of css code (no issue of overriding).I have tried other examples in stack but didn't work the issues were of tbody. i have tried including tbody tag but didn't work.
<div class="container box" style="margin-top: 10px;">
<table class="table table-striped table-fit table-bordered table-hover">
<thead>
<tr>
<th>Item</th>
<th>Amount</th>
<th>Category</th>
<th>Location</th>
<th>Spent On</th>
</tr>
<tr *ngFor="let entry of expenseEntries">
<th scope="row">{{ entry.item }}</th>
<th>{{ entry.amount }}</th>
<td>{{ entry.category }}</td>
<td>{{ entry.location }}</td>
<td>{{ entry.spendOn | date: 'short' }}</td>
</tr>
</thead>
</table>
</div>
You have to define <thead> and <tbody> tags inside the <table> tag.
table content inside the tbody will only be affected by .table-striped class as mentioned in the official document
at the beginning I wrapped and wrongly.
my mistake was that i put tag inside tag initially then i tried removing tag. but i now wrapped correctly outside
like this
<div class="container box" style="margin-top: 10px;">
<table class="table table-striped table-fit table-bordered table-hover">
<thead>
<tr>
<th>Item</th>
<th>Amount</th>
<th>Category</th>
<th>Location</th>
<th>Spent On</th>
</tr>
<tbody>
<tr *ngFor="let entry of expenseEntries">
<th scope="row">{{ entry.item }}</th>
<th>{{ entry.amount }}</th>
<td>{{ entry.category }}</td>
<td>{{ entry.location }}</td>
<td>{{ entry.spendOn | date:'fullDate' | uppercase }}</td>
</tr>
</tbody>
</thead>
</table>
</div>
but actually tag should be after closing tag like the below one code
<div class="container box" style="margin-top: 10px;">
<table class="table table-striped table-fit table-bordered table-hover">
<thead>
<tr>
<th>Item</th>
<th>Amount</th>
<th>Category</th>
<th>Location</th>
<th>Spent On</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let entry of expenseEntries">
<th scope="row">{{ entry.item }}</th>
<th>{{ entry.amount }}</th>
<td>{{ entry.category }}</td>
<td>{{ entry.location }}</td>
<td>{{ entry.spendOn | date:'fullDate' | uppercase }}</td>
</tr>
</tbody>
</table>
</div>

How do I hide my table element when the component is empty?

The html is printing all the API data in the table. Products and Components
The table should not print the product when the components are empty. What is the best way to do this?
I'm using angular 8
products = {
"id": 1,
"name": "John",
"components": [
{
"id": 130,
"name": "Price",
}
]
"isSelected": false }
products = {
"id": 2,
"name": "name",
"components": [] }
<div class="card">
<div class="card-body">
<table class="table table-striped table-bordered hover">
<thead>
<tr>
<th width="1%" class="text-center"></th>
<th width="8%" class="text-center">Id</th>
<th width="8%" class="text-center">Name</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let product of products; index as i">
<tr>
<td>
<div>
<button class="btn btn-sm btn-default"></button>
</div>
</td>
<td>{{product.id}}</td>
<td>{{product.name}}</td>
</tr>
<tr *ngFor="let prodComp of product.components">
<td></td>
<td>{{prodComp.id}}</td>
<td>{{prodComp.name}}</td>
</tr>
</ng-container>
</tbody>
</table>
</div>
</div>
You could add another container inside your *ngFor using *ngIf to test for that condition:
<ng-container *ngFor="let product of products; index as i">
<ng-container *ngIf="product.components.length > 0">
<tr>
<td>
<div>
<button class="btn btn-sm btn-default"></button>
</div>
</td>
<td>{{product.id}}</td>
<td>{{product.name}}</td>
</tr>
<tr *ngFor="let prodComp of product.components">
<td></td>
<td>{{prodComp.id}}</td>
<td>{{prodComp.name}}</td>
</tr>
</ng-container>
</ng-container>

Freeze three column in table (unscrollable)

I'm using angular 8. I need to fix first three column position of table to make it non-scroll able,
this is my recent code:
<mat-tab label="Rental details">
<div class="table-responsive" *ngIf="!rentLoader" >
<table class="table">
<thead class="text-info">
<tr>
<th>Voucher No.</th>
<th>Voucher Date</th>
<th>Amount</th>
<th>Mode Of deduction</th>
<th>Deduction Date</th>
<th>Deduction Amount</th>
<th>Remarks</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let rentals of rentalDetailsList | paginate: { itemsPerPage: 10, currentPage: rentalPage, id: 'rentalPagination'}">
<td>{{rentals.Voucher_No}}</td>
<td>{{rentals.Voucher_Date | date : 'short'}}</td>
<td>₹ {{rentals.Amount}}</td>
<td>{{rentals['Mode of deduction']}}</td>
<td>{{rentals['Deduction Date']}}</td>
<td>₹ {{rentals['Deduction Amount']}}</td>
<td>{{rentals.Remarks}}</td>
</tr>
</tbody>
</table>
</div>
<div class="text-center" *ngIf="rentalDetailsList.length == 0 && !rentLoader">
No data found.
</div>
</mat-tab>
I need to freeze Voucher No.,Voucher Date and Amount.
Thank you
I did it by using d-flex class bootstrap.
I divided them into two different div which is to be scrolled and different div for non scroll.
<div class="d-flex">
<div class="table-nowrap" *ngIf="!rentLoader">
<table class="table">
<thead class="text-info">
<tr>
<th>Voucher No.</th>
<th>Voucher Date</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr
*ngFor="let rentals of rentalDetailsList | paginate: { itemsPerPage: 10, currentPage: rentalPage, id: 'rentalPagination'}">
<td>{{rentals.Voucher_No}}</td>
<td>{{rentals.Voucher_Date | date : 'short'}}</td>
<td>₹ {{rentals.Amount}}</td>
</tr>
</tbody>
</table>
</div>
<div class="table-responsive" *ngIf="!rentLoader">
<table class="table">
<thead class="text-info">
<tr>
<th>Mode Of deduction</th>
<th>Deduction Date</th>
<th>Deduction Amount</th>
<th>Remarks</th>
</tr>
</thead>
<tbody>
<tr
*ngFor="let rentals of rentalDetailsList | paginate: { itemsPerPage: 10, currentPage: rentalPage, id: 'rentalPagination'}">
<td>{{rentals['Mode of deduction']}}</td>
<td>{{rentals['Deduction Date']}}</td>
<td>₹ {{rentals['Deduction Amount']}}</td>
<td>{{rentals.Remarks}}</td>
</tr>
</tbody>
</table>
</div>
</div>

Getting same index when trying to get selected row index

I'm using Angular and want to get index of rows inside the table when user clicks.When I try to get,it returns always 0.Because I have just one tr inside tbody but even I cange with $('table td') still getting same index.What should I change?
Table in HTML
<table id="example" class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Student Number</th>
<th>Department</th>
<th>Photo</th>
</tr>
</thead>
<tbody *ngFor="let studentsEl of items2">
<tr>
<td>{{studentsEl.name}}</td>
<td>{{studentsEl.age}}</td>
<td>{{studentsEl.stuNumber}}</td>
<td>{{studentsEl.department}}</td>
<td>
<img
[src]="studentsEl.imagePath"
alt="{{ studentsEl.name }}"
class="img-responsive"
style="max-height: 75px;">
</td>
</tr>
</tbody>
</table>
Typescript file of the component
constructor() {
$(document).ready( function() {
$('table tr').click( function() {
alert($(this).index());
});
});
Here you have a couple of issues:
use ngFor for table row
You shouldn't use dosument.ready in constructor, but create a method and click handler.
Here is HTML:
<table id="example" class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Student Number</th>
<th>Department</th>
<th>Photo</th>
</tr>
</thead>
<tbody >
<tr *ngFor="let studentsEl of items2; let idx = index">
<td>
<span (click)="getIndex(idx)">
{{studentsEl.name}} yourIndex: {{ idx }}
</span>
</td>
<td>{{studentsEl.age}}</td>
<td>{{studentsEl.stuNumber}}</td>
<td>{{studentsEl.department}}</td>
<td>
<img
[src]="studentsEl.imagePath"
alt="{{ studentsEl.name }}"
class="img-responsive"
style="max-height: 75px;">
</td>
</tr>
</tbody>
</table>
Your typescript file:
getIndex(idx){
console.log(idx);
}

Table row was not showing

I am using knockout Js. I want to show the table row with table header when I click another table row in the table. I used this code below. Can anyone help me out?
var ViewModel = function() {
var self = this;
this.client_details = [{
name: 'Jack',
email: 'jack#gmail.io',
phone: '256987',
address: 'US',
dob: '24/01/1975',
taxid: '125'
}, {
name: 'Hari',
email: 'hari#yahoo.com',
phone: '247896',
address: 'chennai',
dob: '02/01/1975',
taxid: '255'
}];
this.datas = [{
name: 'John',
email: 'john#gmail.com',
phone: '58963287'
}, {
name: 'JohnBert',
email: 'bert#gmail.com',
phone: '589625887'
}];
self.seletedRow = ko.observable();
self.goToFolder = function(folder) {
self.seletedRow(folder);
};
};
ko.applyBindings(new ViewModel(self.datas));
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<table width='100%'>
<thead>
<tr>
<th width='25%'>Client Name</th>
<th width='25%'>Email</th>
<th class='Phone' width='15%'>Phone</th>
<th class='Address' width='10%'>Address</th>
<th class='dob' width='15%'>DOB</th>
<th class='tax' width='15%'>Tax ID</th>
</tr>
</thead>
<tbody data-bind="foreach: client_details">
<tr class="table_row">
<td data-bind="text: name,click: $root.goToFolder"></td>
<td data-bind="text: email"></td>
<td data-bind="text: phone"></td>
<td data-bind="text: address"></td>
<td data-bind="text: dob"></td>
<td data-bind="text: taxid"></td>
</tr>
</tbody>
</table>
<table data-bind="with: seletedRow">
<thead>
<tr>
<th width='25%'>User Name</th>
<th width='25%'>Email</th>
<th class='Phone' width='15%'>Phone</th>
</tr>
</thead>
<tbody data-bind="foreach: datas">
<tr>
<td data-bind="text: name"></td>
<td data-bind="text: email"></td>
<td data-bind="text: phone"></td>
</tr>
</tbody>
</table>
Can anyone help me to get the table row data using knockout?
The with binding creates a new binding context. Your second <table> therefore looks for the name, email and phone properties inside the currently selected client.
If you just want to show/hide the second table based on if there's a selection, you can use the if binding.
If you want to perform any filters/logic on data based on the row that's selected, you can use a computed.
Note that I've also moved your click binding to the <tr>, so you can click anywhere in the row.
var ViewModel = function() {
var self = this;
this.client_details = [{
name: 'Jack',
email: 'jack#gmail.io',
phone: '256987',
address: 'US',
dob: '24/01/1975',
taxid: '125'
}, {
name: 'Hari',
email: 'hari#yahoo.com',
phone: '247896',
address: 'chennai',
dob: '02/01/1975',
taxid: '255'
}];
this.datas = [{
name: 'John',
email: 'john#gmail.com',
phone: '58963287'
}, {
name: 'JohnBert',
email: 'bert#gmail.com',
phone: '589625887'
}];
self.selectedRow = ko.observable();
self.goToFolder = function(folder) {
self.selectedRow(folder);
};
};
ko.applyBindings(new ViewModel(self.datas));
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<table width='100%'>
<thead>
<tr>
<th width='25%'>Client Name</th>
<th width='25%'>Email</th>
<th class='Phone' width='15%'>Phone</th>
<th class='Address' width='10%'>Address</th>
<th class='dob' width='15%'>DOB</th>
<th class='tax' width='15%'>Tax ID</th>
</tr>
</thead>
<tbody data-bind="foreach: client_details">
<tr class="table_row" data-bind="click: $root.goToFolder">
<td data-bind="text: name"></td>
<td data-bind="text: email"></td>
<td data-bind="text: phone"></td>
<td data-bind="text: address"></td>
<td data-bind="text: dob"></td>
<td data-bind="text: taxid"></td>
</tr>
</tbody>
</table>
<table data-bind="if: selectedRow">
<thead>
<tr>
<th width='25%'>User Name</th>
<th width='25%'>Email</th>
<th class='Phone' width='15%'>Phone</th>
</tr>
</thead>
<tbody data-bind="foreach: datas">
<tr>
<td data-bind="text: name"></td>
<td data-bind="text: email"></td>
<td data-bind="text: phone"></td>
</tr>
</tbody>
</table>