Sitecore XP 10 Forms Custom Form Element with Multiple Fields

Here’s a comprehensive walkthrough on how to create a custom form element with multiple fields.

May 27, 2025

By Gorman Law

Walkthrough: Creating a Custom Form Element with Multiple Fields

In this blog, we will be making a custom address form element as an example. It will contain fields for address, city/town, province/state, postal code, and country.

Create a Template for the Fields

  1. Right click on /sitecore/templates/System/Forms/Fields and insert a new template named Address Complete.
  2. After it’s created, switch over to the Content tab. There should be a Data section with a Base template field. Add Templates/System/Forms/Fields/Field.

    Sitecore form builder interface showing a selected custom field under base template options

  3. Go back to the Builder tab and add a Section named Address. Add the following fields with the Type Single-Line Text.

    • Address Label
    • Address Label Css Class
    • Address Css Class
    • Address Div Css Class
    • Address Placeholder Text

  4. Add a Section named City and the following fields. The Field Name is the important field, but we will get to that later.

    City Label, City Label Css Class, City Css Class, City Div Css Class, City Placeholder Text, City Field Name

  5. Add a section named Province

    Province Label, Province Label Css Class, Province Css Class, Province Div Css Class, Province Field Name

  6. Add a section named Postal Code

    Postal Code Label, Postal Code Label Css Class, Postal Code Css Class, Postal Code Div Css Class, Postal Code Placeholder Text, Postal Code Field Name

  7. And finally, a section named

    Country Label, Country Label Css Class, Country Css Class, Country Div Css Class, Country Field Name

  8. Now to go the Builder Options ribbon at the top and add Standard values. Without standard values, you will not be able to add the element inside form builder. You can fill out the Standard values however you want. I did something simple like this:

    Form field settings

Creating a New Class

Now it’s time to go into the code. In Visual Studio, create a new class named AddressCompleteViewModel.cs . Here’s what mine looks like with just the Address fields included to save space. Please read the comments for more details.

using Sitecore;
using Sitecore.Data.Items;
using Sitecore.ExperienceForms.Mvc.Models.Fields;
using System;

namespace MyProject.Feature.Sitecore.Forms.Fields
{
    [Serializable]
    public class AddressCompleteViewModel : StringInputViewModel
    {
        public string ErrorMessage { get; set; }

        //Address fields. Copy the name of the fields in the Address Complete template, but remove the spaces; it increases readability
        public string AddressLabelCssClass { get; set; }
        public string AddressCssClass { get; set; }
        public string AddressDivCssClass { get; set; }
        public string AddressPlaceholderText { get; set; }

        // add the rest of the fields here

        // Create an override for InitItemProperties
        protected override void InitItemProperties(Item item)
        {
            // on form load
            base.InitItemProperties(item);

            // Initialize the address fields. They will be the Standard values at first
            AddressLabel = StringUtil.GetString(item.Fields["Address Label"]);
            AddressLabelCssClass = StringUtil.GetString(item.Fields["Address Label Css Class"]);
            AddressCssClass = StringUtil.GetString(item.Fields["Address Css Class"]);
            AddressDivCssClass = StringUtil.GetString(item.Fields["Address Div Css Class"]);
            AddressPlaceholderText = StringUtil.GetString(item.Fields["Address Placeholder Text"]);

            // add the rest of the fields here
        }

                // override UpdateItemFields
        protected override void UpdateItemFields(Item item)
        {
            // upon save
            base.UpdateItemFields(item);

            // Save updated fields
            item.Fields["Address Label"]?.SetValue(AddressLabel , true);
            item.Fields["Address Label Css Class"]?.SetValue(AddressLabelCssClass, true);
            item.Fields["Address Css Class"]?.SetValue(AddressCssClass, true);
            item.Fields["Address Div Css Class"]?.SetValue(AddressDivCssClass, true);
            item.Fields["Address Placeholder Text"]?.SetValue(AddressPlaceholderText, true);

                        // add the rest of the fields here
                    }

    }
}

Create a View File

Next, let’s create a view file to go with our new class. I’ve named it AddressComplete.cshtml. The default location for Sitecore Forms views are stored inside website/Views/Formbuilder/FieldTemplates. I stored mine inside website/Views/Formbuilder/Custom.

 @using Sitecore.ExperienceForms.Mvc.Html
