Tagged: Conditional logic

Sitecore 9 Forms: Custom Control – Conditional Section

I came across a scenario to implement Conditional Section for Sitecore 9.0 to hide/show fields based on user input. This feature was introduced on Sitecore 9.1(Checkout my other blog here). Since the project is in Sitecore 9.0, I decided to create a custom control using speak. 

Let’s get started.

Step 1: Create form element in core DB using speak

  • Switch to Core DB
  • Go to /sitecore/client/Applications/FormsBuilder/Components/Layouts/PropertyGridForm/PageSettings/Settings
  • Create a template based of Form Parameters. (I couldn’t find it when i tried from Insert Template, so i duplicated the existed one- MutliLine Text. If you know, how to add Form Parameters template(not using Sitecore Rocks), please leave a comment.)

 

  • Add the FormTextBox Parameters template. Since I duplicated MultiLine Text field, it came with the Details, Validation, Styling and Advanced. I feel it’s best shortcut to create quick.
  • Fill out FormLabel, IsLableOnTop and BindingConfiguration fields. 
  • Repeat the fields as many as you need. Here i added one more to compare the value.
  • NOTE: IsLabelOnTop is unchecked for additional fields

Step 2: Create form template in Master DB

  • On Master DB, create a custom template under Basic/Lists/Security/Structure folders based on Field Type template(/sitecore/templates/System/Forms/Field Type). I created under Structure Section as it’s Condition Section.
  • Fill out Property Editor field by choosing the custom control that was created in Core DB. You can see all the fields listed shown in below screen shot. 
  • Fields(View Path, Model Type)will be filled out after creating code behind and razor view files.

Step 3: Create model and view in Visual Studio

  • Create model and view in project under Helix structure
    public class ConditionalViewModel : FieldViewModel
    {
        public string TargetField { get; set; }
        public string TrueValue { get; set; }

        protected override void InitItemProperties(Item item)
        {
            base.InitItemProperties(item);

            TargetField = StringUtil.GetString(item.Fields["Target Field"]);
            TrueValue = StringUtil.GetString(item.Fields["Show Value"]);
        }

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

            item.Fields["Target Field"]?.SetValue(TargetField, true);
            item.Fields["Show Value"]?.SetValue(TrueValue, true);
        }
    }
@using Sitecore.ExperienceForms.Models
@using Sitecore.ExperienceForms.Mvc.Html
@using Sitecore.Mvc
@model  Sitecore.Project.Example.Views.CustomControl.ConditionalViewModel

@{
    var viewModel = Model is IViewModel vModel ? vModel : null;
}

<div @(Sitecore.Context.Request.QueryString["sc_formmode"] != null ? "" : "hidden") class="@Model.CssClass cond-@Model.targetField-@Model.trueValue">
    @Html.RenderFields(viewModel)
</div>

@if (Sitecore.Context.Request.QueryString["sc_formmode"] == null)
    {
        <script type="text/javascript">
            const condArr = [];

            function initConditional() {
                const conditionals = document.querySelectorAll('[class*="cond-"');
                conditionals.forEach((e) => {
                    e.className.split(" ").forEach((c) => {
                        if (c.includes('cond-')) {
                            condArr.push(parseClassName(c));
                        }
                    });
                });
                condArr.forEach((cond) => {
                    const element = document.getElementsByClassName(cond.field_name)[0];
                    element.setAttribute("data-cond", cond.field_name);
                    element.onchange = () => {
                        conditionalChange(element, condArr);
                    }
                });
            }

            function conditionalChange(element, condArr) {
                condArr.forEach((cond) => {
                    if (cond.field_name === element.getAttribute("data-cond")) {
                        if (cond.value === element.value) {
                            document.getElementsByClassName(cond.class)[0].removeAttribute("hidden");
                        } else {
                            document.getElementsByClassName(cond.class)[0].setAttribute("hidden", "true");
                        }
                    }
                })
            }

            function parseClassName(class_name) {
                const arr = class_name.split("-");
                if (arr.length < 3) {
                    console.log(`Malformed className: ${class_name}`);
                } else {
                    const obj = {
                        class: class_name,
                        field_name: arr[1],
                        value: arr[2]
                    }
                    return obj;
                }
            }

            initConditional();
        </script>

Step 4: Update the template fields

Now you should see the new form control on the elements panel. Drag and Drop to any form and fill out the Target Field and True Value fields appropriately and put any element(s) inside Conditional Section to show/hide the element(s).

Don’t forget to publish all the templates and forms!

Happy Sitecoring! Leave a comment if you have any questions.

0

Sitecore 9.1 Forms: Conditional Logic

Conditional Logic is great new feature introduced in Sitecore 9.1 Forms. Basically you can add conditions to show/hide fields based on user input.

In this example below I set up a drop down and couple of sections that show/hide the section(you can go fields as well) based on user interaction.

My simple conditional logic form

Now I added the conditions to drop-down list by clicking on the Conditions section in the form elements pane.

Edit conditions to add new condition logic

Now are you wondering why the condition logic looks weird? Here is how it works –

  • All Condition are evaluated and applied in sequence.
  • Foreach condition, if the Condition matches, then apply selected action. Else, apply inverse of selected action.

Added the form to a web page and here is how my output looks –

When I chose 1, showed the Attendee #1 section
When I chose 2, showed both Attendees section

1. Dropdown Selection: Empty

  • Condition 1 Evaluation = False. Inverse selected action (Hide section1 and section2)
  • Condition 2 Evaluation = True. Apply selected action (Hide section1)

Results: Hide both section1 and section2

2. Dropdown Selection: 1

  • Condition 1 Evaluation = False. Inverse selected action (Hide section1 and section2)
  • Condition 2 Evaluation = False. Inverse selected action (Show section1)

Results: Show section1 and hide section2

3. Dropdown Selection: 2

  • Condition 1 Evaluation = True. Apply selected action (Show section1 and section2)
  • Condition 2 Evaluation = False. Inverse selected action (Show section1)

Results: Show both section1 and section2

Now you have the cool working conditional logic on the form. Any questions, please leave a comment.

Happy sitecoring!

2