Dynamically generating table containing child table using rowspan and loops - html

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>

Related

Insert 2 html table cells that cover 3 rows

In this Html table , how could I insert the cells "XPath" and "XSL transformations" as each of them covers 1.5 row (the 2 cells cover equally 3 rows).
How should I use the "rowspan" attribute ?
<td rowspan = "number">table content...</td>
Another example
<table>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
<tr>
<td>Ajay</td>
<!-- This cell will take up space on two rows -->
<td rowspan="2">24</td>
</tr>
<tr>
<td>Priya</td>
</tr>
</table>

Display different backgrounds for alternating rows of expanding table

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>

html - css - print page - header repeat not working

why Header1 and Header2 not exists in all page in print landscape
https://fiddle.jshell.net/6mvucked/
seems height header is limit. if more than a value to be not show in all page
why ?
ٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍٍ
Your javascript will append 100 rows to only those containers whose id is "test".
So if you want the same to happen with the tbody of header, then simply write
<tbody id="test">
in the one in the header.
But in that case, it will only print 100 rows for the header tbody and not the other second tbody, as Javascript will append 100 rows to the 1st tag with id="test".
So if you need to append 100 or x number of rows to both or many tbody, then give them separate ids and hence write separate functions for them in javascript.
Like this:
<table>
<teahd>
<tr>
<td>ok , no problem, but show only in first page and not repeat</td>
<td>
<table>
<tbody id="test-one">
<tr><td>header not be shown if this code(table) here</td></tr>
</tbody>
</table>
</td>
</tr>
</teahd>
<tbody id="test-two">
</tbody>
<tfoot>
<tr>
<td>no problem</td>
</tr>
</tfoot>
</table>
And the javascript functions like:
for(var i=1;i<=100; i++)
$('#test-one').append('<tr><td colspan="2">row '+i+'</td></tr>');
$('#test-two').append('<tr><td colspan="2">row '+i+'</td></tr>');

Adding last row of table rowspan attribute doesnt work

I'm using twitter bootstrap but i dont think that makes a difference to what I'm doing.
Basically I have a table. I'm testing the length of an enumerable that is filling the table and the last row i want to "pad" to the full length of the container i.e. if its less than 10 rows i want to add a row that has a rowspan that is 10 - item.count... however, its just rendering a blank row... is this intentional or am i doing something wrong? Here is a fiddle:
http://jsfiddle.net/L46FX/37/
and here is a table... any help would be appreciated...
<table class="table table-bordered">
<thead>
<tr>
<th>#</th>
<th>First Name</th>
<th>Last Name</th>
<th>Username</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="2">1</td>
<td>Mark</td>
<td>Otto</td>
<td>#mdo</td>
</tr>
<tr>
<td>Mark</td>
<td>Otto</td>
<td>#TwBootstrap</td>
</tr>
<tr>
<td>2</td>
<td>Jacob</td>
<td>Thornton</td>
<td>#fat</td>
</tr>
<tr>
<td>3</td>
<td colspan="2">Larry the Bird</td>
<td>#twitter</td>
</tr>
<tr>
<td colspan="4" rowspan="10">
this should be a row that is 10 rows long...
</td>
</tr>
</tbody>
</table>
EDIT:
As suggested, javascript seems to be the answer... this is what I came up with, it tests the line-height due to the fact my tables are in a tab so the height attribute came back with 0 because they weren't currently in a active tab..
$('.stretch').each(function () {
var rows = $(this).rowCount();
if (rows < 10) {
var lr = $(this).children('tbody').children('tr:last');
var bg = lr.children('td').first().css('background-color');
var ht = lr.css('line-height').replace('px', '') * (10 - rows);
var row = '<td colspan="' + lr.children('td').length + '"></td>';
$(this).children('tbody').append('<tr style="height: ' + ht + 'px; background-color: ' + bg + '">' + row + '</tr>');
}
});
Also to clarify what I was doing... I really hate it when a table renders 1 row, it just looks so ugly :) I tend to put action items for the table in the footer so this attempts to fill the container with a giant row and anchors the tfoot to the bottom of the parent or very close to it....
Not sure I completely understand... but here is what I think...
rowspan is used incorrectly in your code. It will only increase the height of a tr if the column has rows beside it. See this example: http://reference.sitepoint.com/html/th/rowspan
If you want to expand the last row to 10x its size, you could use some script as follows:
var a = $( "tr" ).last().height();
$( "tr" ).last().css('height',a * 10 + 'px');
Here's the demo: http://jsfiddle.net/L46FX/38/
You mean the CELL should be 10 COLUMNS long. You are mixing up the meanings of "row" and "column" (col) and also "row" and "cell".
<tr>
<td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
</tr>
<tr>
<td colspan="10">this should be a CELL that is 10 COLUMNS long...</td>
</tr>
Of course your table first needs to have 10 columns and yours does not.
I didn't understand real problem, but it you want last table cell <td> spans 10 rows, than you used it incorrectly.
This is not a valid html. If you give rowspan into last row table-cell than, there is no space to spans table-cell.
ROWSPAN: This attribute specifies the number of rows spanned by the current cell. The default value of this attribute is one ("1"). The value zero ("0") means that the cell spans all rows from the current row to the last row of the table section (THEAD, TBODY, or TFOOT) in which the cell is defined.
Read table specification
See this

Adding data into rows of next column

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