get dynamically generated ajax textbox id - c#

I have created a web application in which I need to generate textboxes depending upon the number the user enters.I have used Ajax and created textboxes dynamically but these textboxes are not accessible from code-behind.I have used find control but to no use.This is the code I use to generate textbox.
if (txtnobranches.Text != "")
{
if (Convert.ToInt32(txtnobranches.Text) != 0)
{
div_br.InnerHtml = "<table></table>";
tbl_br.Controls.Clear();
for (int i = 0; i < Convert.ToInt32(txtnobranches.Text); i++)
{
TableRow rowbr = new TableRow();
TableCell cellname = new TableCell();
cellname.Text = "Branch Location " + i.ToString();
rowbr.Cells.Add(cellname);
TableCell cellvalue = new TableCell();
cellvalue.Text = "";
TextBox txt = new TextBox();
txt.Text = "";
txt.ID = "txtbranchloc" + i.ToString();
cellvalue.Controls.Add(txt);
cellvalue.ID = "txtbranchloc" + i.ToString();
rowbr.Cells.Add(cellvalue);
tbl_br.Rows.Add(rowbr);
}
}
}

You can access the element by name using Request.Form["NameOfFormControl"] You will have to make little change in code.
In javascript
txt.Name = "txtbranchloc" + i.ToString();
In Code Behind
Note: Make sure you access it in postback otherwise you get null
if (Page.IsPostBack)
{
string firstTxtVal = Request.Form["txtbranchloc0"].ToString();
string secondTxtVal = Request.Form["txtbranchloc1"].ToString();
}
Using Request.Form Collection

Related

Cannot retrieve value of dynamically created textboxes

Good Day!
I'm creating dynamic textboxes. The number of textboxes that should be created depends on the number of column elements my XML has. I can create the textboxes, my problem is retrieving the value of each textboxes on a button click. Could you help me with this?
Here is my code for creating textboxes:
foreach (XMLClasses.column col in columns.ToList())
{
Literal lt = new Literal();
TextBox txtbox = new TextBox();
Label lbl = new Label();
lt.Text = "<br/>";
lbl.Text = col.title + ":";
lbl.Width = Unit.Pixel(200);
txtbox.ID = "txtbox_" + col.id;
txtbox.Width = Unit.Pixel(200);
Panel1.Controls.Add(lt);
Panel1.Controls.Add(lbl);
Panel1.Controls.Add(txtbox);
}
Here is my code for retrieving:(button_click)
foreach (XMLClasses.column col in columns.ToList())
{
TextBox txt = new TextBox();
Panel pnl = new Panel();
ContentPlaceHolder cph = (ContentPlaceHolder)Master.FindControl("ContentPlaceHolder1");
if(cph != null)
{
pnl = (Panel)cph.FindControl("Panel1");
if (pnl != null)
{
txt = (TextBox)pnl.FindControl("txtbox_" + col.id);
if (txt != null)
{
value = txt.Text;
}
else
{
value = "NOOOO";
}
}
}
}
I am getting the value "NOOOO". Am I missing something??

Retaining Label and Literal controls after post back fails

