Optgroup with the Kendo UI Combobox

Kendo UI is a great framework to use, sometimes what you are looking for is not out of the box, but it’s not really difficult to make it work as you want to.

Kendo provides a combobox and a dropdown control, the following article uses the combobox for the example but applies for both controls.

What I want to achieve is to build a combobox with an optgroup.

Here is the raw html sample

<select>
 <optgroup label="Group 1">
 <option value="Value0">Option N°0</option>
 <option value="Value1">Option N°1</option>
 <!-- ... -->
 </optgroup>
 <optgroup label="Group 2">
 <option value="Value0">Option N°0</option>
 <option value="Value1">Option N°1</option>
 <!-- ... -->
 </optgroup>
 <optgroup label="Group 3">
 <option value="Value0">Option N°0</option>
 <option value="Value1">Option N°1</option>
 <!-- ... -->
 </optgroup>
 </select>

Using kendo, you can define a combox using the MVC wrappers this way

@(Html.Kendo().ComboBox()
 .Name("democombo").HtmlAttributes(new { style = "width:300px;" })
 .Filter("contains")
 .Placeholder("Select an item ...")
 .Items(x =>
 {
 // add some values
 x.Add().Text("Group 1");
 for (int i = 0; i < 10; i++)
 {
 x.Add().Value("value" + i).Text("Option N°" + i);
 }
 x.Add().Text("Group 2");
 for (int i = 0; i < 10; i++)
 {
 x.Add().Value("value" + i).Text("Option N°" + i);
 }
 //....

}))

it will look like this :

kendo combobox

There is a nice style and a search functionality, but since there is no way to specify that we want an optgroup, you cannot spot the difference between a simple item and a “group” item

Fortunately, it’s not that hard to make it work like if this option was existing.

Kendo ships with a template engine that will help

if we change a bit our code to make a clever user of the template :


@(Html.Kendo().ComboBox()
 .Name("democombo").HtmlAttributes(new { style = "width:300px;" })
 .Filter("contains")
 .Placeholder("Select an item ...")
 .Items(x =>
 {
x.Add().Text("Group 1").Value("optgroup");// notice that we give a value
 // ...
}).TemplateId("scriptTemplate"))

the template

// we use the value
<script id="scriptTemplate" type="text/x-kendo-template">
 # if ( Value=="optgroup") { #
 <div class="optgroup">#=Text#</div>
 # } else { #
 <div class="option">#=Text#</div> # } #
</script>

and the css


.k-list .k-item .optgroup {
 background: #fff;
 color: #000;
 font-weight: bold;
 }
 .k-list .k-item .option {
 padding-left: 15px;
 }

we are getting this result

kendo ui template

It’s nice but there is still two problems: the style on hover change, and the item is clickable

we can make use of the kendo combobox events to resolve that :


@(Html.Kendo().ComboBox()
 .Name("democombo").HtmlAttributes(new { style = "width:300px;" })
 .Filter("contains")
 .Placeholder("Select an item ...")
 .Items(x =>
 {
x.Add().Text("Group 1").Value("optgroup");
// ...
}).TemplateId("scriptTemplate").Events(events =>
 {
 events.DataBound(@<text>function(e){
// disable the click, and add a special class on the parent (which is the real item)
       $(".optgroup").parent().click(false).addClass("optgrouplistitem");
 }</text>);>
 }))

Some CSS to override the normal kendo “hover” style


.k-popup .k-list .k-item.optgrouplistitem.k-state-hover{
 border: none;
 color: #000;
 border-radius: 0;
 background: none;
 padding: 1px 5px 1px 5px;
 box-shadow: none;
 }

and we end with this

kendo optgroup

Complete code

<style type="text/css">
 .k-list .k-item .optgroup {
 background: #fff;
 color: #000;
 font-weight: bold;
 }

 .k-popup .k-list .k-item.optgrouplistitem.k-state-hover {
 border: none;
 color: #000;
 border-radius: 0;
 background: none;
 padding: 1px 5px 1px 5px;
 box-shadow: none;
 }

.k-list .k-item .option {
 padding-left: 15px;
 }
</style>

 

<script id="scriptTemplate" type="text/x-kendo-template">
 # if ( Value=="optgroup") { #
 <div class="optgroup">#=Text#</div>
 # } else { #
 <div class="option">#=Text#</div> # } #
</script>

 

@(Html.Kendo().ComboBox()
 .Name("democombo").HtmlAttributes(new { style = "width:300px;" })
 .Filter("contains")
 .Placeholder("Select an item ...")
 .Items(x =>
 {
 x.Add().Text("Group 1").Value("optgroup");
 for (int i = 0; i < 10; i++)
 {
 x.Add().Value("value" + i).Text("Option N°" + i);
 }
 x.Add().Text("Group 2").Value("optgroup");
 for (int i = 0; i < 10; i++)
 {
 x.Add().Value("value" + i).Text("Option N°" + i);
 }
 x.Add().Text("Group 3").Value("optgroup");
 for (int i = 0; i < 10; i++)
 {
 x.Add().Value("value" + i).Text("Option N°" + i);
 }

}).TemplateId("scriptTemplate").Events(events =>
 {

events.DataBound(@<text>function(e){
 $(".optgroup").parent().click(false).addClass("optgrouplistitem");
 }</text>);
 }))

Incoming search terms:

  • kendo combobox
  • kendoComboBox template tree
  • kendoDropDownList and optgroup
  • kendo select group items
  • kendocombobox
  • optgroup filter
  • kendo ui model for combobox
  • Kendo() DropDownList TemplateId
  • kendo optgroup
  • filter the kendo drop down list with 2 or 3 drop donlist