This XML file may work for this example:
<?xml version="1.0"?> <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 }