Basically I am creating a data grid that displays data from different tables in database.I am using ASP.NET MVC4 for this.
Following is how my part of my code looks:
<table class="myTable">
<tbody>
#foreach (var item in Model.sets)
{
<tr class="parent" data-level="0">
<td>
#item.setName
#* Here my logic would go*#
</td>
</tr>
}
So after displaying the rows of name of sets,in the next column I would want to display the elements that belong to that set.So I wrote another for loop in <td></td> that would loop through the Model.elements and check if it belongs to that set and display it.But I am getting "Element td cannot be nested within element td " validation error.
So how can I add data into rows of the next column?
Put your logic below the first end td tags instead. You can't put td tags inside other td tags; a series of sibling td tags make up a row.
If you want each separate piece of data in its own column:
#foreach (var item in Model.sets)
{
<tr class="parent" data-level="0">
<td>
#item.setName
</td>
#foreach (var element in Model.elements)
{
<td>
#*logic here*#
</td>
}
</tr>
If you want all your content inside the same cell, then you want:
#foreach (var item in Model.sets)
{
<tr class="parent" data-level="0">
<td>
#item.setName
</td>
<td>
#foreach (var element in Model.elements)
{
#*logic here*#
}
</td>
</tr>
}
Related
I am using primeNg row expansion feature.
Code is here : https://primefaces.org/primeng/showcase/#/table/rowexpansion
I have a requirement to display yellow background for odd rows and grey background for even rows, but the additional inserted row having the child table should not be included during calculation.
Consider the below html example, where user has expanded the first row. I do not want the rows with 'table-row-expand' class to be considered in the even/odd rule. Here I want first row to have yellow color, second row to have grey color and third row to have yellow again. The expanded row should not have any background.
Note that the .table-row-expand row gets added to the DOM only when user expands the corresponding row. Kindly help me with this problem.
.table-row:nth-child(odd) {
background-color: yellow;
}
.table-row:nth-child(even) {
background-color: grey;
}
<table>
<tr class='header-row'>
<th> </th>
</tr>
<tr class='table-row'>
<td> // first row (should be gray)</td>
</tr>
<tr class='table-row-expand'>
<td> // expanded row (should not be colored)
<div>
<p-table> // child table </p-table>
</div>
</td>
</tr>
<tr class='table-row'>
<td> // second row (should be yellow)</td>
</tr>
<tr class='table-row'>
<td> // third row (should be gray)</td>
</tr>
</table>
Save yourself a headache and drop in a wee bit 'o JavaScript. You may need to put this code in a function to be called when new rows are added.
.table-row.odd {
background-color: yellow;
}
.table-row.even {
background-color: grey;
}
<table>
<tr class='header-row'>
<th> </th>
</tr>
<tr class='table-row'>
<td> // first row (should be gray)</td>
</tr>
<tr class='table-row-expand'>
<td> // expanded row (should not be colored)
<div>
<p-table> // child table </p-table>
</div>
</td>
</tr>
<tr class='table-row'>
<td> // second row (should be yellow)</td>
</tr>
<tr class='table-row'>
<td> // third row (should be gray)</td>
</tr>
</table>
<script>
const styledRows = document.querySelectorAll('.table-row');
const isOdd = n => Boolean(n % 2); // returns true if n / 2 has a remainder
styledRows.forEach((row, i) => {
row.classList.add(isOdd(i) ? 'odd' : 'even');
});
</script>
I have the following incomplete code :
if (tr.attr('data-depth') == 0 && **tr.children()** {
}
The double star marked above is incomplete.
In the above code, what i want to achieve is check for a parent row( that i am doing by checking tr.attr('data-depth')==0) and then check if that parent row has any child rows and if no child rows are present for that parent row ,then remove a custom class which i am doing between the curly braces.
How to achieve the same?
Any code sample would be very helpful.
You can check the parent row has any row as child with find('tr') and check anything has been found with .length
This code is an example. You can modify it according to your needs.
$('tr[data-depth = 0]').each(function(){
if( $(this).find('tr').length > 0)
$(this).css('background-color','red')
})
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr data-depth = 0>
<td>
<table>
<tr>
<td>
1
</td>
</tr>
<tr>
<td>
2
</td>
</tr>
</table>
</td>
</tr>
<tr data-depth = 0 >
<td>
3
</td>
</tr>
<tr>
<td>
4
</td>
</tr>
</table>
For easier expression you must select your exact tr element
let my_row = // Your target row
if( $(my_row).data('depth') == 0 && $(my_row).find('tr').length > 0)
{
// Do something
}
I have a table where tr is repeated using *ngFor a collection, the collection which have a child members which should be binded as related table.
Note This is similar to nested array but only difference the html is not inside the nested array. I have referenced ngFor deep nested array already
typescript class
export class CreateBooking{
id: number;
bookings: BookingItem[]; // This should repeat as parent rows,
}
export class BookingItem {
id: number;
bookingNumber: number;
relatedVehicles: BookingItem[]; //This should be repeated as child rows
}
Html
<table>
<tr *ngFor="let booking of createBooking.bookings;let bookingIndex = index;">
<td>
<input type="text"
[ngModel]="booking.serialType" name="serialType--{{bookingIndex}}" />
</td>
</tr>
<tr> *ngFor="let v of booking[parent].relatedVehicles;
let i = index;
let parent = booking[something];"
<td>
<input [(ngModel)]="v.bookingNumber"
(ngModelChange)="serialNumberChangedIndex(parentIndex,$event,i)"
name="bookingNumber--{{i}}"/>
</td>
</tr>
</table>
Question 1 - How would i get the index of parent row on the child row
Question 2 - As a alternative i tried a inside which contains another table which have child items, But even with td colspan="allcolumns" i couldn't achieve expected output.
Challenges
- if i design the like this
<tr *ngFor="let booking of createBooking.bookings;let bookingIndex = index;">
<td>
<input type="text"
[ngModel]="booking.serialType" name="serialType--{{bookingIndex}}" />
</td>
<td>
<table>
<tbody>
<tr> *ngFor="let v of booking.RelatedVehicles;let i = index;"
<td>
<input [(ngModel)]="v.bookingNumber"
(ngModelChange)="serialNumberChangedIndex(bookingIndex ,$event,i)"
name="bookingNumber--{{i}}"/>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
This way i could generate the Nested array but the child collection will start at the 2nd column, I need the child element as full row.
Working sample code stackblitz
Please help me with some
expected output
From your code above, I do not see any relation in the second tag to the first one, where as your data structure I see the need for a nested tag. I think you should use a tag for the outer loop and a tag for the inner loop.
I need the html table for the following table structure.
This is something similar I have tried till now: (this is a .cshtml view, which takes a model as input)
<table>
<tbody>
<tr>
<th>Code Number of Equipment</th>
<th>Name of Equipment</th>
<th>Brand</th>
<th>Model</th>
<th>Quantity</th>
<th>Check Item</th>
<th>Note</th>
<th>Quoted Price</th>
</tr>
#foreach (var equipment in Model.Equipments)
{
<tr>
<td>#equipment.Code</td>
<td>#equipment.Name</td>
<td>#equipment.EquipmentBrand</td>
<td>#equipment.EquipmentModel</td>
<td>#String.Format("{0:n0}", equipment.Quantity)</td>
<td colspan="2">
<table >
<tbody >
#foreach (var item in equipment.EligibilityChecksheets)
{
<tr>
<td>#item.CheckListItem</td>
<td>#item.Note</td>
</tr>
}
</tbody>
</table>
</td>
<td>#String.Format("{0:n0}", Model.Currency + " " + equipment.UnitPrice)</td>
</tr>
}
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th>Total : </th>
<th>#String.Format("{0:n0}", Model.Currency + " " + Model.TotalPrice)</th>
</tr>
</tbody>
</table>
The problem with this code is - there is a gap between <td> and the inner table. I want to do this work using rowspan - is it possible to do it for this scenario?
When you are making an HTML table, the table rows of the table are constructed sequentially in HTML; i.e.- once you create a new <tr>, you can't add new <td> or other table elements in any previous <tr> directly from HTML.
For this reason, any variant of this approach will not work as you are expecting:
<table>
foreach(parent-row in parent-table)
{
<tr>
<!-- parent table data of each row in "td"s with rowspan -->
foreach(child-row in child-table)
{
<tr>
<!-- child table data of each row in "td"s without rowspan -->
</tr>
}
<!-- remaining parent table data of each row in "td"s with rowspan -->
</tr>
}
</table>
One thing I can think of about how you can do what you are asking for is -
completely construct the first row - including the first row of the child table. After constructing that row, you can construct the remaining rows of the child table for that particular parent table row.
In code, the approach will be something like this (considering rowspan = 'number of rows in child table for a particular row in the parent table'):
<table>
foreach(parent-row in parent-table)
{
<tr>
<!-- parent table data of each row in "td"s with rowspan -->
foreach(child-row in child-table) // this loop will iterate only once
{
<!-- child table data of first row in "td"s without rowspan -->
}
<!-- remaining parent table data of each row in "td"s with rowspan -->
</tr>
<!-- parent table row with first row of child table for that parent table row created -->
<!-- creating the remaining rows of the child table -->
foreach(child-row in child-table) // this loop will iterate (rowspan - 1) times
{
<tr>
<!-- child table data of each row except first row in "td"s without rowspan -->
</tr>
}
} // parent table row with its corresponding child table fully constructed
</table>
My problem is that HTML table instead of displaying Rows vertically, after some rows it starts to put them into a new column automatically, in this order:
|Row1 | Row3 | Row4 |
|Row2 |
But I only need it to go vertically just in one column:
|Row1|
|Row2|
|Row3|...
Below my table's HTML code and how I am loading in data:
<table id="coinflip-table">
<tbody id="coinflip-list">
<tr>
#if (ViewBag.CoinflipAll != null)
{
foreach (CoinFlip.Main.Models.CoinflipViewModel cfGames in Model.Coinflips)
{
<td>
<img class="coinflip-list-avatar" src="#cfGames.User1_IconUrl" />
#if (cfGames.Status != 0)
{
<span class="coinflip-vs-player">VS</span>
<img class="coinflip-list-avatar" src="#cfGames.User2_IconUrl" />
}
</td>
<td class="coinflip-list-skins">
#if (ViewBag.WeaponBet != null)
{
foreach (CoinFlip.Main.Models.WeaponWebViewModel wep in ViewBag.WeaponBet)
{
<img class="coinflip-list-skins-small" title="#wep.Name" src="#wep.ImageUrl">
}
}
</td>
<td>
<span class="coinflip-value">$#cfGames.TotalValue</span>
</td>
<td></td>
<td>
<button class="coinflip-list-action" type="button" data-toggle="modal">WATCH</button>
</td>
}
}
</tr>
</tbody>
</table>
And I cannot seem to understand the cause of it. Is there a solution to this, just to go vertically? In JS, CSS or HTML? Or the issue can be related somewhere else?
Any help is appreciated,
Cheers
you need to include <tr> tag in loop to get row foreach list
or
if you need vertical row within a column try this!
<!-- Row -->
<tr>
<!-- Column -->
<td>
<!-- Row Within Column -->
<tr>
<td></td>
</tr>
</td>
</tr>
comment below if you have any questions?
If you need your table to be built vertically you have to put your foreach loop around < tr > < /tr > elements