Solved

Building a Dynamic Form Builder - oh my!

Posted on 2004-08-27
8
2,411 Views
Last Modified: 2008-01-09
I'm considering using the following solution to solve a problem of allowing users to "design' forms thru the web ui...

To create a web control, lets call it a "generic form builder"... where it renders forms based on a DB query..

The result set may look like

ControlType                              Label    DataSource
System.Web.UI.TextBox         -  Name      null
System.Web.UI.CheckBox       - Over 21    null
System.Web.UI.DropDownList - State      tblStates

etc..

I'll use this web control to accept input and it allows the flexibility of letting the end users design the fields they need to capture..

So if tommorrow they decide they want to capture "Favorite Food", they have the ability to add this..there are several issues, but the one i am getting a little hung up with the the dropdownlist...

my question is, have any of the uber coders out there created as similar "form builder" that can offer any suggestions on issues with viewstate, databinding or any other hurdles you may have jumped along the way..

thanks
0
Comment
Question by:Rodney Helsens
  • 5
  • 3
8 Comments
 
LVL 33

Expert Comment

by:raterus
ID: 11914357
I've done this before in one of my programs,  It is a Document Management program, where the user would design a "Template" of all the details they want to store about a particular type of document.  The user designs a form, and my asp.net page renders this page based on that (which is stored in a DB).

As far as databinding, how my program works, I programmed two options.  The first was to have one table for dropdownlist "listitem" values, where I put the text and the value, and an identifier to specify which created dropdownlist these were to be linked to.  This table was good for values that weren't necessarily stored elsewhere in our data.  When the program runs it is easy enough to get the data with this set up.  The other option I built in was to put a SQL Statement, and a connection string which my program would use to establish a connection to another datasource.  This sql string returned a result with datatextfield/datavaluefields already set, so my program could be generic enough to use any datasource, as long as the sql strings were built properly.

Getting the results of what they select is the fun part, you have to recreate the form on postback, since dynamically created controls aren't persisted across a postback.  That is the tricky part.

Let me know if you have any other questions,
--Michael
0
 
LVL 9

Author Comment

by:Rodney Helsens
ID: 11914807
Michael,
Thanks for the response, I do have another question regarding getting the values on postback.

I did a simple test aspx page and was able to create all the form elements and retrieve their values, but when I've tried to same tests using a web control, within a aspx page, I am losing the values selected.

I know this has to do with the timing of when the form elements are rebuilt, in my example, I am calling a method of the web control from my aspx on_load to build the form with a parameter telling it which form to build..

I have read about getting the form elements built in page_init or view state will not work..

Do you think it's possible to use the design of calling a method of the ascx to tell it to build the form, ie webControl.BuildForm(formID); from page_load on the aspx page?

Then on postback, I will call this webControl.BuildForm(formID) again, but it loses the values that were entered.

thanks again.
0
 
LVL 33

Expert Comment

by:raterus
ID: 11914921
By WebControl within an aspx page, I'm assuming you are meaning a UserControl (since you mentioned ascx).  Let me get this right, you have a usercontrol that will render the custom form automatically, based on a property you have selected, and on postback, you want anything you have typed/selected to be available from the usercontrol.  Are you wondering what you should call on the aspx page to recreate the UserControl correctly, and where to call it?

Just one question too if all this is correct,
Is the usercontrol dynamically added to your aspx page, or have you placed this within the aspx source?

--Michael
0
 
LVL 33

Expert Comment

by:raterus
ID: 11915230
Here I'm just going to throw some code at you if my last post was on track.  Basically you don't need to worry about telling the usercontrol to Build itself, just expose a property, and when you change that, it knows it needs to remake itself.  Here was my sample, works great for me (hope you are using Visual Studio)

This is a webpage that has a usercontrol which either renders as a SingleLine textbox or a Multiline textbox based on a property "RenderAs".  The secret in all of this is the Public property of the Usercontrol, RenderAs, when you change it, you just tell it to Build the controls again.  No need for your aspx page to tell it to rebuild, it should already know how to do this.

WebForm1.aspx
<%@ Register TagPrefix="uc" TagName="Dynamic" src="WebUserControl1.ascx" %>
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx.vb" Inherits="Test.WebForm1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
  <head>
    <title>WebForm1</title>
