Multi-Select with check boxes

1 Answer 1358 Views
MultiSelect
AP
Top achievements
Rank 1
Iron
Iron
Veteran
AP asked on 17 May 2022, 03:31 PM

I'm updating an application (based on version v2021.2.511) porting bits of code to a new application based on v2022.2.510). I'm trying to get a multi-select drop-down list with checkboxes working.  The requirment is for the check boxes to be checked if an item in the list is selected, and unchecked if it is unselected.

The following styles were added:-


<style type="text/css">

    @*.EditButton {
        display:@ViewBag.EditButton;
    }*@

    .nopadding {
   padding-left: 0 !important;
    padding-right: 0 !important;

}

 .k-multiselect:after {
         content: "\25BC";
         position: absolute;
         top: 30%;
         right: 10px;
         font-size: 10px;
     }

    .k-multiselect-wrap.k-floatwrap li.k-button .k-icon.k-i-close
  {
    display: none !important;
  }

}
</style>

<style scoped>

    .k-widget.k-multiselect {
        width: 300px;
        vertical-align: middle;
        display: inline-block;
    }
</style>

The multiselect definition is:-


 @(Html.Kendo().MultiSelect()
                                .Name("msSpecialty")
                                .DataValueField("Code")
                                .DataTextField("Description")
                                    .Placeholder("All specialties...")
                                    .ItemTemplate("<input type='checkbox' /> #=data.Description#")
                                    .AutoClose(false)
                                    .ClearButton(false)
                                    .TagMode(TagMode.Multiple)
                                //.TagTemplate(" <span>#= Description #</span>")

                                .Events(e => e.Close("onSpecListChange").DataBound("specListDataBound").Change("chkFix"))
                                .DataSource(src => src.Read(rd => rd.Action("getOpenClockSpecDDL", "Validation")).ServerFiltering(false))
                                    .HtmlAttributes(new { style = "width:300px;" })
                        )

And the javascript:-


 var currentSpec = '-X-';

 function onSpecListChange() {
        var items = this.ul.find("li");
        checkInputs(items);
        //check if list has changed since last close, if so, fire change event (Avoids unnescessary requeries)

        var multiselect = $("#msSpecialty").data("kendoMultiSelect");
        var Svalue = multiselect.value().sort();

        var SpecString = "";

        if (Svalue != null & Svalue != '') {


            for (i = 0; i < Svalue.length; i++) {
                SpecString = SpecString + Svalue[i] + "|";
            }

        }
        else {
            SpecString = "-X-";
        }



        if (currentSpec != SpecString) {
            onChange();
        }




    }

    function checkInputs(elements) {
        elements.each(function () {
            var element = $(this);
            var input = element.children("input");

            input.prop("checked", element.hasClass("k-state-selected"));
        });
    }

    function specListDataBound() {

        var items = this.ul.find("li");
        setTimeout(function () {
            checkInputs(items);
        });

    }

    function chkFix() {
        var items = this.ul.find("li");
        setTimeout(function () {
            checkInputs(items);
        });
    }

 function onChange()
    {

    }

I assume the styles have changed between the versions, because this code is not working. The checkboxes aren't being checked on selection, the list doesn't close when clicked away from, and the closed multiselect isn't displaying properly.  How can I get it working as it was please?

1 Answer, 1 is accepted

Sort by
0
Ivan Danchev
Telerik team
answered on 20 May 2022, 10:02 AM

Hello Andrew,

There are two issues in the js logic within the checkInputs function you posted:

function checkInputs(elements) {
    elements.each(function () {
        var element = $(this);
        var input = element.children("input");

        input.prop("checked", element.hasClass("k-state-selected"));
    });
}
1. With the current rendering of the MultiSelect, the li element of the items in the popup contains a span element. The text of the item and any additional Html added through an ItemTemplate will be rendered within that span element. This means the children method, used in the snippet above won't be able to find the input, because the children method looks only 1 level down. It should be replaced with the find method. For more details on the new rendering of the MultiSelect, refer to: https://docs.telerik.com/aspnet-mvc/html-helpers/editors/multiselect/appearance

2. The logic relies on the "k-state-selected" class, which is no longer used in the MultiSelect and other similar components after the rendering changes in R1 2022. Here's the respective documentation section, which shows how the state classes have been changed: https://docs.telerik.com/aspnet-mvc/styles-and-layout/components-rendering-overview#state-classes

These 2 issues can be resolved the following way:

function checkInputs(elements) {
	elements.each(function () {
		var element = $(this);
		var input = element.find("input");

		input.prop("checked", element.hasClass("k-selected"));
	});
}

 

Regards,
Ivan Danchev
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Tags
MultiSelect
Asked by
AP
Top achievements
Rank 1
Iron
Iron
Veteran
Answers by
Ivan Danchev
Telerik team
Share this question
or