Checkboxes unchecking themselves automatically - Custom Form Component

Michael Legacy asked on July 12, 2021 17:47

Hey there! Interesting issue here. I've got a custom form control built to allow for multi-select checkbox fields. The form control seemingly works great. The checkboxes are built out correctly and everything appears well....until you click one. It selects the box, then unchecks it almost immediately. You can't check any of the boxes. I am wondering if the Kentico build scripts for the form builder are doing something here?

You can preview the issue here (you need to check "yes" to the true/false question, as its conditional):

https://dev.caos.carle.org/about/contact-us

Here is my implementation code for the form component:

Form Component Itself

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CAOS.Models.FormComponents;
using Kentico.Forms.Web.Mvc;

[assembly: RegisterFormComponent(MultiselectCheckboxComponent.IDENTIFIER, typeof(MultiselectCheckboxComponent), "Multi-select Checkbox", Description = "Allows users to add a multi select checkbox field.", IconClass = "icon-cb-check-preview")]
namespace CAOS.Models.FormComponents
{
    public class MultiselectCheckboxComponent : FormComponent<MultiselectCheckboxComponentProperties, string>
    {
        public const string IDENTIFIER = "MultiselectCheckboxComponent";

        [BindableProperty]
        public string CheckboxValue { get; set; }

        public override string GetValue()
        {
            return CheckboxValue;
        }
        public override void SetValue(string value)
        {
            if (!String.IsNullOrEmpty(value))
            {
                CheckboxValue = value;
            }
            else
            {
                CheckboxValue = "";
            }
        }

    }
}

Form Component Properties

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CAOS.Models.FormComponents;
using CMS.DataEngine;
using Kentico.Forms.Web.Mvc;

namespace CAOS.Models.FormComponents
{

    public class MultiselectCheckboxComponentProperties : FormComponentProperties<string>
    {
        [DefaultValueEditingComponent(TextInputComponent.IDENTIFIER, DefaultValue = "")]
        public override string DefaultValue { get; set; }

        [EditingComponent(TextAreaComponent.IDENTIFIER, DefaultValue = "")]
        public string MultiselectItems { get; set; }

        public MultiselectCheckboxComponentProperties() : base(FieldDataType.LongText)
        {

        }
    }
}

ANDDDD the view:

@using Kentico.Forms.Web.Mvc
@using CAOS.Models.FormComponents
@using CAOS.FormBuilder.Models
@using System.Collections.Generic

@model MultiselectCheckboxComponent

@{
    var htmlAttributes = ViewData.GetEditorHtmlAttributes();
    List<Checkbox> options = new List<Checkbox>();

    string[] optionsSplit = Model.Properties.MultiselectItems.Split('|');

    foreach(var option in optionsSplit)
    {
        string[] splitOption = option.Split(';');

        Checkbox cb = new Checkbox();
        cb.Checked = false;
        cb.Label = splitOption[0];
        cb.Value = splitOption[1];

        options.Add(cb);

    }
}

<div class="grid-container noPaddingX">
    <div class="grid-x">
        @foreach (var option in options)
        {
            <div class="large-4 medium-6 small-12 cell">
                <div class="multi-checkbox">
                    <input type="checkbox" name="checkbox-@Model.BaseProperties.Guid" value="@option.Value" id="@option.Value.Replace(" ", "").ToLower()" />
                    <label for="@option.Value.Replace(" ", "").ToLower()">@option.Label</label>
                </div>
            </div> 
        }
    </div>
</div>

Recent Answers


Liam Goldfinch answered on July 12, 2021 20:00

Hi Michael

I haven't tried your code, but it might be worth trying CustomAutopostHandling set to be true. This should stop Kentico monitoring the value and trying to automatically submit (and reset) the value.

See https://docs.xperience.io/k12sp/developing-websites/form-builder-development/developing-form-components there's an example of how to utilise this property.

Regards,

0 votesVote for this answer Mark as a Correct answer

Michael Legacy answered on July 12, 2021 21:13

Seemed like a very logical answer, although doesn't change anything unfortunately. I assumed overriding that property would at least allow my checkboxes to be checked (even if there are some submission issues before adding all the javascript as well), but no dice.

I may have to submit to Kentico support.

0 votesVote for this answer Mark as a Correct answer

Sean Wright answered on July 13, 2021 15:09

Your Form Component must not be deserializing the value correctly on the server side.

The Xperience script https://dev.caos.carle.org/Kentico/Scripts/forms/updatableFormHelper.js is causing the form to be auto-submitted when it is interacted with.

The response from the submission is the updated DOM rendering of the state of the form. This response is handled by onResponse in the script:

    var onResponse = function (event) {
        if (!event.target.response.data) {
            var selectionStart = selectionEnd = null;
            if (focus && (focus.type === "text" || focus.type === "search" || focus.type === "password" || focus.type === "tel" || focus.type === "url")) {
                selectionStart = focus.selectionStart;
                selectionEnd = focus.selectionEnd;
            }

            var currentScrollPosition = $(window).scrollTop();
            $(elementIdSelector).replaceWith(event.target.responseText);
            $(window).scrollTop(currentScrollPosition);

            if (focus.id) {
                var newInput = document.getElementById(focus.id);
                if (newInput) {
                    newInput.focus();
                    setCaretPosition(newInput, selectionStart, selectionEnd);
                }
            }
        }
    };

The line $(elementIdSelector).replaceWith(event.target.responseText); is causing the issue (but not the problem), because the rendered DOM coming back from the server is overwriting the form that was just interacted with. Since the checkboxes aren't maintaining their state during the roundtrip to the server, the newly rendered DOM clears out the value selected.

0 votesVote for this answer Mark as a Correct answer

Michael Legacy answered on July 13, 2021 22:58

Gotcha, knowing I can't really update the javascript file, as it will get overwritten with any hotfix updates to it, I guess I'm gonna have to figure out why it isn't validating my input. I'm assuming it's because i'm expecting string, and each checkbox is a boolean, although the actual field itself should be returning a concatenated string based on what options are selected.

0 votesVote for this answer Mark as a Correct answer

Sean Wright answered on August 14, 2021 20:09

Michael,

Instead of writing your own HTML rendering for Form Components, try using the helpers provided by ASP.NET Core to ensure that they include the correct values so that the form submission matches the deserialization process on the server side.

@Html.CheckBoxFor() and @Html.LabelFor()

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.