Assign variable value in asp.net textbox in aspx - c#

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

Related

How to iterate through every HTML table in a single HTML row

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.

Retrieve data from HTML table in C#

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

How to dynamically display loop items in tables?

The following is the design.
<table>
<tr>
<td>Project Title</td>
<td>Download Link</td>
</tr>
<tr>
<td><asp:Label ID="dlLbl" runat="server"></asp:Label></td>
<td><asp:Label ID="dlLink" runat="server"></asp:Label></td>
</tr>
</table>
And the following is the backend codes.
foreach (SPListItem objInnovationListItem in objInnovationList.Items)
{
if (Convert.ToString(objInnovationListItem["Innovation Approval Status"])== status)
{
countStatus++;
//Displays name of the document and download link
dlLbl.Text = objInnovationListItem["Project Title"].ToString();
dlLink.Text = "<a href='/RIDepartment/Innovation%20Submission/" + objInnovationListItem.File.Name + "'>Download</a><br>";
}
}
Hence, my question is, what can I do to allow the tables to dynamically accommodate the document and dl link when there's more than 1 in the loop?
Appreciate some code samples.
With your code style (manual creating html without web-controls) i recommend you to look on ASP.NET MVC side. But i can answer to your question:
First - you need to use asp:Repeater like this:
<table>
<tr>
<td>Project Title</td>
<td>Download Link</td>
</tr>
<asp:Repeater ID="repLinks" runat="server"
onitemdatabound="repLinks_ItemDataBound">
<ItemTemplate>
<tr>
<td>
<asp:Label ID="lblProject" runat="server" Text="Label"></asp:Label>
</td>
<td>
<asp:HyperLink ID="hlLink" runat="server">HyperLink</asp:HyperLink>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
second: you need to initialize your collection, that you want to display. For example: you want to display a collection of objInnovationListItem class:
public class objInnovationListItem
{
public string Name { get; set; }
public string Title { get; set; }
public override string ToString()
{
return Title;
}
}
you need do next:
// list - it's source List<objInnovationListItem>
var bindList = list.Where(p => objInnovationListItem["Innovation Approval Status"] == status); // filter your collection - replace you foreach and if statement
repLinks.DataSource = bindList; // set to repeater your displayed collection
repLinks.DataBind(); // bind your collection
and last - you need to indicate in your Repeater ItemTemplate how to display your objInnovationListItem instance - subscribe to event of your Repeater ItemDataBound:
protected void repLinks_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
var item = e.Item.DataItem as objInnovationListItem;
((Label) e.Item.FindControl("lblProject")).Text = item.Name;
((HyperLink) e.Item.FindControl("hlLink")).NavigateUrl = string.Format("/downloaduri?id={0}", item.Title);
}
Result will look like that:
I would use a repeater... Something like this (code might not be exact):
<table>
<tr>
<td>Project Title</td>
<td>Download Link</td>
</tr>
<asp:Repeater id="rptItems" runat="server">
<ItemTemplate>
<tr>
<td><asp:Label ID="dlLbl" runat="server"></asp:Label></td>
<td>Download<br></td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
and then in the ItemDataBound event of the repeater, do something like this:
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) {
((Label)e.Item.FindControl("dlLbl")).Text= ((SPListItem)e.Item.DataItem)["Project Title"].ToString();
}
Why don't you skip the server side controls, and just write the actual html?
Include this div in your aspx file:
<div runat="server" id="divTable"></div>
And put this in your Page_Load():
StringBuilder sb = new StringBuilder();
sb.Append("<table><tr><td>Project Title</td><td>Download Link</td></tr>");
for (int i = 0; i < 10; i++)
{
sb.AppendFormat("<tr><td>{0}</td><td><a href='{1}'>{1}</a></td></tr>", "Title", "Link");
}
sb.Append("</table>");
divTable.InnerHtml = sb.ToString();
You'll of course need to replace "Title" and "Link" with the appropriate values.
Your other options is to actually create new labels and links, but ASP.net is notoriously difficult to work with when you create your server side controls dynamically.

Im trying to make a Repeater table visible = false

I have a document management system which creates a report showing people who own which document. There are times where people have 0 documents and in that case I would like the repeater table for that person to not be visible. I have looked around for a while and have not had much luck, maybe its because I am new or maybe its because I havent found my answer.
I have repeaters nested inside repeaters but if the first repeater is not visible the rest should follow.
aspx file
<h3> <%# DataBinder.Eval(Container.DataItem, "FullNm") %></h3>
<table ID="CollectorTable" runat="server" class="report-totals">
<tr>
<th>Total Collected:</th>
<td><asp:Literal ID="CollectorTotalCollected" runat="server" /></td>
<td class="report-totals-spacer"></td>
<th>Total Contacted:</th>
<td><asp:Literal ID="CollectorTotalContacted" runat="server" /></td>
<td class="report-totals-spacer"></td>
<th></th>
<td></td>
</tr>
</table>
// etc....
Code Behind
// ...pull totals
Control CollectorRepeater = new Control();
CollectorRepeater = (Control)e.Item.FindControl("CollectorRepeater");
CollectorRepeater.Visible = false;
Repeater collectorData = (Repeater)item.FindControl("CollectedTableRepeater");
collectorData.DataSource = collectedDocuments;
collectorData.DataBind();
Repeater contactedData = (Repeater)item.FindControl("ContactedTableRepeater");
contactedData.DataSource = contactedDocuments;
contactedData.DataBind();
So all you need to do is check if your data is empty - either before you bind it, or on a repeater's OnDataBinding event, and hide the repeaters if appropriate.
Repeater collectorData = (Repeater)item.FindControl("CollectedTableRepeater1");
Repeater contactedData = (Repeater)item.FindControl("ContactedTableRepeater2");
if( collectedDocuments.Tables[0].Rows.Count > 0 ){
//if there is data(more than 0 rows), bind it
collectorData.DataSource = collectedDocuments;
collectorData.DataBind();
contactedData.DataSource = contactedDocuments;
contactedData.DataBind();
} else {
collectorData.Visible = False;
//optional display "No data found" message
contactedData.Visible = False;
}
In the code behind, in the Repeater's ItemCreated event you can do a check for the document count, and only bind the table within the repeater item it if the count for the data is more than 0.
You can do exactly like "rlb.usa" said or just replace the else part with:
else {
collectorData.DataSource = null;
collectorData.DataBind();
contactedData.DataSource = null;
contactedData.DataBind();
}

