rowspan for 3 columns using angularJS - javascript

I have a category list that contains name and subject list.
The subject list contains name and course list.
The course list contain name.
I want to display this data in table that will rowspan category or subject if they are the same. For example:
Category Subject Course
cat1 sub1 ''
sub2 cour1
cour2
sub3 ''
cat3 ''
Currently I have it working for two columns using this:
<table class="curvetable5" style="width:99%">
<thead>
<tr>
<th width="30%">Category</th>
<th width="30%">Subject</th>
</tr>
</thead>
<tbody ng-repeat="category in organization">
<td rowspan="{{category.subjectList.length+1}}">{{category.categoryName}}</td>
<tr ng-repeat="subject in category.subjectList">
<td>{{ subject.name }}</td>
</tr>
</tbody>
</table>
However, I am having trouble doing it for 3 columns. This is the code I have that is not working. The course name are not being displayed and subject name become listed in column order instead of row order. Any suggestion:
<table class="curvetable5" style="width:99%">
<thead>
<tr>
<th width="30%">Category</th>
<th width="30%">Subject</th>
<th width="40%">Course</th>
</tr>
</thead>
<tbody ng-repeat="category in organization">
<td rowspan="{{category.subjectList.length+1}}">{{category.categoryName}}</td>
<tr ng-repeat="subject in category.subjectList">
<td rowspan="{{subject.courseList.length+1}}">{{ subject.name }}</td>
<tr ng-repeat="course in subject.courseList">
<td>{{ course.name }}</td>
</tr>
</tr>
</tbody>
</table>
Sample Data:
[
{"id":95,"categoryName":"A new catagory",
"subjectList":[{"id":112,"subjectname":"2ndnewcat","curcount":0,
"courseList":"[{\"name\":\"-\",\"curcount\":0}]"},
{"id":76,"subjectname":"ZZZZZZZZZZZZZZZZZZ_class","curcount":0,
"courseList":[{"coursename":"thiswillbenew111111111112","curcount":1}]}]},
{"id":93,"categoryName":"David Test",
"subjectList":[{"id":75,"subjectname":"This is a test","curcount":1,
"courseList":[{"coursename":"newewst1","curcount":0}]}]},
{"id":116,"categoryName":"New Category",
"subjectList":[{"id":79,"subjectname":"New Subject","curcount":2,
"courseList":[{"coursename":"ISO training part 2","curcount":0}]}]},
{"id":0,"categoryName":"cat1",
"subjectList":[{"id":15,"subjectname":"test","curcount":4,
"courseList":"[{\"name\":\"-\",\"curcount\":0}]"}]},
{"id":11,"categoryName":"cat2",
"subjectList":[{"id":68,"subjectname":"asdasd","curcount":5,
"courseList":[{"coursename":"david1","curcount":0},{"coursename":"thisisatest","curcount":0}]}]},
{"id":12,"categoryName":"cate3",
"subjectList":[{"id":12,"subjectname":"newest1","curcount":6,
"courseList":[{"coursename":"cous1","curcount":0}]}]},
{"id":163,"categoryName":"emptylist",
"subjectList":"[{\"name\":\"-\",\"curcount\":0}]"}
]
This is current code I am testing. It will will rowspan the category, display each subject once and then display all the courses for each subject in list in a single cell. I would prefer to rowspan subject too, but this is what I got working so far.
<table class="curvetable5" style="width:99%">
<thead>
<tr>
<th width="30%">Category</th>
<th width="30%">Subject</th>
<th width="40%">Course</th>
</tr>
</thead>
<tbody ng-repeat="category in organization">
<td rowspan="{{category.subjectList.length+1}}">{{category.categoryName}}</td>
<tr ng-repeat="subject in category.subjectList">
<td>{{ subject.subjectname }}</td>
<td> <li ng-repeat="course in subject.courseList" >{{ course.coursename }} </li></td>
</tr>
<td ng-if="category.subjectList.length==27"> </td>
<td ng-if="category.subjectList.length==27"> </td>
</tbody>
</table>
Thanks,
AB

