PuneetGarg
Jan 28, 2022
  2527
(2 votes)

Custom radio control form element that displays the input box CMS 12

Episerver Forms does provide a lot of built-in functionality, but sometimes it is necessary to extend that functionality, which might give you some problems or difficulties. So in this post, I'm going to share my experience while customizing the Episerver form.

Note:- I'm doing this on CMS 12 and Episerver form 5.0.1

In this, we are going to extend the ability of the Selection element by inserting a text box with them.

1. Custom form element type

Since form elements are blocks, you create them the same way as any form of IContent. Instead of inheriting from BlockData inherit it from SelectionElementBlockBase<T>, ValidatableElementBlockBase, and many others, Right now we are going to work with the selection element so we are going to use SelectionElementBlockBase.

 public class InputBoxInChoiceElementBlock : SelectionElementBlockBase<ExtendedOptionItem>
    {
        [Display(GroupName = "Information", Order = -3000)]
        [EditorDescriptor(EditorDescriptorType = typeof(CollectionEditorDescriptor<ExtendedOptionItem>))]
        public override IEnumerable<ExtendedOptionItem> Items { get; set; }

        [Ignore]
        public override string PlaceHolder { get; set; }
        [Ignore]
        public override bool AllowMultiSelect { get; set; }

        public string GetDefaultSelectedString(ExtendedOptionItem item)
        {
            string defaultValue = this.GetDefaultValue();
            return this.GetDefaultSelectedString(item, defaultValue);
        }

        public string GetDefaultSelectedString(ExtendedOptionItem item, string defaultValue)
        {
            string str = item.Value;
            return (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(defaultValue) || !((IEnumerable<string>)defaultValue.Split(',')).Contains<string>(str, (IEqualityComparer<string>)StringComparer.OrdinalIgnoreCase)) && (!item.Checked.HasValue || !item.Checked.Value || !string.IsNullOrEmpty(defaultValue)) ? string.Empty : "data-f-default-value=\"true\"";
        }
    }

2. Create a Class that inherits from IOptionItem.

This class will have all the properties of the radio button that you want to show i.e Label/Caption, Value, and others.

 public class ExtendedOptionItem : IOptionItem
    {
        [DisplayName("/episerver/forms/contentediting/optionitem/caption")]
        [Display(Order = 1000)]
        public virtual string Caption { get; set; }
        [DisplayName("/episerver/forms/contentediting/optionitem/value")]
        [Display(Order = 2000)]
        [RegularExpression("([^,])*", ErrorMessage = "/episerver/forms/contentediting/optionitem/containsinvalidcharacter")]
        public virtual string Value { get; set; }
        [DisplayName("/episerver/forms/contentediting/optionitem/checked")]
        [Display(Order = 3000)]
        public virtual bool? Checked { get; set; }
    }
    [PropertyDefinitionTypePlugIn]
    public class ExtendedOptionItemProperty : PropertyList<ExtendedOptionItem>
    {

    }

 3. Your view

You need to create your own rendering which somewhat looks like this. I didn't check for null in this code when you copy this does place your null checks.

@using (Html.BeginElement(Model, new { id = formElement.Guid, @class = "FormChoice" + cssClasses, data_f_type = "choice", aria_invalid = Util.GetAriaInvalidByValidationCssClasses(cssClasses) }, true))
{
    <fieldset aria-describedby="@Util.GetAriaDescribedByElementName(formElement.ElementName)">
       <legend class="Form__Element__Caption">@Model.Label</legend>        
            @foreach (var item in items)
            {
                var defaultCheckedString = Model.GetDefaultSelectedString(item);
                var checkedString = string.IsNullOrEmpty(defaultCheckedString) ? string.Empty : "checked";
                <label> <input type="radio" name="@formElement.ElementName" value="@item.Value" class="FormChoice__Input FormChoice__Input--Radio" @checkedString @defaultCheckedString data-f-datainput />@item.Caption</label>
            }        
        <label>
            <input type="radio" id="chk" name="@formElement.ElementName"  class="FormChoice__Input FormChoice__Input--Radio" data-f-datainput value=""/>  Other Amount ($) <input type="number" id="otherAmount" class="FormTextbox__Input wrap" data-f-datainput />
        </label>
    </fieldset>
    @Html.ValidationMessageFor(Model)
}

4. Java Script

Now we need to customize our text box like when you click on that particular radio button then only it shows and all. Do remember that by default Episerver form stores the value of the radio button, not the input box so we need to update it.

 $(document).ready(function () {
        // By Default Disable Input
        $("#otherAmount").attr('disabled', true);
        $(".wrap").css('opacity', '2');
        $("form input:radio").change(function () {
            if ($("#chk").is(":checked")) {
                $("#otherAmount").attr('disabled', false);
                $(".wrap").css('opacity', '2');
            }
            else {
                $("#otherAmount").attr('disabled', true);
                $("#otherAmount").val('');
                $(".wrap").css('opacity', '1');
            }
        });
        //Updating value of radio button
        $("#otherAmount").blur(function () {
            if ($("#chk").is(":checked")) {
                var otherAmountVal = parseInt($("#otherAmount").val());
                $("#chk").attr("value", otherAmountVal);
            }
        });
    });

That'll you need to customize the Episerver form.

Thank you

Puneet Garg

Jan 28, 2022

Comments

Please login to comment.
Latest blogs
Optimizely Forms: You cannot submit this form because an administrator has turned off data storage.

Do not let this error message scare you, the solution is quite simple!

Tomas Hensrud Gulla | Oct 4, 2024 | Syndicated blog

Add your own tools to the Optimizely CMS 12 admin menu

The menus in Optimizely CMS can be extended using a MenuProvider, and using the path parameter you decide what menu you want to add additional menu...

Tomas Hensrud Gulla | Oct 3, 2024 | Syndicated blog

Integrating Optimizely DAM with Your Website

This article is the second in a series about integrating Optimizely DAM with websites. It discusses how to install the necessary package and code t...

Andrew Markham | Sep 28, 2024 | Syndicated blog

Opticon 2024 - highlights

I went to Opticon in Stockholm and here are my brief highlights based on the demos, presentations and roadmaps  Optimizely CMS SaaS will start to...

Daniel Ovaska | Sep 27, 2024