PuneetGarg
Jan 28, 2022
  859
(1 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
How to use CacheTagHelper with content areas in Optimizely CMS 12

I might be going out on a limb here - if you have a better solution, feel very free to share it!  Upgrading your Optimizely web application from .N...

Andreas J | Dec 2, 2022

The 1001st Piece in your 1000 Piece Puzzle: .NET Default Interface Functions

I was recently working with a client who wanted a reasonably large subsystem added to Optimizely that would add automated management to their...

Greg J | Nov 28, 2022 | Syndicated blog

Video Demonstration, creating a CMS12 Alloy Sample Site

Hey All Below you will find a quick video demonstration on how to install a local version of Alloy Sample based on CMS12 / .Net 6. As you will see ...

Minesh Shah (Netcel) | Nov 28, 2022

How to create an admin user I Optimizely CMS – with Episerver CLI

In this blog post I’ll show how to create an admin user for Optimizely CMS in a new environment where you don’t have access to the admin interface.

Ove Lartelius | Nov 28, 2022 | Syndicated blog