The two column case should be:
<tbody ng-repeat="dept in org.deptList">
<tr ng-repeat="subj in dept.subjList">
<td rowspan="dept.subjList.length+1">
{{dept.name}}
</td>
<td>
{{subj.name}}
</td>
</tr>
</tbody>
For the three column case, nest a <table> in the <td> element:
<tbody ng-repeat="dept in org.deptList">
<tr ng-repeat="subj in dept.subjList">
<td rowspan="dept.subjList.length+1">
{{dept.name}}
</td>
<td>
<table>
<tr ng-repeat="class in subj.classList">
<td rowspan="subj.classList.length+1">
{{subj.name}}
</td>
<td>
{{class.name}}
</td>
</tr>
</table>
</td>
</tr>
</tbody>

Related

How can I hide <tr> if it's <td> is empty

I have a table that gets data outputted to it dynamically based on data that is being pulled from my database. I have three hard coded <tr> but I want to hide them if there isn't any data outputted to their <td> from the database.
This is my HTML
<table class="table text-light text-end" id="data_table">
<thead>
<tr>
<th></th>
{{#each response4}}
<th class='title' scope="col">{{commodity}}</th>
{{/each}}
<th scope="col">Total</th>
</tr>
</thead>
<tbody class="text-end">
<tr>
<th scope="row">AUX</th>
{{#each response6}}
<td class="whole">{{fb_plus_fr}}</td>
{{/each}}
</tr>
<tr>
<th scope="row">UEM</th>
{{#each response4}}
<td class="whole">{{fb_plus_fr}}</td>
{{/each}}
</tr>
<tr>
<th scope="row">UT</th>
{{#each response5}}
<td class="whole">{{fb_plus_fr}}</td>
{{/each}}
</tr>
</tbody>
</table>
This is an example I pulled from the inspect tool when the page loads and gets data from the database. The first <tr> doesn't have any <td> and should be hidden.
<tbody class="text-end">
<tr>
<th scope="row">AUX</th>
</tr>
<tr>
<th scope="row">UEM</th>
<td class="whole">8215</td>
<td class="whole">5367</td>
<td class="whole">31193</td>
</tr>
<tr>
<th scope="row">UT</th>
<td class="whole">8215</td>
<td class="whole">5367</td>
<td class="whole">31193</td>
</tr>
</tbody>
This is how I'm attempting it but this doesn't work. It won't hide that first that doesn't have any data. Any advice on how to fix this is greatly appreciated!
window.onload = () => {
$("#data_table > tbody > tr ").each(function () {
if ($(this).find('td').is(":empty")){
$(this.hide())
}
})
};
This code may help you:
<tr th:if="${yourtable.empty}">
<td colspan="2">No Content Available</td>
</tr>
I think the easiest way to go about this would be to have an if block wrapped around the <tr> that checks if the data is empty before displaying the <tr>.

How to push/pass table data from one component to another in angular 9?

I want to push/pass data of table (itemName, Quantity, retailRate and totalQuantity , totalPrice ) to another component(getDataComponent) when I click button (pushData()) also navigate to receive.
I am not able to send table data in controller. Is this approach is good to send data from one component to another with navigation...
HTML: * send.html*
<table class="table table-hover table-sm"
*ngIf="secondTableData.length">
<thead>
<tr class="table-primary">
<td># </td>
<td>Item</td>
<td>Quantity</td>
<td>Price</td>
<td class="pull-right">Action</td>
</tr>
</thead>
<tbody>
<tr *ngFor="let newdata of secondTableData let i=index;">
<td>{{i+1}}</td>
<td>{{ newdata.itemName }}</td> <!--this data to push in receiveComponent -->
<td class="text-center">{{ newdata.Quantity }}</td> <!--this data to push in receiveComponent -->
<td>{{ newdata.retailRate }}</td> <!--this data to push in receiveComponent -->
</tr>
</tbody>
<thead>
<tr class="table-secondary">
<td>#: {{ secondTableData.length }}</td>
<td></td>
<td class="text-center">TQ: {{ totalQuantity }}</td> <!--this data to push in receiveComponent -->
<td>TP: {{ totalPrice }}</td> <!--this data to push in receiveComponent -->
<td></td>
</tr>
</thead>
</table>
<div>
<hr>
<button class="btn btn-primary pull-right" (click)="pushData()">
<i class="fa fa-check" aria-hidden="true"></i> OK
</button>
</div>
</div>```
**Component.ts:** *sendComponent.ts*
```tabeTata:any
pushData(){
let data:any = this.tabeTata.values;
this.routerService.navigate(['./receive'],{
queryParams:{data:JSON.stringify(data)}
})
}```
**receive.Html** *here i am using random data for demo. I want to place received data to respective places*
```<table class="table table-bordered table-sm">
<thead>
<tr>
<th>SN</th>
<th>Product</th>
<th>Unit</th>
<th>Price</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Custom oil </td>
<td>10</td>
<td>34</td>
<td>340</td>
</tr>
<tr>
<td>2</td>
<td>Digital illustraion </td>
<td>12</td>
<td>50</td>
<td>600</td>
</tr>
<tr class="small" style="height: 10px;">
<td colspan="3" style="border: none;"></td>
<td>Gross Amount:</td>
<td>1100</td>
</tr>
<tr class="small">
<td colspan="3" style="border: none;"></td>
<td>Discount:</td>
<td>100</td>
</tr>
<tr class="small">
<td colspan="3" style="border: none;"></td>
<td>VAT</td>
<td>30</td>
</tr>
<tr class="small">
<td colspan="3" style="border: none;"></td>
<td>Net Amont</td>
<td>1030</td>
</tr>
</tbody>
</table>
```
**receivecomponent.ts**
```data:any;
ngOnInit(): void {
// To get data from biling component
this.route.queryParams.subscribe((params)=>{
this.data = JSON.parse(params.data);
console.log(params);
})
}```
**Any one is there to help, May be this one is complex**
try using sharedService between components.
here is an example of 'Component Intercommunication' through services:
https://stackblitz.com/edit/angular-communication-3?file=app%2Fside-bar%2Fside-bar.service.ts
For more information resd this article '3 ways to communicate between Angular components'

Copy data from selected rows of one table to another table using jQuery

I got 2 tables one of them has my products data such name,and bar-code.
The other one is empty and I want to copy products' table (selected rows only) into the second table via jQuery.
<table id="exampleTable1" style="max-width:50%;">
<thead>
<tr>
<th>bar-code</th>
<th>product name</th>
</tr>
</thead>
<tbody>
<tr role="row" class="odd selected">
<td class="sorting_1">545333456</td>
<td>Galaxy S9</td>
</tr>
<tr role="row" class="even selected">
<td class="sorting_1">876543</td>
<td>Galaxy S6</td>
</tr>
<tr role="row" class="odd">
<td class="sorting_1">407654</td>
<td>SD 64G </td>
</tr>
<tr role="row" class="even selected">
<td class="sorting_1">876543</td>
<td>Galaxy S5</td>
<tr role="row" class="odd">
<td class="sorting_1">407654</td>
<td>Iphone 7 </td>
</tr>
</tbody>
</table>
My second table :
<table id="exampleTable2" style="max-width:50%;">
<thead>
<tr>
<th>bar-code</th>
<th>product name</th>
</tr>
</thead>
<tbody>
<tr>
</tr>
<tr>
</tr>
</tbody>
</table>
<button class="btn btn-success" data-panelId="copy1" id="copy1">
Copy from exampleTable1 To exampleTable1
</button>
There are a few jQuery methods that make this easy to do, namely the .clone() and .each() method. You could achieve what you want by the following:
$('#copy1').click(function() {
$('tr.selected', '#exampleTable1').each(function() {
// For each "selected" row of table1 ..
var rowFromTable1 = $(this);
// .. Take a clone/copy of it ..
var clonedRowFromTable1 = rowFromTable1.clone();
// .. And append the cloned row to the tbody of table2
$('tbody', '#exampleTable2').append( clonedRowFromTable1 )
})
})

Table inside table using ng-show in AngularJS

I have a table in which after clicking on a row I want to show new child table just after the row I clicked. I am calling new api on row click so I have to show it in new table just after the row clicked. see the snapshot
After clicking on first row the new table is showing like 1, ABC_1, DEF
Here is code for template
<table md-table class="md-primary md-data-table">
<thead md-head md-order="vm.query.order">
<tr md-row>
<th md-column><span>S. No.</span></th>
<th md-column><span>Project Name</span></th>
<th md-column><span>Deadline</span></th>
</tr>
</thead>
<tbody md-body>
<tr md-row ng-click="vm.ShowDetailed($index)" ng-repeat="project in vm.projects | limitTo : vm.query.limit : (vm.query.page-1)*vm.query.limit">
<td md-cell>{{($index+1)+(vm.query.page-1)*vm.query.limit}}</td>
<td md-cell>{{project.fields.project_name}}</td>
<td md-cell>{{project.fields.end_date}}</td>
<table md-table ng-show="vm.detailedShow[$index]">
<thead md-head>
<tr md-row>
<th md-column><span>Project Name</span></th>
<th md-column><span>District</span></th>
<th md-column><span>City</span></th>
</tr>
</thead>
<tbody md-body>
<tr md-row ng-repeat="site in sites">
<td md-cell>{{site.projectName}}</td>
<td md-cell>{{site.district}}</td>
<td md-cell>{{site.city}}</td>
</tr>
</tbody md-body>
</table>
</tr>
</tbody>
</table>
Here is the functions for show/hide
vm.detailedShow = [];
vm.ShowDetailed = function(index){
vm.detailedShow[index] = !vm.detailedShow[index];
}
The value of vm.detailedShow[$index] is getting true/false on click still I am not able to show the table.
The first thing is you can't insert <table> just like a <tr> or <td>. But you can insert the table inside a <td> tag.
Try the below one.
<table md-table class="md-primary md-data-table">
<thead md-head md-order="vm.query.order">
<tr md-row>
<th md-column><span>S. No.</span></th>
<th md-column><span>Project Name</span></th>
<th md-column><span>Deadline</span></th>
</tr>
</thead>
<tbody md-body>
<tr md-row ng-click="vm.ShowDetailed($index)" ng-repeat-start="project in vm.projects | limitTo : vm.query.limit : (vm.query.page-1)*vm.query.limit">
<td md-cell>{{($index+1)+(vm.query.page-1)*vm.query.limit}}</td>
<td md-cell>{{project.fields.project_name}}</td>
<td md-cell>{{project.fields.end_date}}</td>
</tr>
<tr ng-show="vm.detailedShow[$index]" ng-repeat-end>
<td> </td>
<td colspan="2">
<table md-table ng-show="vm.detailedShow[$index]">
<thead md-head>
<tr md-row>
<th md-column><span>Project Name</span></th>
<th md-column><span>District</span></th>
<th md-column><span>City</span></th>
</tr>
</thead>
<tbody md-body>
<tr md-row ng-repeat="site in sites">
<td md-cell>{{site.projectName}}</td>
<td md-cell>{{site.district}}</td>
<td md-cell>{{site.city}}</td>
</tr>
</tbody md-body>
</table>
</td>
</tr>
</tbody>
</table>

Table: Show only the first row of table tbody. How to hide the succeeding 1st rows?

The very 1st row of EVERY tbody is the row header (contains the column Names). The rest of EVERY tbody succeeding 1st rows are not necessary and wanted to hide them.
Classes used:
toprowHeader = 1st row that holds every column names
recordsRow = holds the other record details
For now it shows like this:
--------------------------------------------
| MessageID | Sender | Message |
--------------------------------------------
| 1 | admin |my admin message |
--------------------------------------------
| MessageID | Sender | Message |
--------------------------------------------
| 2 | sender1 |reply to admin |
Here is the sample structure I wanted to achieve:
--------------------------------------------
| MessageID | Sender | Message |
--------------------------------------------
| 1 | admin |my admin message |
| 2 | sender1 |reply to admin |
Though I have some options to make it easier but the requirement says that every record should be inside a tbody
Here is my Sample Table structure:
<table class="gridtable">
<tbody>
<tr class="toprowHeader" >
<td class="">...</td>
</tr>
<tr class="recordsRow " >
<td class="">...</td>
</tr>
<tr class="recordsRow " >
<td class="">...</td>
</tr>
</tbody>
<tbody>
<tr class="toprowHeader">
<td class="">...</td>
</tr>
<tr class="recordsRow ">
<td class="">...</td>
</tr>
<tr class="recordsRow ">
<td class="">...</td>
</tr>
</tbody>
</table>
Added requirement:
A lot of you questioned the table structure above but the main reason why I placed it inside individual tbody its because I also have a button to be able to move the 1st tbody to the bottom/last of the table.
I use PHP to display records
see output below ,Use this
It Will hide all the toprowHeaders except the first one as per your requirement
$('tr.toprowHeader:gt(0)').hide();
$('table').append($('tbody:eq(0)'));
console.log($('tbody:eq(0)'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="gridtable">
<tbody>
<tr class="toprowHeader" >
<td class="">title 1</td>
</tr>
<tr class="recordsRow " >
<td class="">record1</td>
</tr>
<tr class="recordsRow " >
<td class="">record1</td>
</tr>
</tbody>
<tbody>
<tr class="toprowHeader">
<td class="">title2</td>
</tr>
<tr class="recordsRow ">
<td class="">record2</td>
</tr>
<tr class="recordsRow ">
<td class="">record2</td>
</tr>
</tbody>
<tbody>
<tr class="toprowHeader">
<td class="">title3</td>
</tr>
<tr class="recordsRow ">
<td class="">record3</td>
</tr>
<tr class="recordsRow ">
<td class="">record3</td>
</tr>
</tbody>
<tbody>
<tr class="toprowHeader">
<td class="">title4</td>
</tr>
<tr class="recordsRow ">
<td class="">record4</td>
</tr>
<tr class="recordsRow ">
<td class="">record4</td>
</tr>
</tbody>
<tbody>
<tr class="toprowHeader">
<td class="">title5</td>
</tr>
<tr class="recordsRow ">
<td class="">record5</td>
</tr>
<tr class="recordsRow ">
<td class="">record5</td>
</tr>
</tbody>
<tbody>
<tr class="toprowHeader">
<td class="">title6</td>
</tr>
<tr class="recordsRow ">
<td class="">record6</td>
</tr>
<tr class="recordsRow ">
<td class="">record6</td>
</tr>
</tbody>
<tbody>
<tr class="toprowHeader">
<td class="">title7</td>
</tr>
<tr class="recordsRow ">
<td class="">record7</td>
</tr>
<tr class="recordsRow ">
<td class="">record7</td>
</tr>
</tbody>
</table>
You can use CSS as shown below:
tbody:not(:first-child) .toprowHeader{
display: none;
}
<table class="gridtable">
<tbody>
<tr class="toprowHeader">
<td>Title</td>
</tr>
<tr class="recordsRow ">
<td>Record</td>
</tr>
<tr class="recordsRow ">
<td>Record</td>
</tr>
</tbody>
<tbody>
<tr class="toprowHeader">
<td>Title</td>
</tr>
<tr class="recordsRow ">
<td>Record</td>
</tr>
<tr class="recordsRow ">
<td>Record</td>
</tr>
</tbody>
</table>
By the way, You should really try modifying the script to omit the extra titles instead (whichever generates it), and have a single title row inside <thead>

Categories

Resources