Form generation - how using MForm may speed up development process

Too much reading? You can find a movie, following this tutorial at http://www.youtube.com/watch?v=GfrvCApc02Y.

1. Get the contract.

To be able to generate a form, you first need to have data definitions. It is best if you have these definitions in XML schema (as XML schema provides a way to declaratively define data restrictions not currently available in code), but if you are not familiar with XML schema, you can also generate a form form a managed library.

In the following example we will use a Customer data definition:

generation_1.png

The Customer has
  • a first and last names, which cannot be longer than 20 characters,
  • national id,
  • a birth date (of type date),
  • sex, which can be only of value 'Male' or 'Female'
  • and the address, which consists of:
    • street of maximal length 100,
    • house number of maximal length 10,
    • flat number, which is optional,
    • post code, which has to match the pattern two digits - three digits
    • city of maximal length 50

2. Create the MForm Root control

The Root control, as its name suggests, is the root control of the tree of MForm controls. The Root control is in BM.Tools.WebControls.MForm.Controls namespace.

generation_2.png

3. Open the MForm Root control in Visual Studio designer

The Root control has a special control designer implemented. Switch to the designer mode and click the action tag, and change the designer mode to Edit

generation_3.png

4. Click the load a root template form schema button

You will see the generator form:

generation_4.png

5. Choose the contract source and location

Click the choose button and select the XML schema, wsdl or assembly file. Then click Open
The Element name dropdown list will be propagated with available elements (One XML schema file may have more than one element definition, same as one assembly may have more than one class)

generation_5.png

6. Select the element

Once you select one of the elements from the dropdown list, the element tree will be displayed. You have a possibility to decide which definitions should be rendered in the form. By default the whole tree is prepared to be rendered. To change this, uncheck the checkboxes near the elements:

generation_6.png

7. Click Generate

Once you click Generate, the Root control is filled in with the content. The Root designer mode is changed to View mode so you can see the result:
(The rendering in the designer mode is not perfect, the actual page display may vary ):

generation_7.png

8. Switch to Source View

The generated form is available in the source view and can be freely modified. We will take a closer look at the generated code:

generation_8.png

The generated code in aspx may look a little scary at first. There is quite a lot of data that has been generated.
The Root control was empty before, now it has three elements:
  • UriMappings element
  • Contents element
  • Validator element

The UriMappings

The UriMappings element keeps data about prefix and namespace mappings in the data definition. In the case of our example, no namespaces were used, so there is only one mapping, an empty prefix is mapped to an empty namespace.

The Validator

The Validator element is responsible of displaying the form validation errors. It plugs the MForm tree in the ASP.NET page validation mechanism.

The Contents property

Finally, the Contents element is the most important part of the Root control. The Contents property is a template that is instantiated on page rendering, so it may contain any valid aspx script code: html code, web controls, etc.. By default it only contains the generated controls. You can see a Branch control with a property name equal Customer. This control also has the Contents property, which again may contain any aspx script code.

Branches and leafs

The Branch controls are those that represent data definitions that had children. The data definitions that collected text are represented by the Leaf controls. The Leaf controls do not contain the Contents property. Instead, they may contain the ValueHandler element, which provides a communication between the MForm tree and a control that should actually collect the data.

Value handlers

By default all data is collected using TextBoxes, so the default value handler is the TextBoxValueHandler. The MForm framework provides value handlers for the generic .NET form webcontrols. If you want to use your own custom control with the MForm framework, you have to implement a value handler for this control.

The example of a different value handler is in a Leaf called Sex. The data definitions allowed only two values in this element: Male or Female. This has been ported to the form as a listbox control, that has to corresponding list items. If you prefer using i.e. the RadioButtonList instead of the ListBox, you can change the value handler to a RadioButtonListValuehandler, and its inner control to RadioButtonList.

Data type

Do you remember that our customer data definition had a BirthDate field, which was of type date. You can now see that the BirthDate leaf has a property DataType of value Date. This asserts that this field data must be provided in a valid date format.

Additions

Another definition that may be found inside the Leaf control is the Additions. Additions may contain a list of controls that inherit from the Addition control. The Addition control adds some logic to the MForm control, it can for example add a data constraint. The Addition controls that can be found directly after generation are data restrictions taken from XML schema. So if in our data contract the PostCode field had to match the pattern: 2 digits - 3 digits, we will a Restriction addition of restriction type Pattern and value \d{2}-\d{3} in a leaf called PostCode.

The Ordinal property

One last thing that is worth explaining is the Ordinal property.

The MForm webcontrols were designed to maximally facilitate the creation of web forms, but still to give the possibility of editing this form after generation. One can freely modify a once generated form, only remembering that the generated MForm children cannot be moved outside their parents.

So inside the Contents property it is allowed to:
  • add some html code or controls;
  • place MForm child control inside these added controls (e.g. all Leaf controls can be placed inside a table);
  • extract a part of a generated code and place it in an external user control, and add a reference to this control inside the Contents;
  • change the order of MForm siblings;

When creating an output xml from the tree of MForm controls, two factors are taken into account:
  1. the hierarchy of the XML nodes - if MForm children are not moved outside their parents, the MForm hierarchy remains intact, so the hierarchy of XML nodes will also be valid;
  2. the order of XML nodes - because the order of controls can be changed, the Ordinal property is generated. When the output xml is rendered, the MForm controls are sorted by the Ordinal property value, which asserts, that the order of XML nodes is valid

If you do not care about the order of XML nodes (i.e. deserializing xml to objects using the .NET XmlSerializer class in most of the cases totally ignores the order of XML nodes), you can turn off generation of the Ordinal property in the generator under the options tab.

Last edited Jul 10, 2009 at 1:02 PM by michalwozniak, version 8

Comments

No comments yet.