I want to do something like the code below using asp:table dynamically.
I know how to use Table, TableRow and TableCell, but I don't know how I can add a Table inside a TableRow.
<table>
<tr>
<td>[Image]</td>
<td>
<table>
<tr>
<td>Name</td>
<td>Test</td>
</tr>
<tr>
<td>Month</td>
<td>January</td>
</tr>
<tr>
<td>Code</td>
<td>11100</td>
</tr>
<tr>
<td>Price</td>
<td>$100,00</td>
</tr>
</table>
</td>
</tr>
</table>
I want to do something like the code bellow using asp:table
dynamically. I know how to use Table, TableRow and TableCell. But i
don't know how can i add a Table inside a TableRow.
Might I suggest instead you create a single table where you take advantage of row spans instead? Basically you should have 3 columns and the first column has a row height of 4 whereas the 2nd and 3rd columns don't.
Try this,
string table = "<table><tr><td>foo</td></tr></table>";
TableRow row = new TableRow();
TableCell cell = new TableCell();
cell.Text = table;
row.Cells.Add(cell);
Table1.Rows.Add(row);
Related
Recently I was trying to use the features of "https://datatables.net" in one GridView render. It wasn't possible because the render always gives a table without the correct formatting (without thead). Is there a way to transform the render into the correct format?
Correct format:
<table id="table_id" class="display">
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Row 1 Data 1</td>
<td>Row 1 Data 2</td>
</tr>
<tr>
<td>Row 2 Data 1</td>
<td>Row 2 Data 2</td>
</tr>
</tbody>
</table>
This code formats one table to the correct format and then runs the .DataTable(); on the corrected formatted table.
To use this replace the ID of your table in '#gdVscQuote'
If the page you are working on has more than one table this will not work, is not tested.
$(document).ready( function () {
//replace tr
$($('#gdVscQuote')[0].childNodes[1].childNodes[0]).wrap('<thead/>').contents().unwrap();
//replace all td with th inside thead
$('thead td').wrap('<th/>').contents().unwrap();
//get thead
var thead = $("thead").get(0);
//remove saved thead to replace above tbody thead
$("thead").remove();
//add thead correctly
$('#gdVscQuote')[0].prepend(thead);
// replace tds for tr
$($('thead')[0].childNodes).wrapAll("<tr/>")
//add jQuery table functionality
$('#gdVscQuote').DataTable();
});
I have HTML with looks basically like the following
....
<div id="a">
<table class="a1">
<tbody>
<tr>
<td><a href="a11.html>a11</a>
</tr>
<tr>
<td><a href="a12.html>a12</a>
</tr>
</tbody>
<table>
</div>
...
The following coding in C# I used, however, I cannot retrieve the URL in this stage
IWebElement baseTable = driver.FindElement(By.ClassName(TableID));
// gets all table rows
ICollection<IWebElement> rows = baseTable.FindElements(By.TagName("tr"));
// for every row
IWebElement matchedRow = null;
foreach(var row in rows)
{
Console.Write (row.FindElements(By.XPath("td/a")));
}
First of all, you gave us invalid markup. Right one:
<div id="a">
<table class="a1">
<tbody>
<tr>
<td>
a11
</td>
</tr>
<tr>
<td>
a12
</td>
</tr>
</tbody>
</table>
</div>
If you have only one anchor in table row, you should use this code to retrieve url:
IWebElement baseTable = driver.FindElement(By.ClassName(TableID));
// gets all table rows
ICollection<IWebElement> rows = baseTable.FindElements(By.TagName("tr"));
// for every row
IWebElement matchedRow = null;
foreach (var row in rows)
{
Console.WriteLine(row.FindElement(By.XPath("td/a")).GetAttribute("href"));
}
You need to get href attribute of found element. Otherwise, row.FindElement(By.XPath("td/a") will print type name of the IWebElement inherited class, because it is an some type object, not string.
This does not look like a valid xpath to me
Console.Write (row.FindElements(By.XPath("td/a")));
try
Console.Write (row.FindElements(By.XPath("/td/a")));
I am adding a textbox like this dynamically in my aspx file:
Here is my code:
foreach (DataRow info in myDataTable.Rows)
{
//draw html table and add controls
<input type="text" name="myTxt" id="myTxt" runat="server" />
<tr><td><%=Convert.ToString(info[0][1]) %></td></tr>
//more code here
}
How can I assign particular cell value to textbox?
I tried using <%=Eval(info[0][1])%> but it is not working as expected
Some guidance with this would be appreciated.
Thanks in advance.
Updated Q:
<table>
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
</thead>
<tbody>
<%
var rowId = 0;
foreach (System.Data.DataRow info in MyTable.Rows)
{
%> <tr>
<td> //want to draw a textbox which show value of column
<td><%=Convert.ToString(info[0]) %></td>
<td><%=Convert.ToString(info[3]) %></td>
}
%>
</tbody>
</table>
If you want to access the rows value and assign it:
myTxt.Value = info["column"].ToString();
or by column index:
myTxt.Value = info[index].ToString();
As you mentioned, that there is some constraint and you have to do this in aspx only. Keeping that in mind, you can use following code. And make a note here multiple inputs will have id = myTxt , you need to handle this. Else good approach is to follow Repeater and use databinding.
<table>
<%
int counter = 0;
foreach (System.Data.DataRow info in myDataTable.Rows)
{
string txtid = "myTxt" + counter.ToString();
%>
<tr>
<td>
<input type="text" name='myTxt<%=txtid %>' id='myTxt<%=txtid %>' value="<%=Convert.ToString(info[0]) %>" /></td>
<td><%=Convert.ToString(info[0]) %></td>
</tr>
<%
counter = counter + 1;
}%>
</table>
To retrieve changed textbox value on PostBack, use this Request.Form["myTxtmyTxt0"], Request.Form["myTxtmyTxt1"] etc..
You are doing it in wrong way. You need to instantiate TextBox control class and then attach it's properties and values. Finally add the newly created control to your webform's control collection like below. This may not guarantee any particular position where the control will be added. To guarantee the specific position you need to use a place holder control and then add your textbox control to that place holder.
foreach (DataRow info in myDataTable.Rows)
{
TextBox tbx = new TextBox();
tbx.Name = "some_name";
tbx.Text = info[idx].Tostring();
this.webform1.Controls.Add(tbx);
}
Example of using Place Holder Control
Add a place holder control to your ASPX design
<asp:PlaceHolder id="PlaceHolder1" runat="server"/>
Then in your code behind .cs file add the newly created TextBox control to place holder control collection
PlaceHolder1.Controls.Add(tbx);
(OR)
If you already have declared a textbox named myTxt in your design then you can just attached the value saying
foreach (DataRow info in myDataTable.Rows)
{
this.myTxt.Text = info[0] as string;
}
I want to parse a HTML table into a CSV file, but keeping the right number of colspan and rowpspan.
I'm using ";" as delimiter cell. Thus, when there colspan of 2 columns, for example, instead of having only one, ";", it will have 2.
I can extract the content of the table and make line breaks where tr indicators ends, but don't know how to treat colspan and rowspan.
HtmlNodeCollection rows = tables[0].SelectNodes("tr");
// Aux vars
int i;
// ncolspan
// For each row...
for (i = 0; i < rows.Count; ++i)
{
// For each cell in the col...
foreach (HtmlNode cell in rows[i].SelectNodes("th|td"))
{
/* Unsuccessful attempt to treat colspan
foreach (HtmlNode n_cell in rows[i].SelectNodes("//td[#colspan]"))
{
ncolspan = n_cell.Attributes["colspan"].Value;
}
*/
text.Write(System.Text.RegularExpressions.Regex.Replace(cell.InnerText, #"\s\s+", ""));
text.Write(";");
/*
for (int x = 0; x <= int.Parse(ncolspan); x++)
{
text.Write(";");
}
*/
}
text.WriteLine();
ncolspan = "0";
}
Any help, please? Thank you!
UPDATE: Here a simple example table to use:
<table id="T123" border="1">
<tr>
<td colspan="3"><center><font color="red">Title</font></center></td>
</tr>
<tr>
<th>R1 C1</th>
<th>R1 C2</th>
<th>R1 C3</th>
</tr>
<tr>
<td>R2 C1</td>
<td>R2 C2</td>
<td>R2 C3</td>
</tr>
<tr>
<td colspan="2">R3 C1 e C2 with "</td>
<td>R3 C3</td>
</tr>
<tr>
<td>R4 C1</td>
<td colspan=2>R4 C2 e C3 without "</td>
</tr>
<tr>
<td>R5 C1</td>
<td>R5 C2</td>
<td>R5 C3</td>
</tr>
<tr>
<td rowspan ="2">R6/R7 C1: Two lines rowspan. Must leave the second line blank.</td>
<td>R6 C2</td>
<td>R6 C3</td>
</tr>
<tr>
<td>R7 C2</td>
<td>R7 C3</td>
</tr>
<tr>
<td>End</td>
</tr>
</table>
CSV doesn't handle rowspan or colspan values - it's a very simple format that has no concept of columns or rows beyond it's delimiter and the end of line character.
If you want to try preserve the rowspan and colspan you will need to use an intermediate object model which you can use to store the specific contents of a cell and it's location, for example, before exporting the model to CSV. And even then, the CSV format will not preserve the colspan and rowspan as you may be hoping (i.e. like an Excel sheet would).
is true, that you can not put a rowspan or colspan in the csv format, what worked for me is to put blank spaces where the span should exist
It is not the best option, but aesthetically it looks similar
"";SEPTIEMBRE;;OCTUBRE;;NOVIEMBRE;;TOTAL;
PRODUCTOS;cantidad;monto;cantidad;monto;cantidad;monto;cantidad;monto
I'm using c# with htmlagilitypack. Everything works fine except when the table I'm looking for contains no rows. I'm trying to read only the data from the 1st table on the page. The problem is if the first table contains no rows, the htmlagilitypack seems to jump down to the 2nd table for some reason.
The html I'm trying to read looks something like this:
<table class='stats'>
<tr>
<td colspan='2'>This is the 1st table</td>
<tr>
<td>Column A</td>
<td>Column B</td>
</tr>
<tr>
<td>Value A</td>
<td>Value B</td>
</tr>
</table>
<table class='stats'>
<tr>
<td colspan='2'>This is the 2nd table</td>
<tr>
<td>Column 1</td>
<td>Column 2</td>
</tr>
<tr>
<td>Value 111</td>
<td>Value 222</td>
</tr>
</table>
I then retrieve the 1st table's values using the following line:
foreach (HtmlNode node in root.SelectNodes("//table[#class='stats']/tr[position() > 2]/td"))
How do I ensure the data I'm grabbing is only from the 1st table?
Thanks.
You could ensure that you only select the first matching table by using a position index [1] after the table selector.
Try the following:
"//table[#class='stats'][1]/tr[position()>2]/td"
If the first table has no rows, then you will get null back so you should check for that before iterating in the foreach.
For example you might want to do the following:
var elements = root.SelectNodes("//table[#class='stats'][1]/tr[position()>2]/td");
if (elements != null)
{
foreach (HtmlNode node in elements)
{
// process the td node
}
}
You need to have an id on the table or row which uniquely identifies the table or or and then use the id in the xpath.