how to add textboxes dynamically to a table row in C# - c#

i want to add textboxes dynamically in C# on a button click in a table row. for that i have used the following code.
[1]: http://pastie.org/7702237.
the problem is i am able to adding as many textboxes as I want but they are adding at same location, i mean the table row is not incrementing for every button click instead it is simply replacing the old table row with the new one. Please help me in how to solve this problem.
Thanks in advance
Ganesh

Web-based applications do not maintain state; to this end the state of the table and any variables is not being maintained. With each postback (generated by the button), the table's state reverts to what it was prior to adding a row and then a row is programatically added to it.
In order to achieve your goal, you will need to maintain state somehow. In the following code snippet I am making use of a session:
private List<TableRow> TableRows
{
get
{
if(Session["TableRows"] == null)
Session["TableRows"] = new List<TableRow>();
return (List<TableRow>)Session["TableRows"];
}
}
The following is your code modified to work with the session variable:
TextBox txtE, txtM, txtB;
Button btnAdd, btnDel;
TableRow trow;
TableCell tcell;
foreach(TableRow tr in TableRows)
tblEduDetails.Controls.Add(tr);
int count = TableRows.Count + 1;
txtE = new TextBox();
txtE.ID = "E" + count.ToString();
txtE.Visible = true;
txtE.Text = "E " + count.ToString();
txtE.BorderWidth = 2;
txtE.TextMode = TextBoxMode.SingleLine;
txtE.Height = 30;
txtM = new TextBox();
txtM.ID = "M" + count.ToString();
txtM.Visible = true;
txtM.Text = "M " + count.ToString();
txtM.TextMode = TextBoxMode.SingleLine;
txtM.Height = 30;
txtB = new TextBox();
txtB.ID = "E" + count.ToString();
txtB.Visible = true;
txtB.Text = "B " + count.ToString();
txtB.TextMode = TextBoxMode.SingleLine;
txtB.Height = 30;
btnAdd = new Button();
btnAdd.ID = "A" + count.ToString();
btnDel = new Button();
btnDel.ID = "D" + count.ToString();
trow = new TableRow();
trow.ID = "R" + count.ToString();
trow.BorderWidth = 1;
tcell = new TableCell();
tcell.ID = "E" + count.ToString();
tcell.Controls.Add(txtE);
trow.Controls.Add(tcell);
tcell = new TableCell();
tcell.ID = "B" + count.ToString();
tcell.Controls.Add(txtM);
trow.Controls.Add(tcell);
tcell = new TableCell();
tcell.ID = "M" + count.ToString();
tcell.Controls.Add(txtB);
trow.Controls.Add(tcell);
tblEduDetails.Controls.Add(trow);
TableRows.Add(trow);

Related

Dynamically Create Controls Based Off Data Returned From Query

I am querying access table and with my data that is returned I need to be able to create controls. Now the problem with my code is (I obviously need to learn about loops better than I do) the code executes exactly as it should it does the 1st foreach loop then moves to the 2nd foreach loop. So I have all the labels - then I have all the text boxes. I need it to be a 1 to 1 relationship. So Label Text box. This is my current code that is not producing the desired outcome. Can someone assist me in tweaking this to produce the desired outcome of a 1 to 1 relationship of label to textbox
System.Collections.Hashtable lookup = new System.Collections.Hashtable();
OleDbConnection olecon = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + oName);
olecon.Open();
OleDbCommand command = new OleDbCommand("Query Data Goes Here", olecon);
OleDbCommand command1 = new OleDbCommand("Query Data Goes Here", olecon);
dr = command.ExecuteReader();
while (dr.Read())
{
labelNames.Add(dr[0].ToString());
}
dr.Close();
dr = command1.ExecuteReader();
while (dr.Read())
{
textboxNames.Add(dr[0].ToString());
}
dr.Close();
foreach (string label in labelNames)
{
Label lbl = new Label();
lbl.Name = "lbl_" + index;
lbl.Text = label;
lbl.AutoSize = true;
Form1.Controls.Add(lbl);
index++;
}
foreach (string textbox in textboxNames)
{
TextBox tbx = new TextBox();
tbx.Name = "txt_" + counter;
tbx.AutoSize = true;
Form1.Controls.Add(tbx);
counter++;
}
I don't see any use of textboxNames collection. What you need is, group the two foreach and create label and textbox together and add them to your Form like below
foreach (string label in labelNames)
{
Label lbl = new Label();
lbl.Name = "lbl_" + index;
lbl.Text = label;
lbl.AutoSize = true;
Form1.Controls.Add(lbl);
TextBox tbx = new TextBox();
tbx.Name = "txt_" + index;
tbx.AutoSize = true;
Form1.Controls.Add(tbx);
index++;
}
Rather than doing them as 2 separate foreach loops you could do it in a single for loop, e.g. (assuming labelNames and textboxNames are List<string>):
for (int i = 0; i < labelNames.Count; i++)
{
Label lbl = new Label();
lbl.Name = "lbl_" + labelNames[i];
lbl.Text = labelNames[i];
lbl.AutoSize = true;
Form1.Controls.Add(lbl);
TextBox tbx = new TextBox();
tbx.Name = "txt_" + textboxNames[i];
tbx.AutoSize = true;
Form1.Controls.Add(tbx);
}
Might also be worth checking there are equal numbers of each first as a sanity check:
if (labelNames.Count != textboxNames.Count)
{
//throw exception etc.
}
Replace your two foreach loops with a single for loop that iterates through both lists at the same time.:
for(int i = 0; i < Math.Min(labelNames.Length, textboxNames.Length); i++)
{
Label lbl = new Label();
lbl.Name = "lbl_" + i;
lbl.Text = textboxNames[i];
lbl.AutoSize = true;
Form1.Controls.Add(lbl);
TextBox tbx = new TextBox();
tbx.Name = "txt_" + i;
tbx.AutoSize = true;
Form1.Controls.Add(tbx);
}
The "Math.Min(labelNames.Length, textboxNames.Length)" comparator will make sure the loop stops after whichever list has the fewest entries. I didn't see either of your labelNames or textboxNames collections defined so I'm not sure whether they're arrays or lists or what, so you may need to change "Length" to "Count".

