add text box dynamically and capture data on button click - c#

I am adding text boxes dynamically and trying to capture data entered in text box on button click. but what is happening is , though I entered the data in the text box, when I clicked the button, the page is getting loaded and the control is getting created again. As a result , I am loosing the data in the text box. Can you tell me how can I capture this data entered to the dynamically created text boxes.
My sample code is as follows:
protected void Page_Load(object sender, EventArgs e)
{
Table tblTextboxes = new Table();
for(int i=0;i<10;i++)
{
TableRow tr=new TableRow();
TableCell tc=new TableCell();
TextBox tb=new TextBox();
tb.ID=i.ToString();
tc.Controls.Add(tb);
tr.Cells.Add(tc);
TableCell tc1=new TableCell();
LinkButton lnk=new LinkButton();
lnk.ID=i.ToString()+tb.Text+"lnk";
lnk.Text = "Show";
lnk.Click+=new EventHandler(lnk_Click);
tc1.Controls.Add(lnk);
tr.Cells.Add(tc1);
tblTextboxes.Rows.Add(tr);
}
placeTest.Controls.Add(tblTextboxes);
}
void lnk_Click(object sender, EventArgs e)
{
LinkButton lnk=sender as LinkButton;
Label lbl=new Label();
lbl.Text="The text is"+lnk.ID;
placeTest.Controls.Add(lbl);
}

LinkButton ID is changed every time you enter text into TextBox and post back.
One thing you want to make sure when creating control dynamically is - you want to recreate them with same ID when post back.
Updated Solution (to retrieve text from TextBox)
protected void Page_Load(object sender, EventArgs e)
{
var tblTextboxes = new Table();
for (int i = 0; i < 10; i++)
{
var tr = new TableRow();
var tc = new TableCell();
var tb = new TextBox {ID = i.ToString()};
tc.Controls.Add(tb);
tr.Cells.Add(tc);
var tc1 = new TableCell();
// This is a fix for - lnk.ID=i.ToString()+tb.Text+"lnk";
var lnk = new LinkButton {ID = i + "lnk", Text = "Show"};
lnk.Click += lnk_Click;
tc1.Controls.Add(lnk);
tr.Cells.Add(tc1);
tblTextboxes.Rows.Add(tr);
}
placeTest.Controls.Add(tblTextboxes);
}
void lnk_Click(object sender, EventArgs e)
{
var lnk = sender as LinkButton;
var lbl = new Label();
lbl.Text = "LinkButton ID: " + lnk.ID;
// Get number value from string
string id = Regex.Replace(lnk.ID, #"[^\d]", "");
// Retrieves a TextBox control by ID
var control = FindControlRecursive(Page, id);
if (control != null)
{
var textbox = control as TextBox;
lbl.Text += "; TextBox Text: " + textbox.Text;
}
placeTest.Controls.Add(lbl);
}
public Control FindControlRecursive(Control root, string id)
{
if (root.ID == id)
return root;
return root.Controls.Cast<Control>()
.Select(c => FindControlRecursive(c, id))
.FirstOrDefault(c => c != null);
}

Based on the MSDN, I would recommend to use Page class's Init event. Look in to the title View State and Dynamically Added Controls for explanation. Also, I would recommend to add dynamic controls at the end of all existing controls. Create table first, and then add the text boxes.
I modified your code. It worked for me. I used VS 2012, .Net 4.5
protected void Page_Load(object sender, EventArgs e)
{
Response.Write(DateTime.Now.ToString());
}
protected void Page_Init(object sender, EventArgs e)
{
Table tblTextboxes = new Table();
for (int i = 0; i < 10; i++)
{
TableRow tr = new TableRow();
TableCell tc = new TableCell();
TextBox tb = new TextBox();
tb.ID = i.ToString();
tc.Controls.Add(tb);
tr.Cells.Add(tc);
//TableCell tc1 = new TableCell();
//LinkButton lnk = new LinkButton();
//lnk.ID = i.ToString() + tb.Text + "lnk";
//lnk.Text = "Show";
//lnk.Click += new EventHandler(lnk_Click);
//tc1.Controls.Add(lnk);
//tr.Cells.Add(tc1);
tblTextboxes.Rows.Add(tr);
}
placeTest.Controls.Add(tblTextboxes);
}
protected void Button1_Click(object sender, EventArgs e)
{
}

Related

Creating Dynamic controls when changing the dropdown list items. - c#

I have to show a ModalPopupExtender when changing the items of dropdownlist. The controls showing inside the ModalPopupExtender are dynamic controls including buttons. To fire the button click event for this dynamic buttons, I have introduced view state in the code.
Now when changing the item of dropdown list, ModalPopupExtender will come for first item correctly. And then, when changing the item, it throws error like below. How can I clear the previous dynamic controls when changing the dropdown list items?
Multiple controls with the same ID 'lbl1' were found. FindControl requires that controls have unique IDs.
protected async void Page_Load(object sender, EventArgs e)
{
if (ddl_Forms.SelectedItem.Value != "-1")
if (ViewState["viewstate_dynamic"] != null)
CreateDynamicControls();
}
protected void ddl_Forms_SelectedIndexChanged(object sender, EventArgs e)
{
CreateDynamicControls();
}
private async void CreateDynamicControls()
{
if (ddl_Forms.SelectedItem.Value != "-1")
{
url = baseUrl + "GetStructureJson?form_id=" + ddl_Forms.SelectedItem.Value.ToString();
using (var objClient = new HttpClient())
{
objClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + objVariables.login_token);
using (var response = await objClient.GetAsync(url))
{
if ((int)response.StatusCode == 401)//unauthorised or token expired
{
Response.Redirect("Default.aspx");
}
if (response.IsSuccessStatusCode)
{
var jsonString = await response.Content.ReadAsStringAsync();
JavaScriptSerializer j = new JavaScriptSerializer();
object a = j.Deserialize(jsonString, typeof(object));
dict_values = JsonConvert.DeserializeObject<Dictionary<string, string>>(a.ToString());
int flag = 0;
foreach (KeyValuePair<string, string> entry in dict_values)
{
flag++;
TableRow row = new TableRow();
TableCell cell1 = new TableCell();
Label lbl = new Label();
lbl.ID = "lbl" + flag;
lbl.Text = entry.Key;
cell1.Controls.Add(lbl);
row.Cells.Add(cell1);
tbl_forms.Rows.Add(row);
}
TableRow row3 = new TableRow();
TableCell cell3 = new TableCell();
Button btn = new Button();
btn.ID = "btnSubmit2";
btn.Text = "Submit";
btn.Click += new System.EventHandler(this.ButtonsubmitForm2_Click);
btn.CssClass = "button_green";
cell3.Controls.Add(btn);
Button btn2 = new Button();
btn2.ID = "btnCancel2";
btn2.Text = "Cancel";
btn2.Click += new EventHandler(btn_Cancel_allocate2_Click);
btn2.Style.Add("margin-left", "20px");
cell3.Controls.Add(btn2);
row3.Cells.Add(cell3);
tbl_forms.Rows.Add(row3);
**ViewState.Add("viewstate_dynamic", true);**
mp2.Show(); //modalpopuextender
}
}
}
}
}

