Say I have a multi-select that I am populating with music artists, each artist belongs to a genre (Rock, HipHop, Blues etc), so the POCO would look something like this:
public class Artist {
public int ArtistID { get; set; }
public string ArtistName { get; set; }
public int GenreID { get; set; } //FK
}
and the data might look like this:
[
{
"ArtistId": 1,
"ArtistName": "AC/DC",
"GenreID": 1
},
{
"ArtistId": 2,
"ArtistName": "Rolling Stones",
"GenreID": 1
},
{
"ArtistId": 3,
"ArtistName": "Jay Z",
"GenreID": 2
},
{
"ArtistId": 4,
"ArtistName": "Snoop Dogg",
"GenreID": 2
},
{
"ArtistId": 5,
"ArtistName": "BB King",
"GenreID": 3
},
{
"ArtistId": 6,
"ArtistName": "Muddy Waters",
"GenreID": 3
}
]
I want to limit them to only selecting one artist for any given genre. So for example, the control would first load with all 6 options, but if they choose 'AC/DC' I would want to filter out all artists of that genre (in this case the Rolling Stones would get removed). How best do I accomplish this? thanks
5 Answers, 1 is accepted

Hi Scott,
A possible approach to achieve the desired behavior is to keep track of the selected items. When the user select an item you could push the respective genre in a list. You could do that in the select event handler.
select: function(e){
listGenres.push(e.dataItem.GenreID)
},
When the user deselect an item, you could remove it from the list:
deselect: function(e){ var index = listGenres.indexOf(e.dataItem.GenreID); if (index > -1) { listGenres.splice(index, 1); } },
Then you could subscribe to the open event handler of the MultiSelect. In the event handler you could find all items in the MultiSelect popup. Then you could check for each dataItem if its genre is in the list of selected genres and hide the respective element if it is needed. Note, that you may need to use setTimeout method in order to ensure that the elements are rendered by the time you are trying to hide them. Below is an example of such implementation.
open: function(e){
//use setTiemout to ensure that the popup is rendered
setTimeout(function () {
//mark all elements as visible initially
$("#multiselect_listbox .k-item:hidden").show()
//retrieve the data
var data = e.sender.dataSource.data();
var items = $("#multiselect_listbox .k-item");
for (var i = 0; i < items.length; i++) {
var current = items[i];
var currentDataItem = data[i];
for (var j = 0; j < listGenres.length; j++) {
var currentValue = listGenres[j]
// check if the genre of each item is in the list with the selected items genres.
if (currentDataItem.GenreID == currentValue) {
$(current).hide()
}
}
}
})
},
Here is a Dojo example where the described steps are implemented. You could use the same approach in UI for ASP.NET MVC projects.
I hope this helps.
Regards,
Neli
Progress Telerik
Our thoughts here at Progress are with those affected by the outbreak.

Thank you Neli, that's a fine solution that I should be able to implement. Do you think it would it be possible to do this with a DropDownTree with checkboxes as well? In other words, the tree would look like
Rock
|--------AC/DC
|--------Rolling Stones
Hip-Hop
|--------Jay Z
|--------Snoop Dogg
Blues
|--------BB King
|--------Muddy Waters
and work the same way ? Not sure how I would disable a checkbox in a tree like that
Hello Scott,
To achieve similar behavior in DropDownTree I would suggest the following:
- You could subscribe to the open event of the widget. In the event handler you could find all checked checkboxes. Then you could search for the parent node and hide it. I would suggest you also to hide the checkbox of the parent node. Thus, the user will not be able to check/uncheck the parent node. You will also need to use setItmeout method to ensure that the items are rendered by the time you are trying to manipulate the HTML.
open: function(){ setTimeout(function(){ //hide the parent checkbox $(".k-icon.k-i-expand").siblings(".k-checkbox-wrapper").hide() //mark all items as visible $(".k-item[style]").removeAttr("style") var checked = $(".k-checkbox:checked") //hide the parent nodes only of the selected items for (const ch of checked) { var ulParent = $(ch).closest('ul') $(ulParent).parent().hide() } }) }
- You could also prevent the parent node from being selected. In the select event handler, you could check the text of the selected item and prevent the default behavior in case it matches the text of the parent nodes.
select: function(e){ var dataItem = e.sender.dataItem(e.node); var text = dataItem.text if(text == "Rock" || text == "Hip-Hop" || text == "Blues"){ e.preventDefault() } },
Here you fill find a Dojo example with such implementation.
I hope this helps.
Regards,
Neli
Progress Telerik
Our thoughts here at Progress are with those affected by the outbreak.