Multiple controls with the same ID 'ddl_Weight' were found. FindControl requires that controls have unique IDs

I am having this error: Multiple controls with the same ID 'ddl_Weight' were found. Find-control requires that controls have unique IDs. thus i am not add to add more objective text-box, drop-down list.
I have to add objectives, drop-down list for weightage and achieved.
private List<DropDownList> inputDropDownList;
private List<DropDownList> inputDropDownList2;
protected void btn_AddObjectives_Click(object sender, EventArgs e)
{
int rowCount = 0;
//initialize a session.
rowCount = Convert.ToInt32(Session["clicks"]);
rowCount++;
//In each button click save the numbers into the session.
Session["clicks"] = rowCount;
//Create the textboxes and labels each time the button is clicked.
for (int i = 0; i < rowCount; i++)
{
TextBox TxtBoxO = new TextBox();
TxtBoxO.TextMode = TextBoxMode.MultiLine;
DropDownList DDLW = new DropDownList();
DropDownList DDLA = new DropDownList();
inputDropDownList = new List<DropDownList>();
inputDropDownList2 = new List<DropDownList>();
Label lblO = new Label();
Label lblW = new Label();
Label lblA = new Label();
TxtBoxO.ID = "TextBoxO" + i.ToString();
DDLW.ID = "DDLW" + i.ToString();
DDLA.ID = "DDLA" + i.ToString();
inputDropDownList.Add(DDLW);
inputDropDownList2.Add(DDLA);
TxtBoxO.Width = 325;
DDLW.Height = 25;
DDLA.Height = 25;
DDLA.ID = "ddl_Achieved";
DDLA.Items.Add("Select");
DDLA.Items.Add("5");
DDLA.Items.Add("10");
DDLA.Items.Add("15");
DDLA.Items.Add("20");
DDLA.Items.Add("25");
DDLA.Items.Add("30");
DDLA.Items.Add("35");
DDLA.Items.Add("40");
DDLA.Items.Add("45");
DDLA.Items.Add("50");
DDLA.Items.Add("55");
DDLA.Items.Add("60");
DDLA.Items.Add("65");
DDLA.Items.Add("70");
DDLA.Items.Add("75");
DDLA.Items.Add("80");
DDLA.Items.Add("85");
DDLA.Items.Add("90");
DDLA.Items.Add("95");
DDLA.Items.Add("100");
DDLW.ID = "ddl_Weight";
DDLW.Items.Add("Select");
DDLW.Items.Add("5");
DDLW.Items.Add("10");
DDLW.Items.Add("15");
DDLW.Items.Add("20");
DDLW.Items.Add("25");
DDLW.Items.Add("30");
DDLW.Items.Add("35");
DDLW.Items.Add("40");
DDLW.Items.Add("45");
DDLW.Items.Add("50");
DDLW.Items.Add("55");
DDLW.Items.Add("60");
DDLW.Items.Add("65");
DDLW.Items.Add("70");
DDLW.Items.Add("75");
DDLW.Items.Add("80");
DDLW.Items.Add("85");
DDLW.Items.Add("90");
DDLW.Items.Add("95");
DDLW.Items.Add("100");
lblO.ID = "LabelO" + i.ToString();
lblW.Text = "LabelW" + i.ToString();
lblA.ID = "LabelA" + i.ToString();
lblO.Text = "Objective " + " " + (i + 1).ToString() + " : ";
lblW.Text = " Weightage" + " " + (i + 1).ToString() + " : ";
lblA.Text = " Achieved " + " " + (i + 1).ToString() + " : ";
//Add the labels and textboxes to the Panel.
Panel1.Controls.Add(lblO);
Panel1.Controls.Add(TxtBoxO);
Panel1.Controls.Add(lblW);
Panel1.Controls.Add(DDLW);
Panel1.Controls.Add(lblA);
Panel1.Controls.Add(DDLA);
}
The error is pretty clear. You're adding multiple controls with the same ID, which is disallowed. Note that you're in a loop:
for (int i = 0; i < rowCount; i++)
We'll assume that rowCount is greater than 1 and that the loop iterates more than once. Within that loop you create controls:
DropDownList DDLW = new DropDownList();
DropDownList DDLA = new DropDownList();
And you assign IDs to them:
DDLW.ID = "DDLW" + i.ToString();
DDLA.ID = "DDLA" + i.ToString();
These IDs are probably unique. But then you overwrite them with ones that are not unique:
DDLA.ID = "ddl_Achieved";
DDLW.ID = "ddl_Weight";
And then you add them to the page:
Panel1.Controls.Add(DDLW);
Panel1.Controls.Add(DDLA);
The purpose of an ID, as its name suggests, is to uniquely identify an object. Just like with id attributes in HTML, if you re-use the same one multiple times in a page then the behavior becomes undefined. The system (in this case wherever you're using FindControl()) expects there to be 0 or 1 elements with any given ID value. You've created more then 1, which is invalid.
You can probably just remove the lines where you set the non-unique IDs and keep the lines where you set the unique ones.

how to collect value from dynamic input and steps in ASP.NET Wizard

I'm trying to create a dynamic survey form based on dynamic data by using ASP.NET Wizard.
I can create dynamic steps and dynamic inputs without any problem. However, the last step, when I submit the form, I won't be able to collect all information from each steps.
Any idea?
Wizard wizard1 = new Wizard();
wizard1.Style.Add("width", "100%");
//wizard1.DisplaySideBar = false;
for (int i = 1; i <= 3; i++)
{
WizardStep step1 = new WizardStep();
step1.ID = "step" + i.ToString();
step1.Title = "step" + i.ToString();
PlaceHolder ph = new PlaceHolder();
ph.ID = "ph" + i.ToString();
ph.Controls.Add(new LiteralControl("<h1>Step." + i.ToString() + "</h1>"));
TextBox tb = new TextBox();
tb.ID = "step" + i.ToString() + "tb";
ph.Controls.Add(tb);
step1.Controls.Add(ph);
wizard1.WizardSteps.Add(step1);
}
wizard1.FinishButtonClick += atWizardCompleted;
wizard_container.Controls.Add(wizard1);
well, I found the solution by using Control.Find().

Add textbox via dynamic imagebutton in a panel

I have a problem I seem to stumble over all the time, I have a Drop Down box and you can select a number which creates x number of textboxes with images buttons its for a survey it the image buttons are used to create "Sub-Answers" so they can have answers to answers so my question is I need to when they hit the image button to create a textbox under the orginal textbox here is the code.
for (Int32 i = 1; i <= NumberOfAnwsers; i++)
{
Literal l1 = new Literal();
l1.Text = "<tr><td>Answer " + i + " text.</td><td>";
TextBox tb = new TextBox();
tb.ID = "TextBoxAnswer" + i;
tb.EnableViewState = false;
tb.Width = 300;
Literal l3 = new Literal();
l3.Text = "</td><td>";
Literal l2 = new Literal();
l2.Text = "</td></tr>";
RadColorPicker CPI = new RadColorPicker();
CPI.PaletteModes = PaletteModes.WebPalette;
CPI.ID = "RadColorPicker" + i;
CPI.ShowIcon = true;
CPI.SelectedColor = System.Drawing.Color.Black;
ImageButton IBVideo = new ImageButton();
IBVideo.ID = "IBVideo" + i;
IBVideo.ImageUrl = "/images/video-icon.jpg";
IBVideo.ToolTip = "Add Video";
IBVideo.Height = 20;
IBVideo.Width = 20;
ImageButton IBAdd = new ImageButton();
IBAdd.ID = "IBAdd" + i;
IBAdd.ImageUrl = "/images/add-icon.png";
IBAdd.ToolTip = "Add Sub-Answers";
//IBAdd.OnClientClick = "showDialog(" + i + ");return false;";
IBAdd.Height = 20;
IBAdd.Width = 20;
//Add Textbox
PanelAnswersToQuestions.Controls.Add(l1);
PanelAnswersToQuestions.Controls.Add(tb);
PanelAnswersToQuestions.Controls.Add(l3);
PanelAnswersToQuestions.Controls.Add(CPI);
PanelAnswersToQuestions.Controls.Add(IBVideo);
PanelAnswersToQuestions.Controls.Add(IBAdd);
PanelAnswersToQuestions.Controls.Add(l2);
}
As you can see I just add controls to the panel, I need to know when that ImageBUtton is hit I can add a Textbox and in this case it could be more then just one textbox to it.
I hope this is clear but for some reason I dont think it is ... sorry.
I have added a radwindow and poping that up sending the Data to the partent via javascript the which created a new problem for me, I can not in javascript seem to find the dynamicly created hiddenfield
function OnClientClose(radWindow) {
var oWnd = $find("<%=RadWindowAddSubAnswer.ClientID%>");
var SubAnswerValues = oWnd.get_contentFrame().contentWindow.document.forms(0).HiddenFieldSubAnswers.value;
alert(SubAnswerValues);
var AnswerID = oWnd.get_contentFrame().contentWindow.document.forms(0).HiddenFieldAnswerID.value;
alert(AnswerID);
var HiddenName = "HiddenFieldSubAnswers" + AnswerID;
alert(HiddenName);
document.getElementById(HiddenName).value = SubAnswerValues;
$get("DivSubAnswers" + AnswerID).innerHTML = SubAnswerValues;
}
The "document.getElementById(HiddenName).value = SubAnswerValues;" seems to never be found, I also tried $get(HiddenName).value = SubAnswerValues; that does not seem to work either both come back as null as for the code behind its:
HiddenField HFSubAnswers = new HiddenField();
HFSubAnswers.ID = "HiddenFieldSubAnswers" + i;
HFSubAnswers.Value = "0";
Im not sure if I got your question right but if you need to dynamically add controls on a Page here is what I can say.
Before adding your control I guess you need to find the control where you need to add it on, Add the control then assign the properties.
PlaceHolder myPlaceHolder = (PlaceHolder)Page.FindControl("PlaceHolder1");
myPlaceHolder.Controls.Add(myButton);
myButton.Text = "Hello World";
For a more detailed expalnation go here http://anyrest.wordpress.com/2010/04/06/dynamically-removing-controls-in-a-parent-page-from-a-child-control/

Controls.remove() method not working in asp.net

I have a web app where the user can create dynamic textboxes at run time. When the user clicks SUBMIT, the form sends data to the database and I want remove the dynamic controls.
The controls are created in the following code:
Table tb = new Table();
tb.ID = "tbl";
for (i = 0; i < myCount; i += 1)
{
TableRow tr = new TableRow();
TextBox txtEmplName = new TextBox();
TextBox txtEmplEmail = new TextBox();
TextBox txtEmplPhone = new TextBox();
TextBox txtEmplPosition = new TextBox();
TextBox txtEmplOfficeID = new TextBox();
txtEmplName.ID = "txtEmplName" + i.ToString();
txtEmplEmail.ID = "txtEmplEmail" + i.ToString();
txtEmplPhone.ID = "txtEmplPhone" + i.ToString();
txtEmplPosition.ID = "txtEmplPosition" + i.ToString();
txtEmplOfficeID.ID = "txtEmplOfficeID" + i.ToString();
tr.Cells.Add(tc);
tb.Rows.Add(tr);
}
Panel1.Controls.Add(tb);
The Remove section of the code is:
Table t = (Table)Page.FindControl("Panel1").FindControl("tbl");
foreach (TableRow tr in t.Rows)
{
for (i = 1; i < myCount; i += 1)
{
string txtEmplName = "txtEmplName" + i;
tr.Controls.Remove(t.FindControl(txtEmplName));
string txtEmplEmail = "txtEmplEmail" + i;
tr.Controls.Remove(t.FindControl(txtEmplEmail));
string txtEmplPhone = "txtEmplPhone" + i;
tr.Controls.Remove(t.FindControl(txtEmplPhone));
string txtEmplPosition = "txtEmplPosition" + i;
tr.Controls.Remove(t.FindControl(txtEmplPosition));
string txtEmplOfficeID = "txtEmplOfficeID" + i;
tr.Controls.Remove(t.FindControl(txtEmplOfficeID));
}
}
However, the textboxes are still visible.
Any ideas?
I would assume that your creating these controls each time the page is loaded or else when your remove code ran on postback it would fail because they would not exist.
So you need to move the create code to NOT happen with every page load by making sure it is wrapped in a if (!IsPostBacK) { ... } statement.
If you do this then you wouldn't need to remove them manually since they are created dynamically and therefore not created by default on each postback.
If you can post where the code that creates the controls is being called from, and the remove as well, I could help you a bit more.
What I ended up doing was instead of deleting the textbox, I deleted the TableRow;

Categories

Resources