I am dealing with a very unusual situation through which made me go through the effort of putting up for some answers.
I am trying to regenerate some controls based on the following document,
http://www.codeproject.com/Articles/3684/Retaining-State-for-Dynamically-Created-Controls-i
This approach works TextBox controls but does not seem to respond to Label, Literal, UploadFile or other controls that I'm not aware of.
I do understand this not working for UploadFile due to security reasons, but why not for other non TextBox controls?
The above article suggests that if we maintain the ID of a control, we can retain them after post back but in the following implementation I only get the TextBox responding to this solution. The "Label" and "Literal" controls in this situation are lost after PostBack which is undesirable given that I pretty much follow the recipe line by line.
Can someone please have a look at the following implementation and see where I'm going wrong or if I got the whole concept wrong in a way?
This is a counter to keep track of the number of control sets generated,
protected int NumberOfControls
{
get { return (int)ViewState["NumControls"]; }
set { ViewState["NumControls"] = value; }
}
This is the Page_Load event that fetches the previous slides from the DB on initial page load and regenerates the same page on Postback. AddSlide is a "Placeholder" control where I post other Controls into.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
this.NumberOfControls = PopulateCarouselSettingFields(AddSlides);
}
else
{
this.GenerateControls();
}
}
This is the definition for "PopulateCarouselSettingsFields".
public static int PopulateCarouselSettingFields(PlaceHolder _AddSlides)
{
string result = string.Empty;
int counter = 0;
string CS = ConfigurationManager.ConnectionStrings["someconn"].ConnectionString;
using (SqlConnection conn = new SqlConnection(CS))
{
SqlCommand SqlCmd = new SqlCommand();
conn.Open();
SqlCmd.Connection = conn;
SqlCmd.CommandType = CommandType.StoredProcedure;
SqlCmd.CommandText = "storedprocedure";
SqlDataReader dReader;
dReader = SqlCmd.ExecuteReader();
while (dReader.Read())
{
Literal lit1 = new Literal();
lit1.ID = "Lit1_" + counter;
lit1.Text = "<div class=\"controls controls-row\"><div class=\"span3\">";
_AddSlides.Controls.Add(lit1);
Label CarouselTextLabel = new Label();
CarouselTextLabel.ID = "CarouselTextLabel" + counter;
CarouselTextLabel.Text = "Carousel Text";
CarouselTextLabel.Font.Bold = true;
CarouselTextLabel.CssClass = "control-label";
_AddSlides.Controls.Add(CarouselTextLabel);
TextBox CarouselText = new TextBox();
CarouselText.ID = "CarouselText" + counter;
CarouselText.TextMode = TextBoxMode.MultiLine;
CarouselText.Height = 50;
CarouselText.Text = dReader["CarouselText"].ToString();
_AddSlides.Controls.Add(CarouselText);
Literal Lit2 = new Literal();
Lit5.ID = "Lit2_" + counter;
Lit5.Text = "</div></div></div><br />";
_AddSlides.Controls.Add(Lit2);
counter++;
}
}
return counter;
}
This is supposed to regenerate or re-state all the controls using their IDs upon PostBack called from Page_Load event.
protected void GenerateControls()
{
int count = this.NumberOfControls;
for (int i = 0; i < count; i++)
{
Literal lit1 = new Literal();
lit1.ID = "Lit1_" + i.ToString();
AddSlides.Controls.Add(lit1);
Label CarouselTextLabel = new Label();
CarouselTextLabel.ID = "CarouselTextLabel" + i.ToString();
AddSlides.Controls.Add(CarouselTextLabel);
TextBox CarouselText = new TextBox();
CarouselText.ID = "CarouselText" + i.ToString();
AddSlides.Controls.Add(CarouselText);
Literal Lit2 = new Literal();
Lit2.ID = "Lit2_" + i.ToString();
AddSlides.Controls.Add(Lit2);
}
}
The following piece of code adds new set of controls to the Placeholder "AddSlides" container.
protected void AddMoreSlidesToCarousel(object sender, EventArgs e)
{
Literal lit1 = new Literal();
lit1.ID = "Lit1_" + NumberOfControls.ToString();
lit1.Text = "<div class=\"controls controls-row\"><div class=\"span3\">";
AddSlides.Controls.Add(lit1);
Label CarouselTextLabel = new Label();
CarouselTextLabel.ID = "CarouselTextLabel" + NumberOfControls.ToString();
CarouselTextLabel.Text = "Carousel Text";
CarouselTextLabel.Font.Bold = true;
CarouselTextLabel.CssClass = "control-label";
AddSlides.Controls.Add(CarouselTextLabel);
TextBox CarouselText = new TextBox();
CarouselText.ID = "CarouselText" + NumberOfControls.ToString();
CarouselText.TextMode = TextBoxMode.MultiLine;
CarouselText.Height = 50;
AddSlides.Controls.Add(CarouselText);
Literal Lit2 = new Literal();
Lit2.ID = "Lit2_" + NumberOfControls.ToString();
Lit2.Text = "</div></div></div><br />";
AddSlides.Controls.Add(Lit2);
this.NumberOfControls++;
}
I'm sorry to put it like this, but the article you are relying on is doing it wrong.
Dynamically created controls MUST be created in Page_Init, so that they exist before any ViewState stuff. Also, dynamically controls must be recreated each and every time the Page is initialized, PostBack or not.
ViewState/PostBack do not "retain" controls, only the state of such controls.
Please read this article: ASP.NET Page Life Cycle Overview

