This project is read-only.

What is formsy?

Formsy is an XML driven forms engine built with ASP.Net 3.5. Formsy is super easy to use, is completely extensible and generates clean markup for easy styling.

Best of all, when form definitions change, all is required is a change to XML. No coding, and no database table changes (with the inevitable synchronisation across dev, staging and live environments). Just XML!

Cool functionality out of the box

Formsy has lots of extensible functionality. For example, customizable regionalization of labels, validation error messages, and validation regular expressions. Not to mention customizable field pre-populating, data storage, file storage handling, validation, emails on submit, and data sources.

Among other great functionality, Formsy provides the developer with some easy to use controls which do away with tedious manual wiring up of client scripting. For example, Formsy's EmailPair and PasswordPair fields (for email and password confirmation) makes those 2 textboxes and that client side compare validator for you!

Finally Formsy provides a ready built Admin section with CSV download.

Using Formsy

Using Formsy is easy! Once you have run the database creation scripts, copied and reference the dlls, all you need is 3 lines of markup. Then wack on your XML hat, or use a provided example.

Here is all you need in your markup file

<%@ Import namespace="Formsy.Core" %>
<%@ Register  Assembly="Formsy.Core" Namespace="Formsy.Core" TagPrefix="Formsy" %>    

<Formsy:FormEngine ID="SignUpForm" runat="server" FormDefinitionPath="/Xml/FormDefinitions/SignUp.xml" DictionaryPath="/Xml/FormDefinitions/SignUpDictionary.xml" />

Formsy's XML

Formsy uses standard ASP.Net naming for controls. Below is a XML form definition for a typical "Contact Us" form. The naming convenstions follow that of .Net markup, but no real coding is required!

<Form Name="Contact Us" ValidationSummary="true" SuccessPage="/Pages/Success.aspx" UseDefaultStyle="true">
    <Providers>
        <Provider Type="Email" Name="StandardProvider" RecipientAddress="recipient1@yourdomain.com,recipient2@yourdomain.com" SenderAddress="no-reply@yourdomain.com" />
    </Providers>
    <FieldSet Name="Contact Us">
        <Field Name="First Name" Type="TextBox">
            <Validator Type="RequiredFieldValidator" Text="*" ErrorMessage="Please enter a first name" Display="Dynamic"/>
        </Field>
        <Field Name="Last Name" Type="TextBox">
            <Validator Type="RequiredFieldValidator" Text="*" ErrorMessage="Please enter a last name" />
        </Field>
        <Field Name="Email" Type="TextBox" Label="Your Email">
            <Validator Type="RequiredFieldValidator" Text="*" ErrorMessage="Please enter an email" />
            <Validator Type="RegularExpressionValidator" Text="*" ErrorMessage="Please enter a valid email address" ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" Display="Dynamic"/>
        </Field>
        <Field Name="Comment" Type="TextArea">
            <Validator Type="RequiredFieldValidator" Text="*" ErrorMessage="Please enter a comment" Display="Dynamic"/>
        </Field>
    </FieldSet>
    <FieldSet>
        <Field Name="Terms and Conditions" Type="CheckBox">
            <Validator Type="RequiredFieldValidator" Text="*" ErrorMessage="Please agree to the terms and conditions" Display="Dynamic"/>
        </Field>
    </FieldSet>
</Form>

See appendix A in full documentation for supported fields, and Appendix B for a walk-through example.

Admin Page with CSV Download

Formsy comes with an admin facility with a CSV Download tool. It also has super easy to use ajax delete and edit functionality.

Admin Page

Here is an example of the admin markup:

<Formsy:Admin ID="MyAdmin" runat="server" FormName="My Form" IgnoreList="" UseDefaultStyle="true" EntriesPerPage="50"/>

Admin Control Attributes

FormName – The name of the form as definited in your XML form definition
IgnoreList – Comma separated list of fields to ommit from the table
UseDefaultStyle – For using Formy's default admin CSS
EntriesPerPage – Sets the number of entries to display per page

CSV Download

The CSV Download tool can also be used as stand alone. Here is an example of the markup:

<Formsy:CSVDownload ID="MyCsvDownload" runat="server" FormName="My Form" IgnoreList="" UseDefaultStyle="true"/>

CSV Download Control Attributes

FormName – The name of the form as definited in your XML form definition
IgnoreList – Comma separated list of fields to ommit from the table
UseDefaultStyle – For using Formy's default admin CSS

