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
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??
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
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.
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
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();
}