I have a form with 3 wizard steps, and when i click the button to dynamically add text boxes, that works fine, but when i go to the next step and i click on add to add more text boxes, it automatically adds all the text boxes from the previous steps and then continues to add if i keep click on it.
How do i prevent that from happening.
private List ControlsList
{
get
{
if (ViewState["controls"] == null)
{
ViewState["controls"] = new List();
}
return (List)ViewState["controls"];
}
}
private int NextID
{
get
{
return ControlsList.Count + 1;
}
}
protected override void LoadViewState(object savedState)
{
string section = Wizard1.ActiveStep.ID;
int sectionNum = Wizard1.ActiveStepIndex;
var control = Wizard1.ActiveStep.FindControl("Place" + sectionNum) as PlaceHolder;
base.LoadViewState(savedState);
int count = 0;
foreach (string txtID in ControlsList)
{
if (count == 0)
{
control.Controls.Add(new LiteralControl("<tr>"));
}
TextBox txt = new TextBox();
control.Controls.Add(new LiteralControl("<td>"));
txt.ID = txtID;
control.Controls.Add(txt);
control.Controls.Add(new LiteralControl("</td>"));
count = count + 1;
if (count == 3)
{
control.Controls.Add(new LiteralControl("</tr>"));
count = 0;
}
}
}
protected void AddControlButton_Click(object sender, EventArgs e)
{
string section = Wizard1.ActiveStep.ID;
int sectionNum = Wizard1.ActiveStepIndex;
var control = Wizard1.ActiveStep.FindControl("Place" + sectionNum) as PlaceHolder;
TextBox txt1 = new TextBox();
TextBox txt2 = new TextBox();
TextBox txt3 = new TextBox();
txt1.ID = section.ToString() + "Size" + NextID.ToString();
control.Controls.Add(new LiteralControl("<td>"));
control.Controls.Add(txt1);
control.Controls.Add(new LiteralControl("</td>"));
ControlsList.Add(txt1.ID);
txt2.ID = section.ToString() + "Description" + NextID.ToString();
control.Controls.Add(new LiteralControl("<td>"));
control.Controls.Add(txt2);
control.Controls.Add(new LiteralControl("</td>"));
ControlsList.Add(txt2.ID);
txt3.ID = section.ToString() + "Quantity" + NextID.ToString();
control.Controls.Add(new LiteralControl("<td>"));
control.Controls.Add(txt3);
control.Controls.Add(new LiteralControl("</td></tr>"));
ControlsList.Add(txt3.ID);
}
You are storing all of the dynamic textboxes in ViewState and then the ControlsList property getter is returning the whole list when it is building the textboxes.
My recommendation is to use Session cache instead of ViewState, because it will allow you to differentiate the textbox controls from each of the wizard steps, like this:
Session["WizardStep1"] = listOfTextBoxesFromStep1;
Session["WizardStep2"] = listOfTextBoxesFromStep2;
Session["WizardStep3"] = listOfTextBoxesFromStep3;
Related
hi i'm Cannot get value dynamically created textbox and save into database. plz help
his is code which I have created in this code text box are created but when I will input the value in the text and retrieve the value from dynamically created text box it give error
protected void btnAtt_Click(object sender, EventArgs e)
{
int DPLID = int.Parse(DPLCategory.Text);
var query = (from p in database.tbl_Attributes
where p.ProductTypeId_FK == DPLID
select new
{
p.Attribute_Id,
p.AttributeName,
p.ProductTypeId_FK,
}).ToArray();
for (int i = 0; i < query.Count(); i++)
{
Label lblatt = new Label();
lblatt.ID = query[i].AttributeName;
lblatt.Text = query[i].AttributeName + " : ";
lblatt.CssClass = "control-label";
TextBox txtatt = new TextBox();
txtatt.ID = "txtatt"+i;
txtatt.Attributes.Add("runat", "server");
txtatt.Text = String.Empty;
txtatt.CssClass = "form-control input-sm";
HtmlTextWriterTag.Br.ToString();
Place1.Controls.Add(lblatt);
HtmlTextWriterTag.Br.ToString();
Place1.Controls.Add(txtatt);
HtmlTextWriterTag.Br.ToString();
}
}
protected void lbtnSave_Click(object sender, EventArgs e)
{
int DPLID = int.Parse(DPLCategory.Text);
var query = (from p in database.tbl_Attributes
where p.ProductTypeId_FK == DPLID
select new
{
p.Attribute_Id,
p.AttributeName,
p.ProductTypeId_FK,
}).ToArray();
int LastId = database.tbl_Products.Max(p => p.ProductId);
for (int i = 0; i < query.Count(); i++)
{
database.tbl_ProductValue.Add(new Models.tbl_ProductValue()
{
ProductId_FK = LastId,
AttributeID_FK = query[i].Attribute_Id,
ProductValue = ??,
});
database.SaveChanges();
}
}
plz help me for how to get textbox?
I haven't worked with WebForms in a while but you can access the controls by their IDs like this:
ProductValue = ((TextBox)FindControl("txtatt" + i)).Text;
I have dynamic forms that are build from xml. I can generate the form but I can't get new values from it. I get only the old values that were generated. I would like to update values that are diffrent from old. I think the problem is that I override the new values on page_init with old ones?
This is a dropbox link to my UI for better understanding what I want to achive : https://www.dropbox.com/s/nacs9ohgjxefft9/FormView.png?dl=0#
public sealed class FormViewEditTemplate : IBindableTemplate
{
public FormViewEditTemplate(ListItemType type, mmXMLdoc.mmXMLdoc editXmlForm)
{
templateType = type;
_editXmlForm = editXmlForm;
}
//This method provides a way to insert an instance of text and controls into the specified container.
void ITemplate.InstantiateIn(Control container)
{
tabela = new Table();
tabs = new TabContainer();
tapPanel = new TabPanel();
row = new TableRow();
switch (templateType)
{
case ListItemType.EditItem:
List<XmlElement> Controls = _editXmlForm.getNodCollection("//Tabs");
if (Controls.Count > 0)
{
//pridobimo tabe za formo
foreach (XmlElement ctrlItem in Controls)
{
var ControlsItems = _editXmlForm.getNodCollection("./Controls", "Control", -1, ctrlItem);
tabela = new Table();
tapPanel = new TabPanel();
tapPanel.ID = Guid.NewGuid().ToString();
tapPanel.HeaderText = ctrlItem.GetAttribute("name").ToString();
//pridobimo podatke za formo
//var controls1 = ctrlItem.SelectNodes("//Controls");
foreach (XmlElement ctrl in ControlsItems)
{
string name = _editXmlForm.gStr("./#name", -1, ctrl) + Guid.NewGuid().ToString();
string label = _editXmlForm.gStr("./#label", -1, ctrl);
string width = _editXmlForm.gStr("./#width", -1, ctrl);
string type = _editXmlForm.gStr("./#type", -1, ctrl);
string value = String.Empty;
string helpnote = _editXmlForm.gStr("./HelpNote", -1, ctrl);
string boundfield = _editXmlForm.gStr("./BoundField", -1, ctrl);
row = new TableRow();
TableCell cell = new TableCell();
switch (type)
{
case "TextBox":
//The TemplateField allows for a mix of HTML markup, Web controls, and data-binding syntax.
Label lbl_item = new Label();
lbl_item.Font.Bold = true;
lbl_item.Text = label + ": ";
cell = new TableCell();
cell.Controls.Add(lbl_item);
row.Controls.Add(cell);
TextBox txt_item = new TextBox();
txt_item.ID = boundfield;
txt_item.Text = boundfield;
txt_item.DataBinding += new EventHandler(txt_DataBind);
cell = new TableCell();
cell.Controls.Add(txt_item);
row.Controls.Add(cell);
break;
case "CheckBox":
lbl_item = new Label();
lbl_item.Font.Bold = true;
lbl_item.Text = label + "<br/>";
//The BoundField displays the value of specified DataSource field as text.
BoundField bfield = new BoundField();
bfield.HeaderText = label;
bfield.DataField = boundfield;
break;
default:
break;
}
tabela.Controls.Add(row);
}
tapPanel.Controls.Add(tabela);
tabs.Controls.Add(tapPanel);
}
}
break;
case ListItemType.Footer:
Button saveButton = new Button();
saveButton.Command += new CommandEventHandler(SaveButton_Command);
saveButton.CommandName = "Update";
saveButton.Text = "Save";
saveButton.ID = "EditButton";
container.Controls.Add(saveButton);
break;
}
container.Controls.Add(tabs);
}
IOrderedDictionary IBindableTemplate.ExtractValues(Control container)
{
OrderedDictionary dict = new OrderedDictionary();
List<XmlElement> Controls = _editXmlForm.getNodCollection("//Tabs");
if (Controls.Count > 0)
{
//pridobimo tabe za formo
foreach (XmlElement ctrlItem in Controls)
{
var ControlsItems = _editXmlForm.getNodCollection("./Controls", "Control", -1, ctrlItem);
foreach (XmlElement ctrl in ControlsItems)
{
string type = _editXmlForm.gStr("./#type", -1, ctrl);
string boundfield = _editXmlForm.gStr("./BoundField", -1, ctrl);
switch (type)
{
case "TextBox":
TextBox tb = (TextBox)FindControlRecursive(container, boundfield);
if (tb != null)
dict[boundfield] = tb.Text;
break;
case "Label":
Label lb = (Label)FindControlRecursive(container, boundfield);
if (lb != null)
dict[boundfield] = lb.Text;
break;
case "CheckBox":
CheckBox cb = (CheckBox)FindControlRecursive(container, boundfield);
if (cb != null)
dict[boundfield] = cb.Checked;
break;
case "DropDown":
DropDownList ddl = (DropDownList)FindControlRecursive(container, boundfield);
if (ddl != null)
dict[boundfield] = ddl.SelectedValue;
break;
default:
break;
}
}
}
}
return dict;
}
private Control FindControlRecursive(Control ctlRoot, string sControlId)
{
// if this control is the one we are looking for, break from the recursion
// and return the control.
if (ctlRoot.ID == sControlId)
{
return ctlRoot;
}
// loop the child controls of this parent control and call recursively.
foreach (Control ctl in ctlRoot.Controls)
{
Control ctlFound = FindControlRecursive(ctl, sControlId);
// if we found the control, return it.
if (ctlFound != null)
{
return ctlFound;
}
}
// we never found the control so just return null.
return null;
}
I call this in Page_init
protected void Page_Init(object sender, EventArgs e)
{
FormViewEdit.HeaderTemplate = new FormViewEditTemplate(ListItemType.Header, editXmlForm);
FormViewEdit.EditItemTemplate = new FormViewEditTemplate(ListItemType.EditItem, editXmlForm);
FormViewEdit.FooterTemplate = new FormViewEditTemplate(ListItemType.Footer, editXmlForm);
FormViewEdit.ItemUpdating += new FormViewUpdateEventHandler(FormView1_ItemUpdating);
EditFormView.SelectCommand = "SELECT * FROM " + UniqueTable + " WHERE " + PrimaryKey + "=" + ident;
EditFormView.DataBind();
}
protected void FormView1_ItemUpdating(object sender, FormViewUpdateEventArgs e)
{
//TODO get all new values and make query string.
EditFormView.UpdateCommand = "UPDATE " + UniqueTable + " SET bla_Opis='" + e.NewValues["bla_Opis"] + "' WHERE " + PrimaryKey + "=" + ident;
EditFormView.Update();
EditFormView.DataBind();
}
I found the problem. I used randomly generated id for tap panel therfore I believe the the two way binding didnt work on post back. On every postback I got new id and the old data didnt find control to bind the new values.
tapPanel.ID = Guid.NewGuid().ToString();
I need to generate dynamic textboxes (upto 5-10 ) according to user response. So, what will be the best way to do it as regard performance,speed is concerned.
int n=5;
for (int i=0;i<n;i++)
{
TextBox MyTextBox=new TextBox();
//Assigning the textbox ID name
MyTextBox.ID = "tb" +""+ ViewState["num"] + i;
MyTextBox.Width = 540;
MyTextBox.Height = 60;
MyTextBox.TextMode = TextBoxMode.MultiLine;
this.Controls.Add(MyTextBox);
}
for MVC this link might help u...
http://www.codeproject.com/Articles/434886/Dynamically-adding-controls-on-a-hierarchical-stru
TRy this way
for (int j = 0; j < 10; j++)
{
//Create Dynamic textboxes with required field validator .
TextBox tbChildFirstName = new TextBox();
Label lblChildFirstName = new Label();
lblChildFirstName.ID = "lblChildFirstName" + j;
lblChildFirstName.Text = "Children FirstName";
lblChildFirstName.Width = 200;
lblChildFirstName.SkinID = "Outlabel";
tbChildFirstName.ID = "txtChildFirstName" + j;
tbChildFirstName.Text = "Hi hello";
pnlChildDetail.Controls.Add(lblChildFirstName);
pnlChildDetail.Controls.Add(tbChildFirstName);
RequiredFieldValidator rqf = new RequiredFieldValidator();
rqf.ID = "rqf" + i;
pnlChildDetail.Controls.Add(rqf);
rqf.ControlToValidate = "txtChildFirstName" + j;
rqf.ErrorMessage = "Children FirstName is required";
rqf.Display = ValidatorDisplay.Dynamic;
rqf.ValidationGroup = "EligibilityCheck";
rqf.SetFocusOnError = true;
rqf.Text = "*";
tbChildFirstName.Attributes.Add("runat", "server");
pnlChildDetail.Controls.Add(GetLiteral("<br/>"));
pnlChildDetail.Controls.Add(GetLiteral("<br/>"));
}
public Literal GetLiteral(string text)
{
Literal rv = default(Literal);
rv = new Literal();
rv.Text = text;
return rv;
}
Aspx
<asp:Panel ID="pnlChildDetail" Style="text-align: left; padding-left: 10px" Width="100%"
runat="server">
</asp:Panel>
More details for create dynamic textbox form database data count and how to get dynamic textbox value ?: see my blog
Here is a very helpful link and explained why
link from here
Always add the dynamic control in Page_PreInit()
Always assign ID when loading dynamically
For Example
protected void Page_PreInit(object sender, EventArgs e)
{
Control c= LoadControl("./WebUserControl2.ascx");
i=i+1;
c.ID= i.ToString();
PlaceHolder1.Controls.Add(c);
}
OR
protected void Page_PreInit(object sender, EventArgs e)
{
LinkButton button1 = new LinkButton();
button1.ID = "button1"
button1.Text = "button1"
PlaceHolder1.Controls.Add(button1);
}
my datatable formed as follows
DataTable dtFinalData = new DataTable();
//Adding columns for BR details
dtFinalData.Columns.Add("SupId", typeof(string));
dtFinalData.Columns.Add("SupName", typeof(string));
DateTime dt = DateTime.Today;
int num = DateTime.DaysInMonth(DateTime.Today.Year, DateTime.Today.Month);
//--> adding columns for date part (1-31)
for (int i = 1; i < num + 1; i++)
{
dtFinalData.Columns.Add(i.ToString(), typeof(bool));
}
//<-- adding columns for date part (1-31)
#endregion
#region Fill dtFinalData
//--> Looping each BR from tblBrList
foreach (DataRow BrRow in dtBrList.Rows)
{
DataRow dr = dtFinalData.NewRow();
int SupId = Convert.ToInt32(BrRow[0]); //retrieve BR ID from dtBrList
String supName = BrRow[1].ToString(); //retreive Supervisor name from dtBrList
dr["SupId"] = SupId.ToString();
dr["SupName"] = supName;
for (int i = 1; i < num + 1; i++)
{
DateTime dtRunningDate = new DateTime(2013, 5, i);
//select BR_SUP_CODE,
DataRow[] drAttendance = dtAttendance.Select("BR_SUP_CODE=" + SupId + " AND SMS_DATE=#" + dtRunningDate + "#", string.Empty);
if (drAttendance.Length == 1)
{
//CheckBox chkbx = new CheckBox();
//chkbx.Checked = true;
dr[i.ToString()] = true;
}
else
{
//CheckBox chkbx = new CheckBox();
//chkbx.Checked = false;
dr[i.ToString()] = false;
}
}
dtFinalData.Rows.Add(dr);
}
//<-- Looping each BR from tblBrList
#endregion
GridView1.DataSource = dtFinalData;
GridView1.DataBind();
Now i want to add checked image in place of true and unchecked image in place of false.how to bind grid view dynamically such that in place of disable check box i want to insert two types of image?
Your DataTable part is fine and continue to add the True/False text as per the logic. Now you should handle the GridView part. So, define an event handler for the OnRowDataBound event of GridView.
In this event only, check for the Text property of the cells, and if True/False, clear the cells and add the required image.
<asp:GridView ID="GridView1" OnRowDataBound="GridView1_RowDataBound" ... />
And your event handler will have code as below:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
Image chkImage = new Image();
chkImage.ImageUrl="~/images/Checked.png";
Image UnchkImage = new Image();
UnchkImage.ImageUrl = "~/images/UnChecked.png";
if (e.Row.RowType == DataControlRowType.DataRow)
{
// We will start from 3rd cell because the first 2 cells are
// for SupID & SupName, where we don't need to place images
for (int cellIndex = 2; cellIndex < GridView1.Columns.Count; cells++)
{
// Add Checked Image when cell text is true
if (e.Row.Cells[cellIndex].Text == "true")
{
// clear the cell and add only the image
e.Row.Cells[cellIndex].Controls.Clear();
e.Row.Cells[cellIndex].Controls.Add(chkImage);
}
// Add Unchecked Image when cell text is false
if (e.Row.Cells[cellIndex].Text == "false")
{
// clear the cell and add only the image
e.Row.Cells[cellIndex].Controls.Clear();
e.Row.Cells[cellIndex].Controls.Add(unchkImage);
}
}
}
}
I have a DataGrid of seats available, each with a checkbox to be able to reserve the seat. In the button click event, if the CheckBox is clicked, I am adding the contents of the row to an ArrayList, then adding the ArrayList to a session before redirecting to the confirmation page:
protected void Reserve_Click(object sender, EventArgs e)
{
{
ArrayList seatingArreaList = new ArrayList();
for (int i = 0; i < GridView1.Rows.Count; i++)
{
Guid SeatId = (Guid)GridView1.DataKeys[i][0];
CheckBox cbReserve = (CheckBox)GridView1.Rows[i].FindControl("cbReserve");
Label lblSection = (Label)GridView1.Rows[i].FindControl("lblSection");
Label lblRow = (Label)GridView1.Rows[i].FindControl("lblRow");
Label lblPrice = (Label)GridView1.Rows[i].FindControl("lblPrice");
if (cbReserve.Checked)
{
string tempRowInfo = lblSection.Text + "|" + lblRow.Text + "|" + lblPrice.Text;
seatingArreaList.Add(tempRowInfo);
}
}
// Add the selected seats to a session
Session["Seating"] = seatingArreaList;
}
Response.Redirect("Confirm.aspx?concertId=" + Request.QueryString["concertId"]);
}
On the confirmation page, Id like to split this array up and bind it to another gridview in their individual columns.
On the confirmation page, a session exists that has three columns separated with a pipe, I am struggling to split this up and bind it to a confirmation grid.
Please help!
This would probably be easier to just create a DataTable, then add it to the session variable. Once redirected to the confirmation page just bind GridView to the DataTable pulled from the session variable.
protected void Reserve_Click(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add("Section");
dt.Columns.Add("Row");
dt.Columns.Add("Price");
{
ArrayList seatingArreaList = new ArrayList();
for (int i = 0; i < GridView1.Rows.Count; i++)
{
Guid SeatId = (Guid)GridView1.DataKeys[i][0];
CheckBox cbReserve = (CheckBox)GridView1.Rows[i].FindControl("cbReserve");
Label lblSection = (Label)GridView1.Rows[i].FindControl("lblSection");
Label lblRow = (Label)GridView1.Rows[i].FindControl("lblRow");
Label lblPrice = (Label)GridView1.Rows[i].FindControl("lblPrice");
if (cbReserve.Checked)
{
DataRow dr = dt.NewRow();
dr["Section"] = lblSection.Text;
dr["Row"] = lblRow.Text;
dr["Price"] = lblPrice.Text;
dt.Rows.Add(dr);
}
}
// Add the selected seats to a session
Session["Seating"] = dt;
}
Response.Redirect("Confirm.aspx?concertId=" + Request.QueryString["concertId"]);
}
var q = from dto in seatingArreaList
let z = dto.Split("|".ToCharArray())
select z;
and then just bing q to the grid.