ASP.net - Unsure on how to generate table

Given the following HTML:
<asp:content id="Content1" contentplaceholderid="mainContent" runat="server">
<div class="scrollRow">
<table width="100%">
<tr>
<td width="25%">Site name: <b>My site</b></td>
<td>Created on 12th Aug 2010</td>
<td align="right"><button onclick="doRevert(1)">Revert to this</button></td>
</tr>
</table>
</div>
<div class="scrollRow">
<table width="100%">
<tr>
<td width="25%">Site name: <b>Another site</b></td>
<td>Created on 3rd Aug 2010</td>
<td align="right"><button onclick="doRevert(1)">Revert to this</button></td>
</tr>
</table>
</div>
<div class="scrollRow scrollRowOn">
<table width="100%">
<tr>
<td width="25%">Site name: <b>Another site</b></td>
<td>Created on 3rd Aug 2010</td>
<td align="right"></td>
</tr>
</table>
</div>
</asp:content>
Which is a list of rows, how am I programatically meant to generate these after I have retrieved the SQL rows from the code behind? Do I need to make my own control, or something along those lines?
Try something along these lines:
<asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_OnItemDataBound">
<ItemTemplate>
<div class='<%# SetClass(Eval("SiteId")) %>'>
<table width="100%">
<tr>
<td width="25%">Site name: <b><%# Eval("SiteName") %></b></td>
<td>Created on <%# DataBinder.Eval(Container.DataItem, "CreateDate", "{0:dd MMM yyyy}")%></td>
<td align="right"><button id="btnRevert" runat="server" onclick="doRevert(1)">Revert to this</button></td>
</tr>
</table>
</div>
</ItemTemplate>
</asp:Repeater>
In the codebehind Repeater1_OnItemDataBound event you could set the button to be visible or not, depending on whether the item is the current one.
protected void Repeater1_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
RepeaterItem item = e.Item;
if (item.ItemType == ListItemType.AlternatingItem || item.ItemType == ListItemType.Item)
{
Site site = e.Item.DataItem as Site; //List<Site> is what you are binding to the repeater
if (site.SiteId == currentSiteId)
{
var btn = e.Item.FindControl("btnRevert") as Button;
if (btn != null)
{
btn.Visible = false;
}
}
}
}
CSS Classes for your items can be set like this:
protected string SetClass(object obj) {
int siteId;
if (int.TryParse(obj.ToString(), out siteId)){
if (siteId == currentSiteId) //currentSiteId determined elsewhere
{
return "scrollRow";
}
}
return "scrollRow scrollRowOn";
}
There are a lot of ways to get to this, of course, but here's one (possibly not the best, but that's subjective anyway):
Assuming C# web forms and ADO.Net, and assuming you need precisely that html, you could loop over the rows in the DataSet and output the html.
DataSet ds = {data set from your sql}
StringBuilder html = new StringBuilder();
foreach (DataRow row in DataSet.Tables[0].Rows) {
html.Append( string.Format(#"<div class=""scrollRow"">
<table width=""100%"">
<tr>
<td width=""25%"">Site name: <b>{0}</b></td>
<td>Created on {1}</td>
<td align="right"><button onclick="doRevert(1)">Revert to this</button></td>
</tr>
</table>",row["sitename"], row["createdate"]));
}
You could include the html by having an <asp:Literal> in the page code and setting the Text property.
You could also do it by creating System.Web.UI.WebControls.Table nodes in the code behind and adding TableRows and TableCells to them, using the same loop, and then adding those to the page using. Given what you've given us thus far, you seem to be adding controls to a page with a MasterPage, so you would need to add your tables to the Master's ContentPlaceHolder, which you can find and add controls to like so:
ContentPlaceHolder ph = (ContentPlaceHolder)this.Master.FindControl( "ContentPlaceHolder1" );
foreach (DataRow row in DataSet.Tables[0].Rows) {
Panel pnl = new Panel();
Table tbl = new Table();
TableRow tblrow = new TableRow();
TableCell cell1 = new TableCell();
cell1.Text = string.Format("Site name: <b>{0}</b>",row["sitename"]);
row.Cells.Add(cell1);
tbl.Rows.Add(tblrow);
pnl.Controls.Add(tbl);
ph.Controls.Add(pnl);
}
You can set properties on the TableRows and TableCells, but if you do it this way you will lose some control over the html that's generated, most notably the html ID attributes. You don't seem to be using those, so perhaps that's ok.
I would suggest the repeater control. You can use it something like this:
<asp:Repeater runat="server" id="myRepeater">
<ItemTemplate>
<div class="scrollRow scrollRowOn">
<table width="100%">
<tr>
<td width="25%">Site name: <b><% Eval("SiteName")%></b></td>
<td>Created on <% Eval("CreatedOn")%></td>
<td align="right"></td>
</tr>
</table>
</div>
</ItemTemplate>
</asp:Repeater>
Then you need to bind your data to it in the Page_Load event:
myRepeater.DataSource = myData;
myRepeater.DataBind();
Where my data is the data that you retrieve from the database.

Categories

Resources