How to retrieve data from tablecell ASP.NET

When I load the page I send the number of rows the table will have:
protected void Page_Load(object sender, EventArgs e)
{
string numFilas = Request.QueryString["filas"];
tblAdd.Visible = true;
for (int i = 0; i < int.Parse(numFilas); i++)
{
TableRow NewRow1 = new TableRow();
TableCell NewCell1 = new TableCell();
TableCell NewCell2 = new TableCell();
TextBox txtBox1 = new TextBox();
txtBox1.Width = 200;
TextBox txtBox2 = new TextBox();
txtBox2.Width = 200;
// adding lebel into cell
NewCell1.Controls.Add(txtBox1);
NewCell2.Controls.Add(txtBox2);
// adding cells to row
NewRow1.Cells.Add(NewCell1);
NewRow1.Cells.Add(NewCell2);
tblAdd.Rows.Add(NewRow1);
}
}
now when I click submit I'd like to retrieve the data of the textbox inside the table, what I've been capable of is this:
public void submit(Object sender, EventArgs e)
{
for (Int32 i = 0; i < tblAdd.Rows.Count; i++)
{
TableRow dr = tblAdd.Rows[i];
TableCell hhh = dr.Cells[0];
String textCell = hhh.Text();
}
}
However, the text in the cells is empty because the text the user writes is IN the textbox, which I don't know how to get it.
Try this
While creating your text boxes add an ID
E.g.
txtBox1.ID = "txtBox1";
Then you can easily find this TextBox control from the current Cell's Controls collection as follows.
string textCell = ((TextBox)dr.Cells[0].FindControl("txtBox1")).Text;
Hope you understood what I'm trying to say. Basically, you need to find your control in the Cell.
Vote and accept the answer if it solved your issue.
Cheers!

Create buttons dynamically in asp.net page and fire click event to all buttons

I want to create buttons dynamically in asp.net page and wrote the code. Buttons created dynamically through below code.
List<string> category = new List<string>();
category.Add("AAA");
category.Add("BBB");
category.Add("CCC");
category.Add("DDD");
category.Add("EEE");
for (int i = 0; i < category.Count; i++)
{
TableRow tr = new TableRow();
TableCell cl = new TableCell();
TableCell cl2 = new TableCell();
Button button = new Button();
button.ID = "raid" + i;
button.Text = category[i];
button.Click +=button_Click;
private void button_Click(object sender, EventArgs e)
{
Response.Write(sender.ToString());
}
Now I want to add click events for all buttons and want to get which button click event has been fired.
Any idea?
Response.Write(sender.ToString()); OR Response.Write(e.ToString()); returns common properties.
You can use CommandArgument property.
button.ID = "raid" + i;
button.Text = category[i];
button.Click +=button_Click;
button.CommandArgument +=category[i];
private void button_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
string category = btn.CommandArgument;
}

