Custom MVC Controls for WFFM in Sitecore 8.1

The Web Forms For Marketers module is quite customizable, and the styling of the form controls would normally be manipulated from CSS classes, but I found myself in the situation where I had to adjust not only the styles of the controls, but also the html that renders behind. In this case, I investigated how to create my own custom controls and integrate them with the rest of the WFFM module. My project was built on Sitecore XP 8.1 rev.151003 (Initial Release) version, using the WFFM module, version 8.1 rev. 151008. The purpose is to customize a Single-Line Text control so that the field is surrounded by a <div> with a certain CSS class, has a label with a (*) if the field is required, and has some information displayed if filled in by the editor. The same process can then be followed in order to customize any other form control.

The first step is to check how the classic Single-Line Text control is created, and we can start by looking at the code behind. This information can be retrieved from the corresponding item in Sitecore:

SingleLineText

Our custom control will use the same class as the original control, so we do not need to change anything in the ”Assembly” and ”Class” fields. What we are interested to change is the ”MVC Type” used by our control, because we will implement a new rendering and we will need to link it in this field. Using a decompiling tool, we can see how the view model class of this control is implemented in the SingleLineTextField class (namespace Sitecore.Forms.Mvc.ViewModels.Fields, Sitecore.Forms.Mvc.dll). For most of the controls, the view model class has a strong relation with the view containing the actual control rendering, by having the same name (so naming convention is very important, as with everything in MVC). The views, as installed with the WFFM module, can be found in <website>\Views\Form\EditorTemplates. All the view model classes in the namespace Sitecore.Forms.Mvc.ViewModels.Fields inherit from FieldViewModel class (Sitecore.Forms.Mvc.ViewModels). If the view model of a control has a corresponding view with the same name, it will render that one, otherwise it will render the view of the FieldViewModel (implemented in <website>\Views\Form\EditorTemplates\FieldViewModel.cshtml). For example, the view model for the CheckboxField will render the view CheckboxField.cshtml, whereas the view model for SingleLineTextField will render the view FieldViewModel.cshtml.

So let’s create a new view in our project in the same folder as the other WFFM views, and call it MySingleLineTextField.cshtml. This will contain our code for the custom Single-Line Text rendering, and will reference a new view model with the same name. We will add a new ViewModels folder in our project and add the new class MySingleLineTextField.cs there. If we look at the code in FieldViewModel.cshtml, we can see that it makes use of the Html.BeginField() statement, which renders some tags and classes that I want removed and replaced with a different html structure. By removing this code, we need to make sure that we properly manage the label and the validation display. The advantage is that we can completely control how everything will look like by arranging the html and inserting our own CSS classes.

Views/Form/EditorTemplates/MySingleLineTextField.cshtml

@using Sitecore.Forms.Mvc.Html
@using MyProject.ViewModels
@model MySingleLineTextField

<div class="field">
    <label>
        @Html.BootstrapText("Title")
        @if (Model.IsRequired)
        {
            <abbr class="required" title="Required field">*</abbr>
        }
    </label>
    @Html.BootstrapEditor("Value", new string[] { "input-text" })
    @if (!string.IsNullOrEmpty(Model.Information))
    {
        <p class="small-note">
            @Html.BootstrapText("Information")
        </p>
    }
    <p class="small-note">
        @Html.BootstrapValidationMessage("Value")
    </p>
</div>

ViewModels/MySingleLineTextField.cs

using Sitecore.Forms.Mvc.ViewModels.Fields;

namespace MyProject.ViewModels
{
    public class MySingleLineTextField : SingleLineTextField
    {
        public MySingleLineTextField()
        {
        }       

        public override void Initialize()
        {
            base.Initialize();       
        }
    }
}

Now we can create the custom field in Sitecore and link it with the custom rendering. It is easier to copy the existing ”Single-Line Text” item and rename it. We will add the new item under a ”Custom” folder:

MySingleLineText

The custom field can be added on a new or existing form, like in the screenshot below:

CustomFieldOnForm

As a conclusion, we could create variations for any of the existing form controls, customizing the rendering in any way we want, provided that we also implement a view model class with the same name as the rendering. In order to know what to write in the view model class, just look at the decompiled version of the original view model from the Sitecore.Forms.Mvc.dll.

Advertisements

3 thoughts on “Custom MVC Controls for WFFM in Sitecore 8.1”

  1. What else if I want to add two text box in MySingleLineTextField.cshtml. I tried but i am getting same ID for both the New text Box.{
    @Html.ExtendedBootstrapEditor(“value”, ” “, “width:50%”, new[] { “” })
    @Html.ExtendedBootstrapEditor(“value”, ” “, “width:40%”, new[] { “” })
    ID=wffm1755f6ce241245b7a1183288954ce0e7_Sections_0__Fields_0__value

    Like

    1. Hi Shailesh!

      There are two possibilities for your problem. The first, and easiest, would be to use two custom fields, one for each text box. The second would be to replace in each BootstrapEditor the “value” with “Value_1” and “Value_2”. Your IDs will then be different for each textbox:

      @Html.ExtendedBootstrapEditor(“Value_1”, ” “, “width:50%”, new[] { “” })
      @Html.ExtendedBootstrapEditor(“Value_2”, ” “, “width:40%”, new[] { “” })

      The IDs will be something like:
      First textbox: ID=wffm1755f6ce241245b7a1183288954ce0e7_Sections_0__Fields_0__Value_1
      Second textbox: ID=wffm1755f6ce241245b7a1183288954ce0e7_Sections_0__Fields_0__Value_2

      Then, to map these values to the fields in your view model class, you would need to add them as properties. Thus, in ViewModels/MySingleLineTextField.cs, you need to have:

      public string Value_1 { get; set; }
      public string Value_2 { get; set; }

      You will see that Value_1 and Value_2 from your model will receive the values filled in the form.
      I hope this helps!

      Cristina

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s