What is the best way to store controls and dynamically add controls to an existing form

I have a general form that shows the default controls. I am trying to create a queue of forms where, if we have a client who wants to get additional data, I would like to save the asp.net controls necessary to collect data for each client and dynamically load them together with the default form.

Does anyone know or direct me to an architecture / solution to implement this [store forms and load and dynamically add them to an existing form and extract data from them).

My initial thought was to use an xml file for each client that wants to get more data than the existing static form data, and load that xml based on the file name (which matches the client name) and add it to the content holder, and then cycle through the page on the button click to get data from these dynamic fields.

+1
source share
3 answers

This XML file may work for this example:

<?xml version="1.0"?> <!-- Custom fields per tenant/form --> <Customers> <IBM> <Employee> <Field Id="FirstName" Label="First name" /> <Field Id="LastName" Label="Last name" /> </Employee> </IBM> </Customers> 

Start by setting up the XmlDataSource on the page. You can change it to SqlDataSource if you plan to store the form definition in the database with the client, and not in XML files.

 <asp:XmlDataSource ID="CustomFields" runat="sever" DataFile="~/App_Data/CustomFields.config" XPath="//Customers/IBM/Employee"> </asp:XmlDataSource> 

In this case, we will use one XML file, for each client there will be a node, and for each type of form - another node. In this example, IBM is the client and Employee is the form. Of course, the XPath attribute must be set dynamically:

 protected void Page_Load() { if(!Page.IsPostBack) { CustomFields.XPath = String.Format("//Customers/{0}/{1}", CustomerName, FormName); } } 

Now you can bind a part of the form to the form using a ListView, using attributes in XML to display the TextBox for each field:

 <asp:ListView ID="DynamicFields" runat="server" DataSourceID="CustomFields" ItemPlaceHolderID="Item"> <LayoutTemplate> <fieldset> <legend>Custom fields</legend> <asp:PlaceHolder ID="Item" runat="server" /> </fieldset> </LayoutTemplate> <ItemTemplate> <div> <asp:Label runat="server" Text='<%# XPath("Field/@Label") %>' AssociatedControlID="Field" /> <br /> <asp:TextBox ID="Field" runat="server" data-field-id='<%# XPath("Field/@Id") %>' /> </div> </ItemTemplate> </asp:ListView> 

In your code behind, you can now retrieve the values ​​for each field and display them back using the data-field-id attribute:

 protected void Save_Click(object sender, EventArgs e) { foreach(ListViewItem item in DynamicFields.Items) { TextBox field = item.FindControl("Field") as TextBox; string id = field.Attributes["data-field-id"]; string value = field.Text; } } 

Of course, it becomes more complicated when you also want to load data into the fields for editing forms, but this is just a general approach based on your own proposal.

Some things that should be considered for storage are matching with a special table with columns for each data type (rows, numbers, dates, etc.). To do this, you will need to annotate your XML with the data type and confirm the input based on this.

 <Field Id="FirstName" Label="First Name" Type="String" /> <Field Id="DateOfBirth" Label="Date of birth" Type="DateTime" /> 

If you don't need this, you might consider serializing all the values ​​for a single row (JSON?) To store in a single database column. This makes it almost impossible to perform data queries.

 { "FirstName": value, "LastName": value } 
+1
source

Add all controls to the form. Hide the extra ones and show them as needed.

+1
source

I suggest using a binding , dynamically creating your custom control and associating a sub-element with the data of your queue (with the binding source), and after feedback, receiving data from the binding and updating source in the queue.

0
source

Source: https://habr.com/ru/post/1384904/


All Articles