Find Control() not working

I have created 5 text boxes in a button click event and i have to get the values in the text boxes when the dynamically generated button is clicked.
protected void Button1_Click(object sender, EventArgs e)
{
for(int i=0;i<5;i++)
{
HtmlGenericControl tr = new HtmlGenericControl("tr");
HtmlGenericControl td = new HtmlGenericControl("td");
HtmlGenericControl tdbtn = new HtmlGenericControl("td");
TextBox txt=new TextBox();
txt.ID="txt_"+i.ToString();
td.Controls.Add(txt);
Button btn=new Button();
btn.ID="btn_"+i.ToString();
btn.Click+=new EventHandler(btnpay_Click);
btn.Text="Pay";
tdbtn.Controls.Add(btn);
tr.Controls.Add(td);
tr.Controls.Add(tdbtn);
PlaceHolder1.Controls.Add(tr);
}
}
But i couldn't get the Values in the text boxes at btnpay_Click
protected void btnpay_Click(object sender, EventArgs e)
{
Button btn = new Button();
btn = sender as Button;
string[] splitvaues = btn.ID.Split('_');
string identity = splitvaues[1];
TextBox txt = new TextBox();
txt =PlaceHolder1.FindControl("txt_" + identity) as TextBox;
}
Can Anybody tell me a way to solve this problem?
Your problem is that FindControl doesn't recurse down the control tree. It only searches the controls directly in the ControlCollection of the container.
This method will find a control only if the control is directly
contained by the specified container; that is, the method does not
search throughout a hierarchy of controls within controls.
You need to write a recursive FindControl. Something like:
public static Control FindControlRecursive(this Control control, string id)
{
if (control == null || control.ID == id) return control;
foreach (var c in control.Controls)
{
var found = c.FindControlRecursive(id);
if (found != null) return found;
}
return null;
}
try this code.....
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
createcontrol();
}
}
private void createcontrol()
{
for (int i = 0; i < 5; i++)
{
HtmlGenericControl tr = new HtmlGenericControl("tr");
HtmlGenericControl td = new HtmlGenericControl("td");
HtmlGenericControl tdbtn = new HtmlGenericControl("td");
TextBox txt = new TextBox();
txt.ID = "txt_" + i.ToString();
td.Controls.Add(txt);
Button btn = new Button();
btn.ID = "btn_" + i.ToString();
btn.Click += new EventHandler(btnpay_Click);
btn.Text = "Pay";
tdbtn.Controls.Add(btn);
tr.Controls.Add(td);
tr.Controls.Add(tdbtn);
plh1.Controls.Add(tr);
}
}
protected void btnpay_Click(object sender, EventArgs e)
{
Button btn = new Button();
btn = sender as Button;
string[] splitvaues = btn.ID.Split('_');
string identity = splitvaues[1].ToString();
TextBox txt = new TextBox();
txt = plh1.FindControl("txt_" + identity) as TextBox;
string q = txt.Text;
}
protected void Button1_Click(object sender, EventArgs e)
{
createcontrol();
}

dynamically created list of link buttons, link buttons not posting back

Hi I am dynamically creating link buttons in a 'ul li' list. I am then trying to tie each link button to a click event where i set a label to the text of the link button clicked. however the event that should fire doesnt get fired?
if (!Page.IsPostBack)
{
int listItemIds = 0;
foreach (Node productcolour in product.Children)
{
HtmlGenericControl li = new HtmlGenericControl("li");
LinkButton lnk = new LinkButton();
lnk.ID = "lnk" + listItemIds;
lnk.Text = productcolour.Name;
lnk.Click += new EventHandler(Clicked);
//lnk.Command += new CommandEventHandler(lnkColourAlternative_Click);
//lnk.Click
li.Controls.Add(lnk);
ul1.Controls.Add(li);
listItemIds++;
}
}
the above is wrapped within a if(!page.ispostback) and the label text is never set anywhere else.
heres to the event
protected void Clicked(object sender, EventArgs e)
{
LinkButton lno = sender as LinkButton;
litSelectedColour.Text = lno.Text;
}
Code must run on each postback:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
int listItemIds = 1;
for (int i = 0; i < 10; i++)
{
var li = new HtmlGenericControl("li");
var lnk = new LinkButton();
lnk.ID = "lnk" + listItemIds;
lnk.Text = "text" + i;
lnk.Click += Clicked;
//lnk.Command += new CommandEventHandler(lnkColourAlternative_Click);
//lnk.Click
li.Controls.Add(lnk);
ul1.Controls.Add(li);
listItemIds++;
}
}
private void Clicked(object sender, EventArgs e)
{
var btn = sender as LinkButton;
btn.Text = "Clicked";
}
Do this sort of thing OnInit and make sure you recreate the controls on every postback.
See this KB article for an example - a bit outdated but the methodology is still the same.

Categories

Resources