Add Ajax CalendarExtender to a dynamic textBox in ASP.NET C#

Is there a way to add Ajax CalendarExtender to a dynamic ASP.NET textbox control? Basically I'm trying to do the following:
protected void Page_Load(object sender, EventArgs e)
{
database.DB myDB = new database.DB();
DataTable myVars = new DataTable();
string myTopicID = (string)Session["myTopicID"];
bool myInvite = (bool)Session["myInvite"];
bool mySig = (bool)Session["mySig"];
string myLogo = (string)Session["myLogo"];
string myImage = (string)Session["myImage"];
string myLanguage = (string)Session["myLanguage"];
myVars = myDB.getVarFields(myTopicID, myLanguage);
AjaxControlToolkit.CalendarExtender calenderDate = new AjaxControlToolkit.CalendarExtender();
for (int i = 0; i < myVars.Rows.Count; i++)
{
Label label = new Label();
TextBox text = new TextBox();
label.Text = Convert.ToString(myVars.Rows[i]["varName"]);
myPlaceHolder.Controls.Add(label);
text.ID = Convert.ToString(myVars.Rows[i]["varName"]);
myPlaceHolder.Controls.Add(new LiteralControl(" "));
myPlaceHolder.Controls.Add(text);
if (Convert.ToString(myVars.Rows[i]["varName"]).Contains("Date:"))
{
calenderDate.TargetControlID = "ContentPlaceHolder1_" + text.ID;
myPlaceHolder.Controls.Add(calenderDate);
}
myPlaceHolder.Controls.Add(new LiteralControl("<br />"));
}
}
The error I get when I run the code above is the following:
The TargetControlID of '' is not valid. A control with ID 'ContentPlaceHolder1_Date:' could not be found.
Which makes sense I suppose since the actual text box does not exist yet. But is there a way around this?
I think ASP.NET will be smart enough to handle it if you just use text.ID, you shouldn't need to add the ContentPlaceHolder1_ prefix.
If that doesn't work, you can use the TextBox' ClientIdMode property to set it to static, then text.ID will definitely work.
The following code worked locally for me:
AjaxControlToolkit.CalendarExtender calenderDate = new AjaxControlToolkit.CalendarExtender();
for (int i = 0; i < 2; i++)
{
Label label = new Label();
TextBox text = new TextBox();
label.Text = Convert.ToString("varName");
ph1.Controls.Add(label);
text.ID = "myId" + i;
ph1.Controls.Add(new LiteralControl(" "));
ph1.Controls.Add(text);
calenderDate.TargetControlID = text.ID;
ph1.Controls.Add(calenderDate);
ph1.Controls.Add(new LiteralControl("<br />"));
}
Only differences I think you may want to investigate: I'm using latest ControlToolkit from Nuget, I'm using a ToolkitScriptManager instead of default ScriptManager. One thing that may be important to you is making sure you make text.ID unique.

Dynamic C# Not rendering on page_load

