This is a post in my blog series Introduction to Chameleon...

Chameleon form controls implement the functionality of Community Server forms, for example: creating a forum post, editing a user's profile, or registering for a user account. 

Form controls in Chameleon define the minimum functionality required to implement the purpose of the form--they provide the "glue" that makes a set of form element perform an action.  When that action is completed, many forms provide the theme developer with a way to define what to do next.  For example, the ContactForm blog control:

<CSBlog:ContactForm runat="server" SubjectTextBoxId="Subject" NameTextBoxId="Name" EmailTextBoxId="Email" MessageTextBoxId="Body" SubmitButtonId="Submit">
   <SuccessActions>
      <CSControl:SetVisibilityAction runat="server" ControlIdsToShow="SuccessMessage" />
   </SuccessActions>
   <FormTemplate>

      <div><CSControl:FormLabel LabelForId="Name" runat="server" ResourceName="Weblog_ContactForm_Name" /></div>
      <div><asp:TextBox id="Name" runat="server" /></div>

      <div><CSControl:FormLabel LabelForId="Email" runat="server" ResourceName="Weblog_ContactForm_Email" /></div>
      <div><asp:TextBox id="Email" runat="server" /></div>

      <div><CSControl:FormLabel LabelForId="Subject" runat="server" ResourceName="Weblog_ContactForm_Subject" /></div>
      <div><asp:TextBox id="Subject" runat="server" /></div>        

      <div><CSControl:FormLabel LabelForId="Body" runat="server" ResourceName="Weblog_ContactForm_Body" /></div>
      <div><asp:TextBox id="Body" runat="server" TextMode="MultiLine" /></div>

      <div>
      <asp:Button id="Submit" runat="server" Text="Send" />
      <CSControl:ResourceControl runat="Server" id="SuccessMessage" ResourceName="Weblog_ContactForm_Sent" Visible="false" />
      </div>

   </FormTemplate>
</CSBlog:ContactForm>

defines a form that allows visitors to the site to contact the blog owner.  The properties of the ContactForm identify the controls within the FormTemplate to use to implement the form's required inputs -- Subject, Name, Email, Message, and Submit.  The ContactForm itself provides the "wiring" that makes these form elements perform the task of contacting the blog owner.  When the form is successfully processed, the SuccessActions inner-property defines the actions to perform (Actions controls will be discussed in a future post in this series).

Chameleon form controls support the same basic properties as single value base controls (ControlIdsToHideWhenNotVisible, ContainerId, CssClass, Tag, DisplayConditions, LeaderTemplate, TrailerTemplate, DataSource, and Attributes) and also support the following properties (and inherit from WrappedFormBase):

  1. ValidationGroup

    ValidationGroup is the name of the validation group to use when validating the content of the form. 
  2. FormTemplate

    FormTemplate is an inner-property that contains markup and controls to render as the content of the form.  Generally, the form's child controls are contained within the FormTemplate, but this is not required.
  3. Properties for Child Control IDs

    Each form supports a set of child controls specific to its purpose.  For each child control supported, a property is exposed that is named to identify the intended value/purpose of the control and the type of control expected.

    Not all child control properties must be set, however, if the required control IDs are not specified (or do not exist), the form control will throw an exception explaining which control IDs are required to render the form.
  4. Properties for Completion Actions

    Depending on the function of the form, action-related inner-properties will be exposed to allow the theme developer to define the action (or actions) to perform when the form has completed a specific function.

    Most form controls expose "SuccessActions" which are executed when the form is successfully completed (for example, when the ContactForm has been submitted successfully).  If a form has more than one completion action, a "Actions" inner-property is exposed for each type of completion.  Similarly, if a form has no completion action or its completion action is predefined (for example, SearchForm always redirects the user to the search results page), no theme-developer-defined "Actions" are supported.
  5. SubFormIDs

    A few Chameleon form controls support sub-forms.  Chameleon sub form controls (which inherit from WrappedSubFormBase) can participate in the form lifecycle and extend the functionality of existing forms.  For example, the CreateEditForumPostForm supports sub-forms and, in the default theme, uses the TagsSubForm, AttachmentSubForm, VideoSubForm, PollSubForm, and InkSubForm to add tag, attachment, video, poll, and ink support (respectively) to the basic forum post form.

    Sub-forms allow forms to be simpler--the CreateEditForumPostForm implements the basic functionality required to create a forum post--while allowing new, customized functionality to be added on a theme-by-theme basis.  Theme developers can, for example, use a custom implementation of the poll sub-form or video sub-form without having to programmatically override the entire CreateEditForumPostForm control.  Similarly, theme developers can add new sub-forms to the form, such as adding a sub-form to allow users to select a background texture to add to their forum posts.

Chameleon form controls function much like themed controls in Community Server 2.1 and earlier.  They attach to predefined child-controls and perform an action with them.  However, unlike Community Server 2.1 and earlier, Chameleon form controls expose a listing of the supported child controls (via the properties for child control IDs), allow the theme developer to define the control IDs, and allow the theme developer to customize completion actions (via action controls) and form functionality (via sub forms).

If you have any questions regarding forms in Chameleon (or any Chameleon-related question), please send them to me via my contact form or add a comment.  I will answer the questions in the final post in this series.

In my next post in this series, I will discuss Condition controls.