Providers

The goal when creating Formsy was to make it as extensible as possible. So key functionality is provider based.
Formsy's providers can be categoriesed into 3 areas:
1.Control Building (DataSource, CustomField)
2.Pre-Rendering (PrePopulate, Regionalization)
3.Submission (Validation, DataStore, FileSystem, Email)

Control Building

DataSource

Very often form lists (eg. DropdownList, RadioButtonList etc) require custom or predefined data (eg. Countries, street types, products). This provider allows the developer to use a custom DataSource to populate such lists. Here is an example with a DropDownList using an XML provider.

<Field Name="Street Type" Type="DropDownList">
    <Provider Type="DataSource" Name="XmlProvider">
        <Parameter>/Xml/Streets.xml</Parameter> <!-- XML path -->
        <Parameter>StreetTypes</Parameter> <!-- Root XML node-->
        <Parameter>StreetType</Parameter> <!-- Descendent XML node of root-->
    </Provider>
</Field>

The XmlProvider is provided with Formsy. See a working example in the example project.

The developer only needs to override one method (see below).

public abstract List<ListItem> GetListItems(List<XElement> parameters);

Notice that the the "parameters" parameter is simply the parameter list definied in the XML above.

CustomField

This provider allows custom fields to be created. The provider is referenced in the form XML definition, where parameters are also able to be set (see example below).

<Field Name="My Custom Field " Type="CustomField">
    <Provider Type="CustomField" Name="MyCustomField">
        <MyParameter>Param1</MyParameter>
        <Something>Param2</Something>
        <MaybeSomethingElse>Param3</MaybeSomethingElse>
    </Provider>
</Field>

The developer only needs to override one method (see below).

public abstract HtmlGenericControl CreateCustomField(XElement field, HtmlGenericControl div, HtmlGenericControl fieldSet, List<FormField> formFields);

When creating a custom field, the developer is given access to the XML definition, the current containing div and the fieldset containing the div. An object of type FormField must be added to the formFields parameter to allow Formsy to allow Formsy to save the field's data on submit.

The return value must be the containing div. See a working example in the example project.

See a working example in the example project.

Pre-Rendering

These two providers fire at the pre-render page event.

Regionalization

This is one of the coolest parts of Formsy. Regionalization of labels, validation messages and validation regular expressions. Regionalization occurs when the DictionaryPath attribute of the FormEngine control (in the markup) has a value. By default, Formsy will use UICulture to destinguish regions. This provider allows the developer to define other types of regions (eg. suburbs, or even geocodes).

The provider name is referenced in the dictionary XML definition (see below).

<Dictionary Provider="MyRegionalization">

The developer only needs to override one method (see below).

protected virtual string GetRegion();

This method should simply get the current region which matches one defined in the Dictionary XML file.

See a working example in the example project.

PrePopulate

Forms with pre-populated fields (eg for updating membership details) are generally annoying to make. The PrePopulate provider gives a developer direct access to the controls which they want to pre-populate. The prepopulate provuder is referenced in the form XML definition at the top of the XML (see below).

<Providers>
    <Provider Type="PrePopulate" Name="MyPrePopulate">
        <Parameter>This is prepopulated 1</Parameter>
        <Parameter>This is prepopulated 2</Parameter>
    </Provider>
</Providers>

The developer only needs to override one method (see below).

public abstract void PrePopulate(List<FormField> formFields, List<XElement> parameters);

This method gives the developer direct access to fields via the formFields collection. So properties of all the form's controls are exposed. The parameters collection is simply XML access via XElements (XML example above).

See a working example in the example project.

Submission

Validation

On occasion the developer may wish to implement custom validation on submit. The Validation provider allows direct access to the controls in the page to do just that! The Validation provider is referenced at the top of the form XML definition (see example below).

<Providers>
    <Provider Type="Validation" Name="MyValidation" />
</Providers>

The developer only needs to override one method (see below).

public abstract bool Validate(Control formEngine, List<FormField> formFields, Dictionary<string, string> fields)

This method allows the developer to inspect and modify validators and fields via the parameters formEngine and formFields. The parameter "fields" allows quick access to field names and their corresponding values. Simply return true if the form is valid.

See a working example in the example project.

FileSystem