@model MyProject.Feature.Sitecore.Forms.Fields.AddressCompleteViewModel

<div class="@Model.CssClass">
    <div class="@Model.AddressDivCssClass">
        <label for="@Html.IdFor(m => Model.Value)" class="@Model.AddressLabelCssClass">@Model.AddressLabel</label>
        <input id="@Html.IdFor(m => Model.Value)" name="@Html.NameFor(m => Model.Value)" class="@Model.AddressCssClass" type="text" value="@Model.Value" placeholder="@Model.PlaceholderText" data-sc-field-name="@Model.Name" />
    </div>
    <div class="@Model.CityDivCssClass">
        <label class="@Model.CityLabelCssClass">@Model.CityLabel</label>
        <input id="@Html.IdFor(m => Model.CityValue)" name="@Html.NameFor(m => Model.CityValue)" value="@Model.CityValue" type="text" class="@Model.CityCssClass" placeholder="@Model.CityPlaceholderText" data-sc-field-name="@Model.CityFieldName" />
    </div>
    <div class="@Model.ProvinceDivCssClass">
        <label class="@Model.ProvinceLabelCssClass">@Model.ProvinceLabel</label>
        <input id="@Html.IdFor(m => Model.ProvinceValue)" name="@Html.NameFor(m => Model.ProvinceValue)" value="@Model.ProvinceValue" type="text" class="@Model.ProvinceCssClass" data-sc-tracking="@Model.IsTrackingEnabled" data-sc-field-name="@Model.ProvinceFieldName" />
    </div>
    <div class="@Model.PostalCodeDivCssClass">
        <label class="@Model.PostalCodeLabelCssClass">@Model.PostalCodeLabel</label>
        <input id="@Html.IdFor(m => Model.PostalCodeValue)" name="@Html.NameFor(m => Model.PostalCodeValue)" value="@Model.PostalCodeValue" type="text" class="@Model.PostalCodeCssClass" placeholder="@Model.PostalCodePlaceholderText" data-sc-tracking="@Model.IsTrackingEnabled" data-sc-field-name="@Model.PostalCodeFieldName" />
    </div>
    <div class="@Model.CountryDivCssClass">
        <label class="@Model.CountryLabelCssClass">@Model.CountryLabel</label>
        <input id="@Html.IdFor(m => Model.CountryValue)" name="@Html.NameFor(m => Model.CountryValue)" value="@Model.CountryValue" type="text" class="@Model.CountryCssClass" data-sc-tracking="@Model.IsTrackingEnabled" data-sc-field-name="@Model.CountryFieldName" />
    </div>
</div>

Create the Form Elements Pane for Forms Builder

Our next goal is to create a drag and droppable element inside the Sitecore Forms Builder, as well as have editable fields. Here’s a few pictures of our end goal.

Form builder UI showing draggable Text and Address Complete elements under Basic form elements

Address Complete form settings with expandable sections for address details

Address Complete field configuration showing label, placeholder, error message, and CSS class settings

  1. Switch to the Core database and open up the Content Editor.
  2. Navigate to /sitecore/client/Applications/FormsBuilder/Components/Layouts/PropertyGridForm/PageSettings/Settings . If you’re looking for it manually, FormsBuilder is actually labeled Forms.

    Sitecore content tree showing the path to Forms layout components under the Applications section

  3. Right click on the folder, and hit Insert from Template, using /sitecore/client/Business Component Library/version 2/Layouts/Renderings/Forms/Form/Form Parameters. Name it AddressComplete, and make sure IsVisible is checked.

    Appearance settings panel with tooltip input and visibility checkbox enabled

  4. Right click on the new AddressComplete item and Insert from template again, this time using /sitecore/client/Applications/FormsBuilder/Common/Templates/FormSection. Add five FormSection items, naming them:

    • Address
    • City
    • Province
    • PostalCode
    • Country

There are two fields for our new items, ConfigurationItem, and ControlDefinitions. They must all be unique. Any duplicates will have the FormsBuilder spinning and a vague error message appearing in the console.