I have a method which is intended to dynamically generate a series of divs based on the entry of a value from a dropdown list. However, I wish to reuse the same code to generate the tables on the first page_load when a number already exists.
This is where the method is called. It is called GenerateTables and it is called from the Page_Load event:
if (!IsPostBack)
{
AcademicProgramme programme;
if (Request.QueryString["id"] != null)
{
programme = academic.GetAcademicProgramme(Request.QueryString["id"]);
programmeName.Text = programme.Name;
PopulateView(programme);
GenerateTables(programme.Levels);
}
}
And here is the method itself (apologies for the size of the method):
private void GenerateTables(int count)
{
for (int i = 1; i < count + 1; i++)
{
LiteralControl title = new LiteralControl();
LiteralControl close = new LiteralControl();
LiteralControl close2 = new LiteralControl();
String script = "<div class=\"ModuleProgTable\"><h3>Level " + i + "</Modules></h3></br>";
title.Text = script;
AcademicTable.Controls.Add(title);
Panel panel = new Panel();
panel.ID = "Level" + i + "Modules";
PopulatePanel(panel, GetModulesSession(i));
Button a = new Button();
a.ID = "AddModule" + i;
a.Text = "Add Module";
a.Click += (OpenPopup);
AcademicTable.Controls.Add(panel);
AcademicTable.Controls.Add(a);
close.Text = "</div> <!-- Close here -->";
close2.Text = "</div>";
AcademicTable.Controls.Add(close);
}
}
The divs are clearly being populated because if I change the dropdown option then they appear on the PostBack without fail. It's when I try to get them to render on the first page_load that I am having problems.
Any feedback and advice would be greatly appreciated!
Regards,
-Michael

How to dynamically generate html with .ascx?

I have some settings stored in web.config like this:
<add key="Answers" value="radiobutton1,radiobutton2,radiobutton3"/>
Radiobutton1, radiobutton2 and radiobutton3 are radiobutton label values.
In settings.cs I have a function to retrieve value from web.config:
public static string Answers
{
get
{
return System.Configuration.ConfigurationManager.AppSettings["Answers"];
}
}
.ascx file:
<table runat="server" OnPreRender="Radio_PreRender" id="table1" name="table1">
</table>
My ascx.cs file contains this function:
protected void Radio_PreRender(object sender, EventArgs e)
{
if (Settings.Answers != "")
{
int counter = 0;
string a = Settings.Answers;
string[] words = a.Split(',');
StringWriter stringwriter = new StringWriter();
HtmlTextWriter writer = new HtmlTextWriter(stringwriter);
foreach (string word in words)
{
writer.WriteBeginTag("tr");
writer.WriteBeginTag("td");
writer.Write("abc123");
RadioButton rdb1 = new RadioButton();
rdb1.Checked = true;
rdb1.GroupName = "rdbgroup";
rdb1.ID = "radiobutton" + counter;
rdb1.Text = word;
table1.Controls.Add(rdb1 );
writer.WriteEndTag("td");
writer.WriteBeginTag("tr");
table1.Render(writer);
counter++;
}
}
}
In other words, I want to generate a dynamic number of this code inside table1:
<tr>
<td>
// input type="radiobutton" and label go here.
</td>
</tr>
At the moment radiobuttons are not generated, because they can't be direct child elements to a table. If I specify a div instead, radiobuttons are generated, but everything I try to write with HtmlTextWriter is not. I understand that my html has to be rendered by using table1.Render(writer); or something similar, but I can't figure it out.
You can try creating a table and add it to the page you are working on, using the exmaple below you can replace the textbox with a radiobutton
Here is an example:
//Creat the Table and Add it to the Page
Table table = new Table();
table.ID = "Table1";
Page.Form.Controls.Add(table);
// Now iterate through the table and add your controls
for (int i = 0; i < rowsCount; i++)
{
TableRow row = new TableRow();
for (int j = 0; j < colsCount; j++)
{
TableCell cell = new TableCell();
TextBox tb = new TextBox();
// Set a unique ID for each TextBox added
tb.ID = "TextBoxRow_" + i + "Col_" + j;
// Add the control to the TableCell
cell.Controls.Add(tb);
// Add the TableCell to the TableRow
row.Cells.Add(cell);
}
// Add the TableRow to the Table
table.Rows.Add(row);
}
I do this quite often by running the user control through its full asp.net lifetime and getting it as a string:
http://www.diaryofaninja.com/blog/2009/09/14/a-simple-solution-to-viewing-a-preview-of-any-page-in-your-site
This way you can use ASP.Net as a templating engine for anything
Page tempPage = new Page();
UserControl myUserControl = new MyUserControl();
tempPage.Controls.Add(myUserControl);
StringWriter sw = new StringWriter();
HttpContext.Current.Server.Execute(tempPage, sw, false);
if (!String.IsNullOrEmpty(sw.ToString()))
{
return sw.ToString();
}

Categories