London Dev Meetup Rescheduled! Due to unavoidable reasons, the event has been moved to 21st May. Speakers remain the same—any changes will be communicated. Seats are limited—register here to secure your spot!

KennyG
May 31, 2019
  4259
(4 votes)

Episerver Forms – Making Dropdown Lists Multilingual

I recently ran into an issue with Episerver Forms and multi-language. Specifically, the Selection (Dropdown) Block that is part of the Basic Elements. Things like the label and the placeholder text can be translated but the actual <options> only pull from the base language of the block. This is a deeper dive into my forum discussion.

The problem

Say you've got a new form and have added a dropdownlist (Selection Block).

If you switch to another language and edit that version of the block you aren't able to translate the items (<options>).

So either language will only show the base language options. 

Now the reasoning for this may be that you need the form's submitted value to always be the same regardless of the visitor's language.

A Solution

I decided to create a custom Culture Specific Selection block. This would allow me to use the regular Out-Of-The-Box Selection Element blocks for most cases and my custom one when I needed it. 

I inherited from SelectionElementBlock and overrode the Items:

using EPiServer.DataAbstraction;
using EPiServer.DataAnnotations;
using EPiServer.Forms.EditView.Models.Internal;
using EPiServer.Forms.Implementation.Elements;
using System.Collections.Generic;

namespace SelectionBlockExample.Models.Blocks
{
    [ContentType(
        DisplayName = "Culture Specific SelectionBlock", 
        GUID = "xxxxx",
        Description = "Use when you need the options in another language",
        GroupName = "Custom Elements")]
    public class CultureSpecificSelectionBlock : SelectionElementBlock
    {
        [CultureSpecific]
        public override IEnumerable<OptionItem> Items { get; set; }
    }
}

 I also needed to provide the view. 

<%--
    ====================================
    Version: 4.15.1. Modified: 20180726
    ====================================
--%>

<%@ import namespace="System.Web.Mvc" %>
<%@ Import Namespace="EPiServer.Shell.Web.Mvc.Html" %>
<%@ import namespace="EPiServer.Forms.Helpers.Internal" %>
<%@ import namespace="EPiServer.Forms.Implementation.Elements" %>
<%@ import namespace="SelectionBlockExample.Models.Blocks" %>
<%@ control language="C#" inherits="ViewUserControl<CultureSpecificSelectionBlock>
    " %>

    <%
    var formElement = Model.FormElement;
    var labelText = Model.Label;
    var placeholderText = Model.PlaceHolder;
    var defaultOptionItemText = !string.IsNullOrWhiteSpace(placeholderText) ? placeholderText : 
        Html.Translate(string.Format("/episerver/forms/viewmode/selection/{0}", Model.AllowMultiSelect ? "selectoptions" : "selectanoption"));
    var defaultOptionSelected = !Model.AllowMultiSelect && !Model.Items.Any(x => x.Checked.HasValue && x.Checked.Value) ? "selected=\"selected\"" : "";
    var items = Model.GetItems();
    var defaultValue = Model.GetDefaultValue();
    %>

    <% using(Html.BeginElement(Model, new { @class="FormSelection" + Model.GetValidationCssClasses(), data_f_type="selection" })) { %>
    <label for="<%: formElement.Guid %>" class="Form__Element__Caption"><%: labelText %></label>
    <select name="<%: formElement.ElementName %>" id="<%: formElement.Guid %>" <%: Model.AllowMultiSelect ? "multiple" : "" %>  <%= Model.AttributesString %> data-f-datainput>
        <option disabled="disabled" <%= defaultOptionSelected %> value=""><%: defaultOptionItemText %></option>
        <%
        foreach (var item in items)
        {
            var defaultSelectedString = Model.GetDefaultSelectedString(item, defaultValue);
            var selectedString = string.IsNullOrEmpty(defaultSelectedString) ? string.Empty : "selected";
        %>
        <option value="<%: item.Value %>" <%= selectedString %> <%= defaultSelectedString %> data-f-datainput><%: item.Caption %></option>
        <% } %>
    </select>
    <%= Html.ValidationMessageFor(Model) %>
    <% } %>

If you are new to custom FormElement blocks you need to add your view under Shared/Elementblocks.

You can copy and tweak the existing Selection block by getting the view from the EPiServer.Forms.zip file located in the modules folder.

I just had to update the view to use my new class.

Once you're ready the new Form Element should show up in the Custom Elements group.

Now use this instead of the original. 

Like I alluded to earlier, you may want the Choice to be in the selected language and the Value to always be in the base language so your submissions are consistent.

Alternative

Another alternative suggested by Paul Gruffydd was to use a initialization module to force all SelectionElementBlocks to be localizable but I like being able to give the editor the choice which element to use. 

Have your own or better solution? Let me know!

May 31, 2019

Comments

Please login to comment.
Latest blogs
Routing to a page in SaaS CMS

More early findings from using a SaaS CMS instance; setting up Graph queries that works for both visitor pageviews and editor previews.

Johan Kronberg | Apr 14, 2025 |

Developer Meetup - London, 24th April 2025

Next Thursday, 24th April will be Candyspace 's first Optimizely Developer Meetup, and the first one held in London this year! We've have some...

Gavin_M | Apr 14, 2025

Successful Digitalization for SMEs: How Optimizely One can Revolutionize Your Business Processes

"Achieve digital excellence with Optimizely One: Boost efficiency, delight customers, secure growth." In today's digital world, it's crucial for...

Frank Hohmeyer | Apr 11, 2025

Personalized Optimizely CMS Website Search Experiences Azure AI Search & Personalizer

In the last blog, we discussed Integrating the Optimizely CMS website with Azure AI search. Now let’s take a bit more advanced topic to serve...

Naveed Ul-Haq | Apr 10, 2025 |