Let’s Talk

We would love to hear from you. Want to know more about
our services or have any questions? Say Hi!

Special language characters not allowed in Sitecore 10.X Forms | Solution

January 16, 2023
Special language characters not allowed in Sitecore 10.X Forms | Solution
Mitesh Patel
Mitesh Patel
Technical Head
special-language-characters-not-allowed-in-sitecore-10-X-forms-solution

When you create Sitecore Forms, it will provide you with the capability to manage multilingual forms setups. When you are creating new forms in Sitecore Forms, each of the control in the form will be created as a unique, separate item for each specific control.

In the case of the list fields where each of the list item is created as a static list item (and each list item is not rendered from the existing item), for the item names, Sitecore uses the field value if the field name or label is empty. All this is good until you want to use an invalid character in the field value or label for example like ë, ä, etc.

In this case, Sitecore overrides the value to be item name compliant and therefore the values in the list control will be changed to the item name compliant values.

Sitecore removes or deletes the incompliant characters but is that what is required by you? Do you want to be able to use language-specific characters to be displayed or even stored from your list?

We are currently using the Sitecore 10.2 form. The issue faced was with the Radio button list and the check box list. Here are the details of the Radio button list and we have used the Radio button label field in the English language version: Label, Name, Gender. Radio button Label 1: Make and Radio button Label 2: Female.

Further, we have created the form in Japanese language also and used the existing Radio button List field. Radio button Label 1: 男 and Radio button Label 2: 女性, while on clicking Apply, it takes the value but after clicking Save Sitecore Form, it doesn’t work and shows Radio button Label 1: Unnamed item and Radio button Label 2: Unnamed item.

Also, in the Check Box List, we have used the Check Box List Field in the English language version. Label name: Department, Checkbox Label 1: Development.

Furthermore, we have also created the same in the Japanese language versions with the existing field Department. Check box Label 1: 発達, while on clicking Apply, it takes the value and after clicking on Save Sitecore Form, it shows that it's not working and shows Checkbox Label 1: Unnamed item. The same issues was also faced in Sitecore 10.1 forms.

We have analyzed this issue more to identify that there were some issues in this version. We have extracted Sitecore dll and found the below solution:

The issue is that Sitecore uses ItemUtil.ProposeValidItemName when it wants to create the display name for an item. Making Sitecore Forms compliant with these different characters instead of using the ProposeValidItemName when you are creating the items, you have to simply use the listFieldItem.Text or listFieldItem.Value.

Radio Button:

special-language-characters-not-allowed-in-sitecore-10-X-forms-solution-1 special-language-characters-not-allowed-in-sitecore-10-X-forms-solution-2

Checkbox List:

special-language-characters-not-allowed-in-sitecore-10-X-forms-solution-3 special-language-characters-not-allowed-in-sitecore-10-X-forms-solution-4
Solution:

You can solve this issue by implementing a custom DataSourceSettingsManager with methods UpdateSettings and UpdateStaticItems as it gets the DisplayName field and sets the values after putting the value through ItemUtil.ProposeValidItemName(). You also need to change that so it sets the value as is, without ItemUtil.ProposeValidItemName().DisplayNames can be anything (including Japanese characters) so this was added mistakenly.

You then need to set your new and bug-fixed DataSourceSettingsManager in a config-patch file.

As an example, we replace the “ItemUtil.ProposeValidItemName(listFieldItem.Text) : ItemUtil.ProposeValidItemName(listFieldItem.Value)" with "listFieldItem.Text : listFieldItem.Value"

(from Sitecore.ExperienceForms.Mvc.DataSource.DataSourceSettingsManager.UpdateStaticItems()):

DataSourceSettingsManagerController.cs

using System; 

using System.Collections.Generic; 

using System.Linq; 

using System.Web; 

using System.Web.Mvc; 

using Sitecore; 

using System.Globalization; 

using Sitecore.Data; 

using Sitecore.Data.Items; 

using Sitecore.Diagnostics; 

using Sitecore.ExperienceForms.Extensions; 

using Sitecore.ExperienceForms.FieldSettings; 

using Sitecore.ExperienceForms.Mvc.Constants; 

using Sitecore.ExperienceForms.Mvc.DataSource; 

using Sitecore.ExperienceForms.Mvc.Models; 

namespace Addact.Web.Areas.Infrastructure 

{ 

    public class DataSourceSettingsManagerController : DataSourceSettingsManager 

    { 

        // GET: Addact/DataSourceSettingsManager 

        protected override void UpdateSettings( 

            ListFieldItemCollection settings, 

            Item fieldSettingsItem, 

            FieldSettingsContext settingsContext) 

