In this article, we will learn how we can create a dynamic form in ASP.NET. Here, dynamic means that we will create the controls at run time.
Introduction
Suppose someone asks you to create a form in ASP.NET. You will say, "It's easy". You will go to an aspx page, drag the controls from toolbox, and the form is ready. But, the person doesn't want you to drag the controls from the toolbox or write in aspx page. Our requirement is to create the controls at run time. So, is that doable? Yes! It is. We can do this in two ways. I will describe here only one way. However, you will also get a hint of the second. So, let's start the code.
First, look into the requirement.
Suppose, we have a requirement where we need to generate the following form fields and their corresponding field types. This, we need to do dynamically at the run time and have to get the values from them. So, our requirement is clear. Always understand the requirement first because without knowing what exactly we need to do, we can't code perfectly.
Requirement
From the above image, we know what field we will have in the form and what type of controls will be needed for those fields. For example, we have Firstname which will take Textbox.
So, let's start doing the code.
In the above image, I created a function according to our need. In this function, I created a data table with three columns (Fieldname, Fieldtype, and Fieldvalue). So now, our frame is ready. Let's fit it into the form. Let's create another function in which we will create the ASP.NET controls which will return the datatable according to the current function.
Dynamic controls function
- public void CreateDynamicControls()
- {
- DataTable dt = new DataTable();
- dt = CustomFields(); //calling the function which describe the fieldname and fieldtype
- if(dt.Rows.Count>0)
- {
- for(Int32 i=0;i<dt.Rows.Count;i++)
- {
- HtmlGenericControl tr = new HtmlGenericControl("tr");
- HtmlGenericControl td = new HtmlGenericControl("td");
- HtmlGenericControl td1 = new HtmlGenericControl("td");
-
- String FieldName=Convert.ToString(dt.Rows[i]["FieldName"]);
- String FieldType = Convert.ToString(dt.Rows[i]["FieldType"]);
- String FieldValue = Convert.ToString(dt.Rows[i]["FieldValue"]);
-
- Label lbcustomename = new Label();
- lbcustomename.ID = "lb" + FieldName;
- lbcustomename.Text = FieldName;
- td.Controls.Add(lbcustomename);
- tr.Controls.Add(td);
-
- if (FieldType.ToLower().Trim()=="textbox")
- {
- TextBox txtcustombox = new TextBox();
- txtcustombox.ID = "txt" + FieldName;
- txtcustombox.Text = FieldValue;
- td1.Controls.Add(txtcustombox);
- }
- else if(FieldType.ToLower().Trim() == "checkbox")
- {
- CheckBox chkbox = new CheckBox();
- chkbox.ID = "chk" + FieldName;
- if(FieldValue=="1")
- {
- chkbox.Checked = true;
- }
- else
- {
- chkbox.Checked = false;
- }
- td1.Controls.Add(chkbox);
- }
- else if (FieldType.ToLower().Trim() == "radiobutton")
- {
- RadioButtonList rbnlst = new RadioButtonList();
- rbnlst.ID = "rbnlst" + FieldName;
- rbnlst.Items.Add(new ListItem("Male","1"));
- rbnlst.Items.Add(new ListItem("Female", "2"));
- if(FieldValue!=String.Empty)
- {
- rbnlst.SelectedValue = FieldValue;
- }
- else
- {
- rbnlst.SelectedValue = "1";
- }
- rbnlst.RepeatDirection =RepeatDirection.Horizontal;
- td1.Controls.Add(rbnlst);
- }
- else if(FieldType.ToLower().Trim() == "dropdownlist")
- {
- DropDownList ddllst = new DropDownList();
- ddllst.ID = "ddl" + FieldName;
- ddllst.Items.Add(new ListItem("Select", "0"));
-
- if(FieldName.ToLower().Trim()=="state")
- {
- ddllst.Items.Add(new ListItem("Alabama", "AL"));
- ddllst.Items.Add(new ListItem("Alaska", "AK"));
- ddllst.Items.Add(new ListItem("Arizona", "AZ"));
- ddllst.Items.Add(new ListItem("California", "CA"));
- ddllst.Items.Add(new ListItem("New York", "NY"));
- }
- else if(FieldName.ToLower().Trim() == "job")
- {
- ddllst.Items.Add(new ListItem("Developer", "1"));
- ddllst.Items.Add(new ListItem("Tester", "2"));
- }
- if (FieldValue != String.Empty)
- {
- ddllst.SelectedValue = FieldValue;
- }
- else
- {
- ddllst.SelectedValue = "0";
- }
- td1.Controls.Add(ddllst);
- }
- tr.Controls.Add(td1);
- placeholder.Controls.Add(tr);
-
-
- if (i==dt.Rows.Count-1)
- {
- tr = new HtmlGenericControl("tr");
- td = new HtmlGenericControl("td");
- Button btnSubmit = new Button();
- btnSubmit.ID = "btnSubmit";
- btnSubmit.Click += btnsubmit_Click;
- btnSubmit.OnClientClick = "return ValidateForm();";
- btnSubmit.Text = "Submit";
- td.Controls.Add(btnSubmit);
- td.Attributes.Add("Colspan", "2");
- td.Attributes.Add("style", "text-align:center;");
- tr.Controls.Add(td);
- placeholder.Controls.Add(tr);
- }
- }
-
- }
-
- }
I created the above function for creating the dynamic controls. We called the function in which we created the data table with fieldname, fieldtype etc. On the basis of that function, we used a loop and got the fieldname and fieldtype one by one and made the check.
For example, we have firstname at first row and have the type textbox, So, we made a check if the type is textbox.
Then, we went into this block and created a control from the class Textbox by giving it attributes, like id value dynamically, nothing static and will add that in the HtmlGenericControl. We created table row and table data, the same way we did for other controls. At last, we checked if the for loop is running for last count. Then, we added the submit button, client click event, and click event. After this, we added it to the Generic control. That's it.
Now, it is the time to run it and see the output. We call this function on Page_Load event, outside ispostback property; because, we need to get the output also. If we call this function within IsPostBack, we can't find the controls on the page.
Page load event
- protected void Page_Load(object sender, EventArgs e)
- {
- CreateDynamicControls();
-
- }
So, hit the F5 button and see the output. It should be similar to the below image.
Our form is ready. If we have taken the controls on aspx page, it will work fine. So, let's check the aspx page.
You can see in the above image of Aspx page, we don't have any form created in this page. We just have a placeholder where we added controls dynamically in the code behind. Now, the form is ready. I have to validate the form also, but we will discuss that in our next article. Here, we will just discuss the dynamic form creation.
So, our form is ready. Let's move to the next requirement, to read the data from these controls. Since we have created these controls dynamically, so we have to read the data from these controls in the same way. I created a new function to read the data from these fields. I tried to make this function as short and as dynamic as I could.
- public void Save()
- {
- DataTable dtFormValues = new DataTable();
- dtFormValues.Columns.Add("FormId", typeof(Int32));
- dtFormValues.Columns.Add("FieldName", typeof(String));
- dtFormValues.Columns.Add("Value", typeof(String));
-
- DataTable dt = new DataTable();
- dt = CustomFields();
- if (dt.Rows.Count > 0)
- {
- for (Int32 i = 0; i < dt.Rows.Count; i++)
- {
- String FieldName = Convert.ToString(dt.Rows[i]["FieldName"]);
- String FieldType = Convert.ToString(dt.Rows[i]["FieldType"]);
- dtFormValues.NewRow();
-
- if (FieldType.ToLower().Trim() == "textbox")
- {
- TextBox txtbox = (TextBox)placeholder.FindControl("txt" + FieldName);
- if (txtbox != null)
- {
- dtFormValues.Rows.Add(ClientId, FieldName, txtbox.Text);
- }
- }
- else if (FieldType.ToLower().Trim() == "checkbox")
- {
- CheckBox checkbox = (CheckBox)placeholder.FindControl("chk" + FieldName);
- if (checkbox != null)
- {
- dtFormValues.Rows.Add(ClientId, FieldName, checkbox.Checked ? "1" : "0");
- }
- }
- else if (FieldType.ToLower().Trim() == "radiobutton")
- {
- RadioButtonList radiobuttonlist = (RadioButtonList)placeholder.FindControl("rbnlst" + FieldName);
- if (radiobuttonlist != null)
- {
- dtFormValues.Rows.Add(ClientId, FieldName, radiobuttonlist.SelectedValue);
- }
- }
- else if (FieldType.ToLower().Trim() == "dropdownlist")
- {
- DropDownList dropdownlist = (DropDownList)placeholder.FindControl("ddl" + FieldName);
- if (dropdownlist != null)
- {
- dtFormValues.Rows.Add(ClientId, FieldName, dropdownlist.SelectedValue);
- }
- }
- }
- }
- }
We created a function in which we call the same function where we have fieldname and fieldtype. Through that, we would find the control in the placeholder with the dynamic id, and create a data table. After finding the control, we added the data in this data table. Now, in this for loop, you can save this data table into your database. I haven't done it yet but will show you how the data I put in the form gets added in this data table.
Form filled
Then, hitting on the submit button will invoke the submit click event on server side in which we are calling the save method.
Save button event
Now, enable break point in this Save function and see after the for loop result in the data table if you get the correct data or not.
You can see in the above image, when we fill the form and hit the submit button, the values are stored in the data table. You can save these values into the database. I haven't saved the values in the database, just created the dynamic form to show you how we can get the values from these controls. That's it for now.