I have a standard HTML <table inside an ASP:Panel control.
Inside this HTML table is a <TR row
And inside this TR row are severale tables.
<asp:panel ID="PanelPreStart" runat="server" Visible="false" Enabled="false" Width="500px" >
<table runat="server" id="tblPreStart">
...
...
<tr id="trRiskMgt" runat="server" visible="false">
<td colspan="2">
<strong><big>** RISK MANAGEMENT **</big></strong>
<br /><br />
<table id="tblHOC_MON" runat="server" visible="false">
..
..
</table>
<br />
<table id="tblRMP_TUE" runat="server" visible="false" style="width: 100%; height: 114px; color: black; background-color: white;">
<tr>
...
... etc
How do I iterate through the trRiskMgt row to get to all the tables (tblHOC_MON, etc)?
I've tried this but it does not work. I get this error:
CS1579: foreach statement cannot operate on variables of type
'System.Web.UI.HtmlControls.HtmlTableRow' because
'System.Web.UI.HtmlControls.HtmlTableRow' does not contain a public
definition for 'GetEnumerator'
foreach (HtmlTableRow trow in trRiskMgt)
{
foreach (HtmlTable tbl in trow.Cells)
{
foreach (HtmlTableRow row in tbl.Controls)
{
foreach (HtmlTableCell cell in row.Cells)
{
foreach (Control ctrl in cell.Controls)
{
//CONTROL IS TEXBOXT: DISABLE CONTROL (NOT HIDE!)
if (ctrl is TextBox)
{
TextBox txt = (TextBox)ctrl;
txt.Enabled = wsDisable;
}
}
}
}
}
}
Ideas for both JavaScript and C# code behind appreciated.
Thank you
[UPDATE]
I've managed to get around it by hardcoding one of the above tables into the code...
foreach (HtmlTableRow row in tblHOC_MON.Rows)
{
foreach (HtmlTableCell cell in row.Cells)
{
foreach (Control ctrl in cell.Controls)
{
//CONTROL IS TEXBOXT: EXTRACT VALUES//
if (ctrl is TextBox)
{
TextBox txt = (TextBox)ctrl;
txt.Enabled = false;
}
}
}
}
This is obviously not ideal, as I will need to repeat this code multiple times for every table in the TR row.
But it will do for now.
Try inner html concept.
Example:
to iterate particular html element say "table row" in your case, write below code on your controller:
trRiskMgt.InnerHtml = Server.HtmlEncode("your data");// elementId.InnerHtml
If you haven't specified any data it will show the single row in this case.
AS the data will increase it will iterate the row.
You can further google HtmlEncode or Decode for better understanding.
Related
There does not seem to be a lot of info out there when using a GridView with AutoGenerateColumns="true".
In my scenario, I am attempting to use this because my GridView is dynamically pulling numeric values from a stored procedure. As you can see, there may be x number of tiers.
I have everything looking great when viewing the data:
Viewing only:
However, once I put the row into edit mode, things get like this:
Edit mode:
I need to do two things here:
Make the TextBoxes smaller width
Format the numbers to remove the decimals
I have researched looping through all of the controls inside a GridView row, inside DataControlField, inside the DataControlFieldCell but I have gotten confused enough to ask for everyone's help.
My code behind is in C#.
EDIT:
Ok, in an effort to be more clear, I am trying to click the edit (M button) to put the row into edit mode. From here, I would like to loop through all controls in the row and then set the TextBox width. Something along these lines (this is not working code but merely me messing around):
protected void gvFeeTable_RowEditing(object sender, GridViewEditEventArgs e)
{
gvFeeTable.EditIndex = e.NewEditIndex;
BindFeeTableGrid(9);
//foreach (DataControlField field in gvFeeTable.Columns)
//{
// field.ControlStyle.Width = 25;
//}
foreach (Control c in gvFeeTable.Rows[gvFeeTable.EditIndex].Controls)
{
//if (c is TextBox)
//{
// TextBox tb = c as TextBox;
// tb.Width = 25;
//}
string test = c.GetType().ToString();
if (c.GetType() == typeof(DataControlFieldCell))
{
foreach (TextBox tb in c.Controls)
{
tb.Width = 50;
}
}
}
}
For example I want set width of column 3 in c# code: You can do it for all other columns.
GridView1.Columns[2].ItemStyle.Width = 20;
And, for removing decimals use integer datatype in database;
Just wanted to post my solution for setting the size of the textbox...and adding in my code for formatting just to be complete:
protected void gvFeeTable_RowEditing(object sender, GridViewEditEventArgs e)
{
gvFeeTable.EditIndex = e.NewEditIndex;
BindFeeTableGrid(9);
foreach (Control c in gvFeeTable.Rows[gvFeeTable.EditIndex].Controls)
{
if (c.GetType() == typeof(DataControlFieldCell))
{
foreach (Control control in c.Controls)
{
TextBox tb = control as TextBox;
if (tb != null)
{
tb.Width = 50;
double dbl;
bool isNumeric = double.TryParse(tb.Text, out dbl);
if (isNumeric == true)
{
tb.Text = Convert.ToDecimal(tb.Text).ToString("0.00");
}
}
}
}
}
}
Textboxes resized
Textboxes formatted
#gvSomeGridView1 .inpA{ width: 20px;}
#gvSomeGridView1 .inpB{ width: 40px;}
#gvSomeGridView1 .inpC{ width: 80px;}
#gvSomeGridView2 td:nth-child(1) input{ width: 30px;}
#gvSomeGridView2 td:nth-child(2) input{ width: 60px;}
#gvSomeGridView2 td:nth-child(3) input{ width: 120px;}
#gvSomeGridView3 td > input { width:50px}
<div>
<table id="gvSomeGridView1">
<tbody>
<tr>
<td><input id="input1" type="text" class="inpA" /></td>
<td><input id="input2" type="text" class="inpB" /></td>
<td><input id="input3" type="text" class="inpC" /></td>
</tr>
</tbody>
</table>
</div>
<div>
<table id="gvSomeGridView2">
<tbody>
<tr>
<td><input id="input1" type="text"/></td>
<td><input id="input2" type="text"/></td>
<td><input id="input3" type="text"/></td>
</tr>
</tbody>
</table>
</div>
<div>
<table id="gvSomeGridView3">
<tbody>
<tr>
<td><input type="text"/></td>
<td><input type="text"/></td>
<td><input type="text"/></td>
</tr>
</tbody>
</table>
</div>
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 retrieve data from HTML document.
I am scraping data from a web site I almost done but get issue when tried to retrieve data from the table.
Here is HTML code
<div id="middle_column">
<form action="url?" method="post" name="inquirydetail">
<input type="hidden" name="ServiceName" value="SurgeWebService">
<input type="hidden" name="TemplateName" value="Inpat_AvailableResponses.htm">
<input type="hidden" name="CurrentPage" value="inquirydetail">
<form method="post" action="url" name="ResponseSel" onSubmit="return EditPage(document.forms[3])">
<TABLE
<tBody
<table
....
</table
<table
....
</table
<table border="0" width="90%">
<tr>
<td width="10%" valign="bottom" class="content"> Service Number</td>
<td width="30%" valign="bottom" class="content"> Status</td>
<td width="50%" valign="bottom" class="content"> Status Date</td>
</tr>
<tr>
<td width="20%" bgcolor="white" class="subtitle">1</td>
<td width="40%" bgcolor="white" class="subtitle">Approved</td>
<td width="40%" bgcolor="white" class="subtitle">03042014</td>
</tr>
<tr>
<td></td>
</tr>
</table>
</tbody>
</TABle>
</div>
I have to retrieve data for Status field It is Approved and write it in SQL DB
There are many tables in the form tag.Tables do not have IDs.How I can get correct table,row and cell
Here is my code
HtmlElement tBody = WB.Document.GetElementById("middle_column");
if (tBody != null)
{
string sURL = WB.Url.ToString();
int iTableCount = tBody.GetElementsByTagName("table").Count;
}
for (int i = 0; i <= iTableCount; i++)
{
HtmlElement tb=tBody.GetElementsByTagName("table")[i];
}
Something is wrong here
Please help with this.
Don't you have any control over the page being displayed within the Webbrowser control? If you do it's better you add an id field for status TD. Then your life would be much easier.
Anyway, here's how you could search a value within a table.
HtmlElementCollection tables = this.WB.Document.GetElementsByTagName("table");
foreach (HtmlElement TBL in tables)
{
foreach (HtmlElement ROW in TBL.All)
{
foreach (HtmlElement CELL in ROW.All)
{
// Now you are looping through all cells in each table
// Here you could use CELL.InnerText to search for "Status" or "Approved"
}
}
}
But, this is not a good approach as you are looping through each table and each cell within each table to find your text. Keep this as the last option.
Hope this helps you to get an idea.
I prefer using the dynamic type and the DomElement property, but you must be using .net 4+.
For tables, the main advantage here is that you don't have to loop through everything. If you know the row and column that you are looking for, then you can just target the important data by row and column numbers instead of looping through the whole table.
The other big advantage is that you can basically use the entire DOM, reading more than just the contents of the table. Make sure you use lowercase properties as required in javascript, even though you are in c#.
HtmlElement myTableElement;
//Set myTableElement using any GetElement... method.
//Use a loop or square bracket index if the method returns an HtmlElementCollection.
dynamic myTable = myTableElement.DomElement;
for (int i = 0; i < myTable.rows.length; i++)
{
for (int j = 0; j < myTable.rows[i].cells.length; j++)
{
string CellContents = myTable.rows[i].cells[j].innerText;
//You are not limited to innerText; you have the whole DOM available.
//Do something with the CellContents.
}
}
I have an ASP:DataList. Inside the DataList, I have the code below which displays the Name and Checkbox for each row.
What I would like to do is:
Store the Name in a hidden field.
Loop through all the checkboxes, find the ones that are checked and INSERT the value into the database.
If possible, please provide some sample code.
<td style="width: 600px"><%#Eval("Name></td>
<td style="width: 20px">
<asp:CheckBox ID="chkName" Text='<%# Eval("Name") %>' runat="server" />
</td>
what you are doing is fine.
Just in your postback, loop though the check box and check
foreach (Checkbox cb in YOurcheckboxlist)
{
if (cb.Checked) {
// get the name and insert
}
}
Had this situation before, this is what I did,
in the form_Sumbit event,
foreach (Control ctl in form1.Controls)
{
if (ctl is CheckBox)
{
//check for checked or not and store the value into an array or a List.
}
}
Not a perfect solution, let's see if someone can come up with a better idea.
I am writing an application to generate an "Image Summary" of a directory. Image Summary being an HTML document with a table containing the images of that directory. I am attempting to create the HTML document with a StreamWriter. I want each Row (<tr>) to contain 6 images. How can I achieve this? I've searched and can't find a thing that helps.
I would use a ListView. Something like this should get you started:
<asp:ListView runat="server" ID="ListView1" DataSourceID="SqlDataSource1">
<LayoutTemplate>
<table runat="server" id="table1" >
<tr runat="server" id="itemPlaceholder" ></tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr runat="server">
<td runat="server">
<asp:Image ID="Image1" runat="server" ImageUrl='<%#Eval("ImageUrl") %>' />
</td>
</tr>
</ItemTemplate>
</asp:ListView>
This will just create a tr with a single td for every row of data. You would obviously want to create six td's with images instead of just one.
Easiest way, in my opinion, would be to start with Directory.GetFiles(). This will return a string[] of file paths.
From there, you could bind that collection to a Repeater. See the answer to this question for a slick way to show n number of elements per row. There's also a link to an article in that thread that shows how to do it with a ListView.
Messy example.. but works (I'm assuming you're not doing this from ASP.NET, as the others have assumed, since you're using a StreamWriter):
static void renderHTML(string folder, string outputFile, int imagesPerRow, params string[] extensions) {
string[] images = Directory.GetFiles(folder);
using (var sw = new StreamWriter(File.OpenWrite(outputFile))) {
sw.WriteLine("<!html><head><title>Example</title></head><body><table>");
int counter = 0;
sw.Write("<tr>");
foreach (string image in images.Where(x => extensions.Any(y => x.Contains(y)))) {
if (counter == imagesPerRow) {
sw.Write("</tr>");
sw.Write("<tr>");
counter = 0;
}
sw.Write("<td style=\"border: 1px solid;\">");
sw.Write(string.Format("<img src=\"{0}\" />", image));
sw.Write("</td>");
counter++;
}
sw.Write("</tr></table></body></html>");
}
}
You can call it like so:
renderHTML(#"C:\folder", #"C:\output.html", 6, new string[] { ".jpg", ".png", ".gif" });