        { 

            Assert.ArgumentNotNull((object)settings, nameof(settings)); 

            Assert.ArgumentNotNull((object)fieldSettingsItem, nameof(fieldSettingsItem)); 

            Assert.ArgumentNotNull((object)settingsContext, nameof(settingsContext)); 

            if (settingsContext.FieldItem == null) 

                return; 

            if (MainUtil.GetBool(settingsContext.FieldItem.Fields["Is Dynamic"]?.Value, false)) 
            { 
                 foreach (Item child in fieldSettingsItem.Children) 

                    child.Recycle(); 
             } 

             else 
            { 
                string displayFieldName = settingsContext.FieldItem.Fields["Display Field Name"]?.Value; 

                string valueFieldName = settingsContext.FieldItem.Fields["Value Field Name"]?.Value; 

                this.UpdateStaticItemsInternal((List<ListFieldItem>)settings, fieldSettingsItem, displayFieldName, valueFieldName); 
            } 
        } 

      protected void UpdateStaticItems( 

      List<ListFieldItem> items, 

      Item fieldSettingsItem, 

      string displayFieldName, 

      string valueFieldName) 

        { 

            Assert.ArgumentNotNull((object)items, nameof(items)); 

            Assert.ArgumentNotNull((object)fieldSettingsItem, nameof(fieldSettingsItem)); 

            for (int index = 0; index < items.Count; ++index) 

            { 
                ListFieldItem listFieldItem = items[index]; 

                if (string.IsNullOrEmpty(listFieldItem.Value)) 

                { 
                    listFieldItem.ItemId = ""; 
                } 

                else 

                { 
                    string str = ItemUtil.ProposeValidItemName(listFieldItem.Value); 

                    Item obj = ID.IsID(listFieldItem.ItemId) ? fieldSettingsItem.Database.GetItem(listFieldItem.ItemId, fieldSettingsItem.Language) : (Item)null; 

                    if (obj == null) 

                        obj = this.AddItem(str, fieldSettingsItem, new TemplateID(TemplateIds.ListFieldTemplateId)); 

                    else if (!obj.Axes.IsDescendantOf(fieldSettingsItem)) 

                        obj = obj.CopyTo(fieldSettingsItem, str); 

                    listFieldItem.ItemId = obj?.ID.ToString() ?? string.Empty; 

                    if (obj != null) 

                    { 
                        if (string.IsNullOrEmpty(valueFieldName)) 

                            valueFieldName = obj.Template.IsBasedOnTemplate(TemplateIds.ListFieldTemplateId) ? "Value" : "__ItemName"; 

                        obj.Editing.BeginEdit(); 

                        obj.Name = str; 

                        obj.Fields[valueFieldName]?.SetValue(listFieldItem.Value, false); 

                        /* Use item text or item value as displayName. 

                           Original Sitecore code uses ItemUtil.ProposeValidItemName: 

                           ... ItemUtil.ProposeValidItemName(listFieldItem.Text) : ItemUtil.ProposeValidItemName(listFieldItem.Value); */ 

                        (string.IsNullOrEmpty(displayFieldName) || obj.Fields[displayFieldName] == null ? obj.Fields[FieldIDs.DisplayName] : obj.Fields[displayFieldName])?. 

                            SetValue(!string.IsNullOrEmpty(listFieldItem.Text) ? listFieldItem.Text : listFieldItem.Value, false); 

                        obj.Fields[FieldIDs.Sortorder]?.SetValue((index * 100).ToString((IFormatProvider)CultureInfo.InvariantCulture), false); 

                        obj.Editing.EndEdit(); 

                    } 

                } 
            } 

            foreach (Item child1 in fieldSettingsItem.Children) 

            { 
                Item child = child1; 

                if (!items.Exists((Predicate<ListFieldItem>)(li => child.ID.ToString().Equals(li.ItemId, StringComparison.OrdinalIgnoreCase)))) 

                    child.Delete(); 
            } 
        } 
    } 
} 
                    

AppForm.config:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/">
<sitecore > 
    <services > 
<register serviceType="Sitecore.ExperienceForms.FieldSettings.IFieldSettingsManager`1[[Sitecore.ExperienceForms.Mvc.Models.ListFieldItemCollection, Sitecore.ExperienceForms.Mvc]], Sitecore.ExperienceForms" > 
<patch:attribute name="implementationType"> My.Assembly.Namespaces.FixedDataSourceSettingsManager, My.Assembly</patch:attribute > 
</register > 
  </services > 
</sitecore > 
</configuration > 
                    

After having applied the above solution, this issue can be resolved as you can check in the below screenshots. One is the form in ENGLISH LANGUAGE VERSION and the second is in the JAPANESE LANGUAGE VERSION.

special-language-characters-not-allowed-in-sitecore-10-X-forms-solution-5 special-language-characters-not-allowed-in-sitecore-10-X-forms-solution-6

Now, we are able to add Japanese text labels with the help of the above patch and code change.

Conclusion

In the Sitecore Forms, when creating forms, the special language characters in the radio and checkbox list were not allowed. Here in this blog, you can find the steps as to how we came across this issue and how we solved it. You can find the solution to resolve this issue if you come across it.


YOU MAY ALSO LIKE