I have a C# web application and I building an edit screen but I dont know how many records are in the table, so I need to dynamically build the text box and populate it with data... below is the sample loop that I use to retrieve the data...I'm just doing
a response.write for now, but I need to load the values into a text box, then if the user submits this, I need to update the table.
I haven't really ever created input boxes on the fly before...
My examaple is just writing the results to a screen, but I need them loaded into a text box, then allow the user to review the values and potentially update the values...
The response.write was just to help explain the 3 values (for one record) I need to have the user update.
So I need to load the values in a text box, then on postback, submit the values/changes back to the database.
Dynamic webforms controls is not the simplest thing in the world so hopefully I can get you started and with some practice you'll get it.
The main thing you need to always remember: Dynamic controls must be recreated every time the page is posted back. Always. They must also be recreated in the same order or the ViewState won't match.
Add a placeholder where you want your dynamic controls in the page.
Save the DataTable object in ViewState. You'll need it to re-create the controls. Or at least enough information to recreate the exact number of controls in the correct order. ViewState will take care of populating the control's data properties like
Text.
Make sure you recreate the controls on every postback.
Now create a function that inserts them using the given DataTable:
private void CreateDynControls(DataTable dt)
{
foreach (DataRow dr in dt.Rows)
{
TextBox tb = new TextBox();
tb.Text = dr["description"].ToString();
//Now add the textbox to the placeholder.
phRecords.Controls.Add(tb);
//ETC. Add the remaining controls for the other table fields.
//Finally and optionally add a literal control for a line break or horizontal separator here.
}
}
Now make sure the DataTable is stored in ViewState, or at least the total number of rows if that's all you need to recreate the controls. The choice affects the type of parameter (and count of them) in the previously shown function. Right now I'm making the example expecting to serialize into ViewState the entire DataTable.
private DataTable DataSource
{
get
{
object val = ViewState["DataSource"];
if (val == null) return null;
return val as DataTable;
}
set
{
ViewState["DataSource"] = value;
}
}
And finally make sure you always recreate the controls and always serialize the data source.
private void Page_Load(object sender, EventArgs e)
{
DataTable dt = DataSource;
if (!IsPostBack) dt = ObtainTheDataFromYourFavoriteDataSource(); //Usually data read from a database.
//Now create the dynamic controls.
CreateDynControls(dt);
}
Thanks for your post and it starts to kind of make sense a little bit, but was hoping for a little more explanation on ths some points. Im not really sure about this line of code here...what does this mean? if(!IsPostBack) dt
=ObtainTheDataFromYourFavoriteDataSource();//Usually data read from a database.
Also, where and how do I incorporate the looping checking for submission of the form so this data gets saved back to the database?
I am building a page based on your example, but not sure how to add the items I listed above.
That line represents a "placeholder" for your code to retrieve the data from the database. I don't know how you are doing it right now, so I merely represent that unknown code like that. You must change that with your own method of obtaining and filling
the DataTable object.
I suppose you have a Save button, right? If yes, you simply save the data in the click event of such Save button. Right now the CreateDynControls() function I wrote doesn't give the textboxes an ID, but you can modify the function to add meaningfuld ID's
to the textboxes so you can use FindControl() easily in the Click event of the Save button.
private string GetDynControlID(int rid, string colName)
{
return String.Format("dyntb_r{0}_{1}", rid, colName);
}
private void CreateDynControls(DataTable dt)
{
int rid = 0;
foreach (DataRow dr in dt.Rows)
{
TextBox tb = new TextBox();
tb.ID = GetDynControlID(rid, "description");
tb.Text = dr["description"].ToString();
//Now add the textbox to the placeholder.
phRecords.Controls.Add(tb);
//ETC. Add the remaining controls for the other table fields.
//Finally and optionally add a literal control for a line break or horizontal separator here.
rid++;
}
}
Now you have a predictable ID based on row number and column name, and a function that generates the said ID. Now run a foreach in the Save button's Click event:
protected void btnSave_Click(object sender, EventArgs e)
{
DataTable dt = DataSource;
int rid = 0;
foreach(DataRow dr in dt.Rows)
{
TextBox tb = FindControl(GetDynControlID(rid, "description")) as TextBox;
dr["description"] = tb.Text;
//ETC. Repeat for each column.
...
rid++;
}
//At this point the DataTable is updated with the input values. Save to DB.
...
}
Thanks, not sure what its used for? - Maybe I am missing something?
I updated the CreateDynControls function to pull data from using a stored procedure - see below.
Database db = DatabaseFactory.CreateDatabase("ConnectionString");
string sqlCommand = "stp_directory_getBusinessContact";
DbCommand dbCommand = db.GetStoredProcCommand(sqlCommand);
//db.AddInParameter(dbCommand, "business_id", DbType.Int32, 1644);
db.AddInParameter(dbCommand, "business_id", DbType.Int32, 2153);
DataSet ds = db.ExecuteDataSet(dbCommand);
int rid = 0;
foreach (DataRow dr in ds.Tables[0].Rows)
{
TextBox tb = new TextBox();
tb.ID = GetDynControlID(rid, "first_name");
tb.Text = dr["first_name"].ToString();
//Now add the textbox to the placeholder.
phRecords.Controls.Add(tb);
phRecords.Controls.Add(new LiteralControl("<br/>"));
//ETC. Add the remaining controls for the other table fields.
//Finally and optionally add a literal control for a line break or horizontal separator here.
rid++;
}
Incorrect. You only need to pull data from the database on first load of page. On subsequent postbacks you MUST get it from ViewState. That's why I created the DataSource property. That data-loading code MUST go in a separate function. That's the placeholder
code I told you about. Remember this line in my first post where I show a Page_Load event handler?
if (!IsPostBack) dt = ObtainTheDataFromYourFavoriteDataSource(); //Usually data read from a database.
That's the function you need to create with that code for loading data from a stored procedure.
carloslobos
0 Points
34 Posts
Creating textboxes dynamically based on records in table
Feb 20, 2013 07:57 PM|LINK
I have a C# web application and I building an edit screen but I dont know how many records are in the table, so I need to dynamically build the text box and populate it with data... below is the sample loop that I use to retrieve the data...I'm just doing a response.write for now, but I need to load the values into a text box, then if the user submits this, I need to update the table.
I haven't really ever created input boxes on the fly before...
foreach (DataRow dr1 in ds.Tables[0].Rows)
{description"].ToString()); .ToString()); ].ToString());
Response.Write(dr1["
Response.Write(dr1["opens_at"]
Response.Write(dr1["closes_at"
}
My examaple is just writing the results to a screen, but I need them loaded into a text box, then allow the user to review the values and potentially update the values...
The response.write was just to help explain the 3 values (for one record) I need to have the user update.
So I need to load the values in a text box, then on postback, submit the values/changes back to the database.
Please advise of any sample code or references
webJose
Member
730 Points
186 Posts
Re: Creating textboxes dynamically based on records in table
Feb 21, 2013 02:09 AM|LINK
Dynamic webforms controls is not the simplest thing in the world so hopefully I can get you started and with some practice you'll get it.
The main thing you need to always remember: Dynamic controls must be recreated every time the page is posted back. Always. They must also be recreated in the same order or the ViewState won't match.
So add a placeholder:
Now create a function that inserts them using the given DataTable:
private void CreateDynControls(DataTable dt) { foreach (DataRow dr in dt.Rows) { TextBox tb = new TextBox(); tb.Text = dr["description"].ToString(); //Now add the textbox to the placeholder. phRecords.Controls.Add(tb); //ETC. Add the remaining controls for the other table fields. //Finally and optionally add a literal control for a line break or horizontal separator here. } }Now make sure the DataTable is stored in ViewState, or at least the total number of rows if that's all you need to recreate the controls. The choice affects the type of parameter (and count of them) in the previously shown function. Right now I'm making the example expecting to serialize into ViewState the entire DataTable.
private DataTable DataSource { get { object val = ViewState["DataSource"]; if (val == null) return null; return val as DataTable; } set { ViewState["DataSource"] = value; } }And finally make sure you always recreate the controls and always serialize the data source.
private void Page_Load(object sender, EventArgs e) { DataTable dt = DataSource; if (!IsPostBack) dt = ObtainTheDataFromYourFavoriteDataSource(); //Usually data read from a database. //Now create the dynamic controls. CreateDynControls(dt); }carloslobos
0 Points
34 Posts
Re: Creating textboxes dynamically based on records in table
Feb 21, 2013 03:51 PM|LINK
Thanks for your post and it starts to kind of make sense a little bit, but was hoping for a little more explanation on ths some points.
Im not really sure about this line of code here...what does this mean?
if (!IsPostBack) dt = ObtainTheDataFromYourFavoriteDataSource(); //Usually data read from a database.
Also, where and how do I incorporate the looping checking for submission of the form so this data gets saved back to the database?
I am building a page based on your example, but not sure how to add the items I listed above.
Thanks for all your help...
webJose
Member
730 Points
186 Posts
Re: Creating textboxes dynamically based on records in table
Feb 21, 2013 03:57 PM|LINK
That line represents a "placeholder" for your code to retrieve the data from the database. I don't know how you are doing it right now, so I merely represent that unknown code like that. You must change that with your own method of obtaining and filling the DataTable object.
I suppose you have a Save button, right? If yes, you simply save the data in the click event of such Save button. Right now the CreateDynControls() function I wrote doesn't give the textboxes an ID, but you can modify the function to add meaningfuld ID's to the textboxes so you can use FindControl() easily in the Click event of the Save button.
carloslobos
0 Points
34 Posts
Re: Creating textboxes dynamically based on records in table
Feb 21, 2013 03:59 PM|LINK
Ok I do have the fields being loaded correctly with data...but how do I save the data back...below is my rendered code
No very easy to understand as far as 'saving the data back to the table?
Could you provide some assistance with the FindControl() idea...thanks.
<input name="ctl02" type="text" value="Brian" /><br/>
<input name="ctl03" type="text" value="Les " /><br/>
<input name="ctl04" type="text" value="Paul " /><br/>
webJose
Member
730 Points
186 Posts
Re: Creating textboxes dynamically based on records in table
Feb 21, 2013 04:14 PM|LINK
private string GetDynControlID(int rid, string colName) { return String.Format("dyntb_r{0}_{1}", rid, colName); } private void CreateDynControls(DataTable dt) { int rid = 0; foreach (DataRow dr in dt.Rows) { TextBox tb = new TextBox(); tb.ID = GetDynControlID(rid, "description"); tb.Text = dr["description"].ToString(); //Now add the textbox to the placeholder. phRecords.Controls.Add(tb); //ETC. Add the remaining controls for the other table fields. //Finally and optionally add a literal control for a line break or horizontal separator here. rid++; } }Now you have a predictable ID based on row number and column name, and a function that generates the said ID. Now run a foreach in the Save button's Click event:
protected void btnSave_Click(object sender, EventArgs e) { DataTable dt = DataSource; int rid = 0; foreach(DataRow dr in dt.Rows) { TextBox tb = FindControl(GetDynControlID(rid, "description")) as TextBox; dr["description"] = tb.Text; //ETC. Repeat for each column. ... rid++; } //At this point the DataTable is updated with the input values. Save to DB. ... }carloslobos
0 Points
34 Posts
Re: Creating textboxes dynamically based on records in table
Feb 21, 2013 05:22 PM|LINK
Thanks for your input, everything makes sense, except for the btnSave_Click function.
I'm not sure I understand what is happening here...
I dont quite follow the idea behind the loop and the DataTable dt = DataSource, where is this coming from.
Sorry if this is a silly question.
webJose
Member
730 Points
186 Posts
Re: Creating textboxes dynamically based on records in table
Feb 21, 2013 05:23 PM|LINK
See my first post with code. There's a property I called DataSource. That's that.
carloslobos
0 Points
34 Posts
Re: Creating textboxes dynamically based on records in table
Feb 21, 2013 05:35 PM|LINK
Thanks, not sure what its used for? - Maybe I am missing something?
I updated the CreateDynControls function to pull data from using a stored procedure - see below.
Database db = DatabaseFactory.CreateDatabase("ConnectionString"); string sqlCommand = "stp_directory_getBusinessContact"; DbCommand dbCommand = db.GetStoredProcCommand(sqlCommand); //db.AddInParameter(dbCommand, "business_id", DbType.Int32, 1644); db.AddInParameter(dbCommand, "business_id", DbType.Int32, 2153); DataSet ds = db.ExecuteDataSet(dbCommand); int rid = 0; foreach (DataRow dr in ds.Tables[0].Rows) { TextBox tb = new TextBox(); tb.ID = GetDynControlID(rid, "first_name"); tb.Text = dr["first_name"].ToString(); //Now add the textbox to the placeholder. phRecords.Controls.Add(tb); phRecords.Controls.Add(new LiteralControl("<br/>")); //ETC. Add the remaining controls for the other table fields. //Finally and optionally add a literal control for a line break or horizontal separator here. rid++; }webJose
Member
730 Points
186 Posts
Re: Creating textboxes dynamically based on records in table
Feb 21, 2013 05:39 PM|LINK
Incorrect. You only need to pull data from the database on first load of page. On subsequent postbacks you MUST get it from ViewState. That's why I created the DataSource property. That data-loading code MUST go in a separate function. That's the placeholder code I told you about. Remember this line in my first post where I show a Page_Load event handler?
That's the function you need to create with that code for loading data from a stored procedure.