Formsy's Standard provider saves the uploaded file (unchanged) to the file system. The FileSystem provider allows custom handling of the files. For example, the developer may want to create a thumbnail of an uploaded image. The ImageThumbnail provider is provided with Formsy.

The FileSystem provider is referenced at the top of the form XML definition (see example below).

<Providers>
    <Provider Type="FileSystem" Name="MyFileSystem" />
</Providers>

The developer only needs to override one method (see below).

public abstract List<FormsyFile> Save(string formName, int entryId, List<FormsyFile> files, string folderPath);

This method allows access to uploaded files via the "files" parameter. It is recommended that the developer follows the following naming conventions when doing custom handling of files.

// create filename
string filename = entryId.ToString() + "_" + f.FieldName + "." + f.Extension;

// save full filename path
f.Filename = folderPath + filename;

This method returns a List of FormsyFile because the developer may wish to create multiple versions of the file. For example, below is the overrided method in the ImageThumbnail provider.

public override List<FormsyFile> Save(string formName, int entryId, List<FormsyFile> files, string folderPath)
{
    List<FormsyFile> thumbnails = new List<FormsyFile>();

    foreach (var f in files)
    {
        string filename = entryId.ToString() + "_" + f.FieldName + "." + f.Extension;
        string thumbName = entryId.ToString() + "_" + f.FieldName + "_thumb." + f.Extension;

        FileSystemLibrary.SaveImage(folderPath, filename, f.Bytes);
        FileSystemLibrary.SaveThumbnailImage(folderPath, thumbName, f.Bytes, 100, 100);
        f.Filename = filename;
        FormsyFile thumb = new FormsyFile(f.FieldName, null, f.Extension);
        thumb.Filename = thumbName;
        thumb.FieldName = thumb.FieldName + "_thumb";
        thumbnails.Add(thumb);
    }

    // combine lists
    files.AddRange(thumbnails);

    return files;
}

See a working example in the example project.

DataStore

Formsy stores form entries in it's custom database tables via it's default DataStore provider. The DataStore provider allows the developer to store the captured form data elsewhere (such as another custom database table).

The DataStore provider is referenced at the top of the form XML definition (see example below).

<Providers>
    <Provider Type="DataStore" Name="MyDataStore" />
</Providers>


The developer only needs to override two methods (see below).

public virtual IFormsyEntry InsertEntry(string formName, bool isUpdate)
public virtual List<IFormsyEntryData> InsertEntryData(int formId, int entryId, Dictionary<string, string> dictionary, bool isUpdate)

When overriding these methods, the developer must call the base methods to allow formsy to store the form data. If base.InsertEntry is not called, Formsy will throw an exception when it tries to access entry.FormId to pass into the InsertEntryData method.

The method "InsertEntry" simply provides the form name, and whether the form is updatable. The InsertEntryData method gives access to the field names and their related values.

See a working example in the example project.

Email

By default, Formsy sends an email to a recipient when a form is submitted. Sometimes emails (perhaps multiple) need to be sent elsewhere (or perhaps not at all). The Email provider allows this.

The Email provider is referenced at the top of the form XML definition (see example below).

<Providers>
    <Provider Type="Email" Name="MyEmail" RecipientAddress="recipient@yourdomain.com" SenderAddress="no-reply@yourdomain.com" />
</Providers>


The developer only needs to override one method (see below).

public override void Send(string formName, string senderAddress, string recipientAddresses, Dictionary<string, string> dictionary)


This method is very self explainitory. The recipientAddresses parameter is a comma separated list of email addresses. The dictionary parameter gives the developer access to the field names and their values.

See a working example in the example project.

Installation

1.Run the database table create script under \DOCUMENTATION\Formsy.sql
2.Copy the DLL's to a DLL's folder and reference them in your project.
3.Add the configuration sections to your web.config. See \DOCUMENTATION\Web.config for an example.
4.Add the FormEngine control to your .aspx page.
5.Create your XML file, or use one of the provided examples.

To see more, download the full documentation.

Last edited Apr 5, 2011 at 3:16 PM by AnthonyDotNet, version 9

Comments

Kalakonda1986 Jun 4, 2011 at 1:31 AM 
Hi How can I override the functions and store it into my database. This is what we need with little bit of customization any help in this regard is greatly appreciated

Kalakonda1986 Jun 4, 2011 at 1:12 AM 
Hi,

I am new to .Net I want to store the data into my custom tables how should I do that I unable to view the code to see where it is getting saved to database