Create New Expanders for ConfigurationItem

  1. Go to /sitecore/client/Applications/FormsBuilder/Components/Layouts/PropertyGridForm/PageSettings/Common/Sections. Right-click and add a new folder from the template /sitecore/templates/Common/Folder named AddressComplete.
  2. Inside the new AddressComplete folder, add five new items using this template: /sitecore/client/Business Component Library/version 2/Layouts/Renderings/Containers/Expander/Expander Parameter. As you’ve probably already guessed, name them:
    • AddressExpander
    • CityExpander
    • CountryExpander
    • PostalCodeExpander
    • ProvinceExpander
  3. Now lets go back to ~/Property Editor Settings/AddressComplete and edit the ConfigurationItem field for each FormSection item.
    • e.g. Address: change the value in the dropdown to sitecore/client/Applications/FormsBuilder/Components/Layouts/PropertyGridForm/PageSettings/Common/Sections/AddressComplete/AddressExpander.
    • Repeat with the four remaining items.

Create ControlDefinitions for each FormSection

  1. Right click on Address and Insert from template using: /sitecore/client/Business Component Library/version 2/Layouts/Renderings/Forms/Form/Templates/FormTextBox Parameters.
  2. Create items with the same names as the template.
    • Address Css Class
    • Address Div Css Class
    • Address Placeholder Class
    • etc
  3. Here are the Appearance settings for the items.

    Appearance settings panel with enabled and visible checkboxes, tooltip input, and input type set to

  4. Scroll down to the Form section and fill it out like so. In the BindingConfiguration, use the same name as the template name, but in camelCase, eg. Address Div Css Class → addressDivCssClass.

    Form settings panel showing label position toggle, CSS binding configuration, and rendering item path

  5. Do this for Address, City, Province, PostalCode, and Country. You should end up with a tree looking like this:

  6. Edit the ControlDefinitions for each FormSection. Let’s do Address as it will be a little different.

    • We will actually be using the default Sitecore FieldName for Address, which ensures we can have multiple Address Complete elements on the form (as long as the FieldName is unique). You can find FieldName under sitecore/client/formsbuilder/components/layouts/PropertyGridForm/PageSettings/Common/Details/FieldName.

      Sitecore item selection panel

    • I used Sitecore’s default label, but you can use the custom Address Label field we created.

    • The rest of the items can be found under the FormSection we just created. Ignore the extra items I’ve added for testing.

      Sitecore item selection view highlighting selected address field CSS class properties under AddressComplete settings

    • Now do this for Country, City, Province, and PostalCode as well. For example, City should end up looking like this:

      Sitecore item details for the City form section showing template path, configuration item, and control definitions

Creating the Field Type Item

  1. Go back to the master database, and go to /sitecore/system/Settings/Forms/Field Types/Basic.
  2. Right click, and Insert from template using /sitecore/templates/System/Forms/Field Type.
    • View Path - This is the path to our view. We used Custom/AddressComplete.
    • Model Type - Our viewmodel. Ours will be MyProject.Feature.Sitecore.Forms.Fields.AddressCompleteViewModel, MyProject.Feature.Sitecore.
    • Property Editor - This is what we just created in the core database. Select Property Editor Settings/AddressComplete.
    • Field Template - The template we created at the beginning of this walkthrough. Set it to Fields/Address Complete.
    • Icon - I chose OfficeWhite/32x32/map_location2.png because it looks like a map. This will be the icon for the Address Complete element in the Forms Builder.
    • BackgroundColor - I chose Carrot. You can choose anything. This is the background color for the Address Complete element in the Forms Builder

And that is it! Open up the Forms Builder and you should see the Address Complete element under Form elements.

Drag and drop it into your new form, and start editing. Here’s what mine looks like:

Form layout preview showing input fields for mailing address, city, province, postal code, and country

Here’s a few of my CSS classes. I used Bootstrap

  • Address Div Css Class: col-sm-12 mb-4
  • City Div Css Class: col-sm-6 mb-4
  • Province Div Css Class: col-sm-6 mb-4
  • Country Div Css Class: col-sm-6 mb-4

Final Result

And here’s what it looks like after I’ve published it:

Form view with input fields for mailing address, city, province, postal code, and country

Thank you for reading my walkthrough. I hope it helped!

Gorman Headshot

Gorman Law

Full Stack Developer

Gorman is a Full Stack Developer and a University of Calgary alumni who has a background in Canada's financial industry. Outside of work, he likes to go rock climbing, try out new ice cream places, and watch sports.