Solved

Building a Dynamic Form Builder - oh my!

Posted on 2004-08-27
8
2,410 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
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
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

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Suggested Solutions

Just a quick little trick I learned recently.  Now that I'm using jQuery with abandon in my asp.net applications, I have grown tired of the following syntax:      (CODE) I suppose it just offends my sense of decency to put inline VBScript on a…
User art_snob (http://www.experts-exchange.com/M_6114203.html) encountered strange behavior of Android Web browser on his Mobile Web site. It took a while to find the true cause. It happens so, that the Android Web browser (at least up to OS ver. 2.…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

707 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

14 Experts available now in Live!

Get 1:1 Help Now