</head>
  <body>

    <form id="Form1" method="post" runat="server">
            <uc:Dynamic id="ucD1" runat="server" />
            <asp:button id="btnClick" runat="server" text="Postback" />
            <asp:button id="btnSwitch" runat="server" text="Switch RenderAs" />
    </form>

  </body>
</html>

WebForm1.aspx.vb
Public Class WebForm1
    Inherits System.Web.UI.Page

    Protected WithEvents btnClick As System.Web.UI.WebControls.Button
    Protected WithEvents btnSwitch As System.Web.UI.WebControls.Button
    Protected WithEvents ucD1 As WebUserControl1

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Put user code to initialize the page here
        If Not Page.IsPostBack Then
            ucD1.RenderAs = 1
        End If
    End Sub

    Private Sub btnClick_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnClick.Click
        'some stuff on postback
    End Sub

    Private Sub btnSwitch_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSwitch.Click
        If ucD1.RenderAs = 1 Then
            ucD1.RenderAs = 2
        Else
            ucD1.RenderAs = 1
        End If
    End Sub
End Class

WebUserControl1.ascx
<%@ Control Language="vb" AutoEventWireup="false" Codebehind="WebUserControl1.ascx.vb" Inherits="Test.WebUserControl1" TargetSchema="http://schemas.microsoft.com/intellisense/ie5" %>

WebUserControl1.ascx.vb
Public Class WebUserControl1
    Inherits System.Web.UI.UserControl

    Public Property RenderAs() As Integer
        Get
            Return CInt(ViewState("renderas"))
        End Get
        Set(ByVal Value As Integer)
            ViewState("renderas") = Value
            MakeForm()
        End Set
    End Property

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Put user code to initialize the page here
        MakeForm()
    End Sub

    Private Sub MakeForm()
        Me.Controls.Clear()

        If RenderAs = 1 Then
            Dim txtTest As TextBox = New TextBox
            Me.Controls.Add(txtTest)
        Else
            Dim txtTest As TextBox = New TextBox
            txtTest.TextMode = TextBoxMode.MultiLine
            Me.Controls.Add(txtTest)
        End If
    End Sub
End Class

0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 9

Author Comment

by:Rodney Helsens
ID: 11915995
raterus, thanks again for the help.

I will read thru your code more thoroughly in a moment..to try and understand the implementation better, but one thing that jumps out at me is the postback code..

you never explicity re-render the user control, to create the form... so where/how do you access the values for those dynamically created form elements?  you show the line... 'some stuff on postback, but this is where I am experiencing the most trouble...  
how does the user control know on postback how to render itself in your example? how do you access the values of those objects?
thanks

0
 
LVL 33

Accepted Solution

by:
raterus earned 500 total points
ID: 11916509
Well here is where it gets difficult :-)

Depending on your level of coding ability, your best bet would probably be to create an object that represents any custom form your program could create.  Your aspx page instantiates this object, fills it with any values the form elements would need, and you load the UserControl with this object, which the usercontrol takes off and creates the form for you.  To get the values back out, you define your own methods in this object to do that.  What it is going to come down to is how elaborate you need to make this object be, like are you ever going to have to set a value in this dynamic form, how many different form elements could you possibly have, etc.

Or from your aspx page you can do this..ucd1.FindControl("SomeControl"), cast it, and grab the value.  

The solution to this can be very elegant and encapsulated, or it can be brute force.  You pick..

--Michael
0
 
LVL 33

Expert Comment

by:raterus
ID: 11916534
Oh, in the page_load of the usercontrol is MakeForm(), that will remake the form on every page load.
0
 
LVL 9

Author Comment

by:Rodney Helsens
ID: 11916575
your feedback is appreciated, I think I am going to take another approach at this point, thanks
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

In an ASP.NET application, I faced some technical problems. In this article, I list them out and show the solutions that I found.  I hope it will be useful. Problem: After closing a pop-up window, the parent page should be refreshed automaticall…
ASP.Net to Oracle Connectivity Recently I had to develop an ASP.NET application connecting to an Oracle database.As I am doing it first time ,I had to solve several problems. This article will help to such developers  to develop an ASP.NET client…
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
Migrating to Microsoft Office 365 is becoming increasingly popular for organizations both large and small. If you have made the leap to Microsoft’s cloud platform, you know that you will need to create a corporate email signature for your Office 365…

863 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

25 Experts available now in Live!

Get 1:1 Help Now