virtual Boolean|Object(default: false)

Enables the virtualization feature of the widget. The configuration can be set on an object, which contains two properties - itemHeight and valueMapper.

For detailed information, refer to the article on virtualization.

virtual.itemHeight Number(default: null)

Specifies the height of the virtual item. All items in the virtualized list must have the same height. If the developer does not specify one, the framework will automatically set itemHeight based on the current theme and font size.

virtual.mapValueTo String(default: "index")

The changes introduced with the Kendo UI R3 2016 release enable you to determine if the valueMapper must resolve a value to an index or a value to a dataItem. This is configured through the mapValueTo option that accepts two possible values - "index" or "dataItem". By default, the mapValueTo is set to "index", which does not affect the current behavior of the virtualization process.

For more information, refer to the article on virtualization.

virtual.valueMapper Function(default: null)

The widget calls the valueMapper function when the widget receives a value, that is not fetched from the remote server yet. The widget will pass the selected value(s) in the valueMapper function. In turn, the valueMapper implementation should return the respective data item(s) index/indices.

Important

As of the Kendo UI R3 2016 release, the implementation of the valueMapper function is optional. It is required only if the widget contains an initial value or if the value method is used.

Example - DropDownList widget with a virtualized list

<input id="orders" style="width: 400px" />
<script>
    $(document).ready(function() {
        $("#orders").kendoDropDownList({
            template: ({ OrderID, ShipName, ShipCountry }) => `<span class="order-id">${OrderID}</span> ${ShipName}, ${ShipCountry}`,
            dataTextField: "ShipName",
            dataValueField: "OrderID",
            filter: "contains",
            virtual: {
                itemHeight: 26,
                valueMapper: function(options) {
                    $.ajax({
                        url: "https://demos.telerik.com/kendo-ui/service/Orders/ValueMapper",
                        type: "GET",
                        dataType: "jsonp",
                        data: convertValues(options.value),
                        success: function (data) {
                            //the **data** is either index or array of indices.
                            //Example:
                            // 10258 -> 10 (index in the Orders collection)
                            // [10258, 10261] -> [10, 14] (indices in the Orders collection)

                            options.success(data);
                        }
                    })
                }
            },
            height: 520,
            dataSource: {
                type: "odata",
                transport: {
                    read: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Orders"
                },
                schema: {
                    model: {
                        fields: {
                            OrderID: { type: "number" },
                            Freight: { type: "number" },
                            ShipName: { type: "string" },
                            OrderDate: { type: "date" },
                            ShipCity: { type: "string" }
                        }
                    }
                },
                pageSize: 80,
                serverPaging: true,
                serverFiltering: true
            }
        });
    });

    function convertValues(value) {
        var data = {};

        value = $.isArray(value) ? value : [value];

        for (var idx = 0; idx < value.length; idx++) {
            data["values[" + idx + "]"] = value[idx];
        }

        return data;
    }
</script>

Example - DropDownList widget with declarative virtualization config

<div class="demo-section k-header">
    <h4>Search for shipping name</h4>
    <input id="orders" style="width: 400px"
           data-role="dropdownlist"
           data-bind="value: order, source: source"
           data-text-field="ShipName"
           data-value-field="OrderID"
           data-filter="contains"
           data-virtual="{itemHeight:26,valueMapper:orderValueMapper}"
           data-height="520"
           />
</div>

<script>
    $(document).ready(function() {
        var model = kendo.observable({
                order: "10548",
          source: new kendo.data.DataSource({
            type: "odata",
            transport: {
              read: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Orders"
            },
            schema: {
              model: {
                fields: {
                  OrderID: { type: "number" },
                  Freight: { type: "number" },
                  ShipName: { type: "string" },
                  OrderDate: { type: "date" },
                  ShipCity: { type: "string" }
                }
              }
            },
            pageSize: 80,
            serverPaging: true,
            serverFiltering: true
          })
        });

        kendo.bind($(document.body), model);
    });

    function orderValueMapper(options) {
        $.ajax({
          url: "https://demos.telerik.com/kendo-ui/service/Orders/ValueMapper",
          type: "GET",
          dataType: "jsonp",
          data: convertValues(options.value),
          success: function (data) {
            options.success(data);
          }
        })
    }

    function convertValues(value) {
        var data = {};

        value = $.isArray(value) ? value : [value];

        for (var idx = 0; idx < value.length; idx++) {
            data["values[" + idx + "]"] = value[idx];
        }

        return data;
    }
</script>
In this article