I have this HTML table in my aspx page which will be populated from datatable, and I need to put a checkbox at the start of each row.
I tried to use the code below in which I used StringBuilder and I also tried using TagBuilder but nothing works.
//Building an HTML string.
StringBuilder html = new StringBuilder();
//Building the Data rows.
foreach (DataRow row in dt.Rows)
{
html.Append("<tr>");
html.Append("<td>");
html.AppendFormat("< input type = 'checkbox' />"); //here it displays the tag as string
html.Append("</td>");
foreach (DataColumn column in dt.Columns)
{
html.Append("<td>");
html.Append(row[column.ColumnName]); //here it displays the data
html.Append("</td>");
}
html.Append("</tr>");
}
datatableBody.Controls.Add(new Literal
{
Text = html.ToString()
});
Here is the Table :
<table class="table dataTable my-0" id="dataTable" style="text-align:center">
<thead>
<tr>
<th><input type="checkbox" /></th>
<th>Matricule</th>
<th>Prenom</th>
<th>Date</th>
<th>Periode</th>
<th>Total</th>
</tr>
</thead>
<tbody id="datatableBody" runat="server">
</tbody>
</table>
Here are the results:
I also want to be able to access the value of the checkbox (checked or not).
I am not sure about that but I think you can use something like this :
html.Append("<input type=\"checkbox\" name=\"CheckSelect").Append(row["id"]).Append("\">");
Or If you don't mind to use Jquery, here is a solution for you :
https://forums.asp.net/t/2156602.aspx?Appending+the+Checkbox+to+the+HTML+Table+
Related
I use EPPlus version 4.0.4 to create an Excel file within an ASP.net MVC5 website and I simply don't know how to add a new rows and columns after completing the very first row.
It's difficult to explain clearly so let's me show you my code. It's easy enough to understand.
var products = new DataTable("1km subscriptions");
// SO HERE THE FIRST COLUMS with ROWS INFORMATION
products.Columns.Add("", typeof(int));
products.Columns.Add("Full Name", typeof(string));
products.Columns.Add("BirthDate", typeof(string));
int i = 0;
foreach (var item in GetData())
{
// Primary user info
products.Rows.Add(i, item.FullName, item.BirthDate);
i++;
// HERE I HAVE TO GO TO NEXT LIGNE NUMBER AND WRITE TWO COLUMNS AND ROWS INFO
//products.NewRow();
products.Columns.Add("ORDER #", typeof(int));
products.Columns.Add("BUY DATE", typeof(string));
foreach (var order in item.OrderViewModels)
{
products.Rows.Add(order.Id, order.CreatedDate);
//products.NewRow();
// THEN, I HAVE TO DO THE SAME THING. GO TO THE NEXT LIGNE AND ADD TWO OTHERS COLUMNS WITH INFO
products.Columns.Add("PRODUCT NAME", typeof(string));
products.Columns.Add("Quantity", typeof(int));
foreach (var osku in order.OrderSKUViewModels)
{
products.Rows.Add(osku.SKUName, osku.Quantity);
}
}
}
using (ExcelPackage pck = new ExcelPackage())
{
ExcelWorksheet ws = pck.Workbook.Worksheets.Add("FIRST TAB NAME");
ws.Cells["A1"].LoadFromDataTable(products, true)
// Write it back to the client
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment; filename=ExcelDemo.xlsx");
Response.BinaryWrite(pck.GetAsByteArray());
Response.Flush();
Response.End();
}
At first, I was thinking the products.NewRow() will do the job but it's not the case. I don't find an easy we to do what that easy operation. I would like to avoid to do major changes to the code for something like that o_O
Anyone can help ?
David
Edit
I can't add a picture but I can share the HTML code I use to display the data. I try to reproduce the same architecture with Excel. So we can understand that I thought that product.NewLine() could produce a kind of line change... :
<table class="table table-hover" style="border: 1px solid #ddd;">
#foreach (var item in Model)
{
<tr class="success">
<th style="width:122px;">Full Name</th>
<th style="width:118px;">BirthDate</th>
</tr>
<tr class="active">
<td>#item.FullName</td>
<td>#item.BirthDate</td>
</tr>
foreach (var order in item.OrderViewModels)
{
<tr>
<td><b>Commande:</b></td>
<td><b>#</b> #order.Id</td>
<td colspan="6"><b>Buy date:</b> #order.CreatedDate</td>
</tr>
foreach (var osku in order.OrderSKUViewModels)
{
<tr>
<td colspan="3"><b>Product name:</b> #osku.SKUName</td>
<td colspan="5"><b>Quantity:</b> #osku.Quantity</td>
</tr>
}
<tr>
#if (order.GuestViewModels.Count() != 0)
{
<th colspan="8" class="success">Guests</th>
}
</tr>
if (order.GuestViewModels.Count() > 0)
{
<tr class="warning">
<th style="width:122px;">FullName</th>
<th style="width:118px;">BirthDate</th>
</tr>
}
foreach (var guest in order.GuestViewModels)
{
<tr style="border-top: 2px double #0094ff;border-left:2px solid #0094ff;border-right:2px solid #0094ff">
<td>#guest.FullName</td>
<td>#guest.BirthDate</td>
</tr>
}
}
}
</table>
I have these tables:
<table>
<tbody>
<tr><th>Header 1</th></tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
<th>Header 4</th>
<th>Header 5</th>
</tr>
<tr>
<td>text 1</td>
<td>text 2</td>
<td>text 3</td>
<td>text 4</td>
<td>text 5</td>
</tr>
</tbody>
</table>
I am trying to transform into an array or List using this code:
var query = from table in doc.DocumentNode.SelectNodes("//table").Cast<HtmlNode>()
from row in table.SelectNodes("tr").Cast<HtmlNode>()
from header in row.SelectNodes("th").Cast<HtmlNode>()
from cell in row.SelectNodes("td").Cast<HtmlNode>()
select new {
Table = table.Id,
Row = row.InnerText,
Header = header.InnerText,
CellText = cell.InnerText
};
But it doesn't work. What is wrong?
Some notes:
You do not need a cast
you are assuming that each row have headers
SelectNodes needs to receive an xpath and you are passing just names
if i were you i would use a foreach and model my data, that way i get to have more control and efficiency, but if you still want to do it your way this is how it should be
var query = from table in doc.DocumentNode.SelectNodes("//table")
where table.Descendants("tr").Count() > 1 //make sure there are rows other than header row
from row in table.SelectNodes(".//tr[position()>1]") //skip the header row
from cell in row.SelectNodes("./td")
from header in table.SelectNodes(".//tr[1]/th") //select the header row cells which is the first tr
select new
{
Table = table.Id,
Row = row.InnerText,
Header = header.InnerText,
CellText = cell.InnerText
};
I have an html table like below:
<table>
<caption>Table 2</caption>
<tr><td>hd1</td><td>hd2</td></tr>
<tr><td>val01</td><td>val02</td></tr>
<tr>
<td colspan="2">
<table>
<caption>Subtable 2</caption>
<tr><td>subval01</td><td>subval02</td></tr>
</table>
</td>
</tr>
</table>
EDIT
Here is my code:
foreach (HtmlNode rows in htmltable.SelectNodes("tr"))
{
DataRow dr = dt.NewRow();
int iRow = 0;
if (!rows.InnerHtml.Contains("<caption>"))
{
foreach (HtmlNode cell in rows.SelectNodes("td"))
{
iRow++;
dr[iRow] = cell.InnerText;
}
}
dt.Rows.Add(dr);
}
My code recognizing <caption> as row and selecting it as well.
I don't get how to skip caption while parsing. So I can parse ONLY the rows.Skip(1) method is not working for me.
If I understand this correctly, you want to skip <tr> having descendant node <caption> (the last <tr> within outer <table> tag). In this case we can use XPath to select only <tr> that doesn't have <caption> like so :
foreach (HtmlNode rows in htmltable.SelectNodes("tr[not(.//caption)]"))
{
DataRow dr = dt.NewRow();
.....
.....
dt.Rows.Add(dr);
}
I have a user control that is part of an update panel. The user control is a heading( tag) and a asp Table. The asp:Table is defined in the ascx file only with the headers. The contents of this table are updated dynamically from the code behind by reading a csv file. This set up is within an Update panel which updates every minute. After every minute the csv file gets updated and hence the table needs to be updated.
Here is the tricky part. Before the table is I updated I need to save a copy of the old table and then update the new table. Once the new table is updated and the page is about to be loaded I need to call a javascript function from in the page_load handler and pass the two tables. Inside the javascript function I need to compare the old table and the new table cell by cell and do some work based on the result of the comparison.
Here is how I copy the data from the table to another table before updating it.
TableCell tableCell;
TableRow tableRow;
for (int i = 0; i < Table1.Rows.Count; i++)
{
tableRow = new TableRow();
for (int j = 0; j < Table1.Rows[i].Cells.Count; j++)
{
tableCell = new TableCell();
tableCell.Text = Table1.Rows[i].Cells[j].Text;
tableRow.Cells.Add(tableCell);
}
oldTable.Rows.Add(tableRow);
}
But for some reason when I pass the tables to the javascript function and access the cells in javascript I see only the headers and not any values in the old table. But when I access the cells in my code behind itself I can see the values.
My HTML is
<table id="ContentPlaceHolderBody_ContentPlaceHolderBody_TradxPriceTable_5_oldTable" ClientID="oldTable">
<tr>
<td colspan="3">6M EURIBOR</td>
<td colspan="3">6M EURIBOR</td>
</tr><tr>
<td>Instr</td>
<td>Bid</td>
<td>Ask</td>
<td>Instr</td>
<td>Bid</td>
<td></td>
</tr><tr>
<td></td>
<td></td>
<td></td>
<td colspan="3">BASIS 3s6s</td>
</tr><tr>
<td></td>
<td></td>
<td></td>
<td>Instr</td>
<td>Bid</td>
<td>Ask</td>
</tr><tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
My javascript is
function foo(table1,table2)
{
var oldTable = document.getElementById(table1);
var newTable = document.getElementById(table2);
alert(oldTable.rows[2].cells[1].innerHTML+" "+newTable.rows[2].cells[1].innerHTML);
}
use html tables and form a string with the tables and the values and pass that string to javascript.
string newTable = "<Table><Tr><Td>"+ somevalue +"</Td></Tr></Table>"
in javascript
var newT = '<%= newTable %>'
I'm reading in a huge HTML string that has some info I need to extract from it. I can set up the search parameters (where to parse), but how can I achieve this without saving to a temp file then using StreamReader?
Example:
//Pertinent data starts here:
<!--
body for the page starts here
-->
<table border="0" >
<tr>
<td class='HeaderTD'><b>User Name</b></td>
<td class='HeaderTD'><b>Mark TheMan</b></td>
</tr>
<tr>
<td class='DataTD_Black_Bold '>Department</td>
<td class='DataTD'>Programming</td>
</tr>
<tr>
<td class='DataTD_Black_Bold '>Office Phone</td>
<td class='DataTD'>555-555-5555</td>
</tr>
<tr>
<td class='DataTD_Black_Bold '>Office Ext</td>
<td class='DataTD'>x5555</td>
I need to just set some attributes in a class to the various fields (which are strings):
User.UserName = "Mark TheMan";
User.Department = "Programming";
User.OfficePhone = "555-555-5555";
etc.
You see I need to search for a line that contains something like "<b>User Name</b>" then return the next line so I can parse out the desired data. Let me know if you need more info, thanks!
You should use Html parser, HtmlAgilityPack is very good.
Here is a little console application to show you how easy is to rip the data from tables :
static void Main(string[] args)
{
HtmlDocument doc = new HtmlDocument();
doc.Load("example.html");
foreach (HtmlNode table in doc.DocumentNode.SelectNodes("//table"))
{
foreach (HtmlNode row in table.SelectNodes("tr"))
{
foreach (HtmlNode cell in row.SelectNodes("th|td"))
{
Console.WriteLine("Cell value : " + cell.InnerText);
}
}
}
}
And for your example output will be :
Cell value : User Name
Cell value : Mark TheMan
Cell value : Department
Cell value : Programming
Cell value : Office Phone
Cell value : 555-555-5555