Search code examples
javascriptkendo-uikendo-asp.net-mvckendo-comboboxkendo-ui-mvc

Selecting first item, if initial value does not exist


Here we have my combobox:

@(Html.Kendo().ComboBox()
    .Name("depots")
    .DataTextField("Text")
    .DataValueField("Value")
    .Height(500)
    .Filter(FilterType.Contains)
    .Events(ev =>
    {
        ev.Change("onDepotsChangeEvent");
        ev.DataBound("onDepotsDataBoundEvent");
        ev.Select("onDepotsSelectEvent");
    })
    .HighlightFirst(true)
    .Suggest(true)
    .Value(SOME INITIAL VALUE)
    .HtmlAttributes(new { style = "width:550px; max-width:100%;" })
    .DataSource(source => source.Custom()
        .Group(group => group.Add("Group", typeof(string)))
        .Transport(transport => transport
            .Read(read =>
            {
                // Censored ;)
            })
        )
    )
)

As you can see, I am setting an initial value with the ".Value(something something". This means that when the combobox loads, the item on the list corresponding to the value, is selected. It works fine as intended.

The problem is when there is not an item with a value corresponding to the initial set value. If that happens, the initial value is shown in the input field of the combobox. After searching around, this is apparently by design and not an error.

What I want to do is, if an item does not exist in the combobox, with the same value as the initial set value, the first item on the list should be selected.

I have searched and searched for days now, with no solution, so any help would be greatly appreciated.

In case it matters, here are the three event methods:

function onDepotsSelectEvent(e) {
    if (e.item) {
        var dataItem = this.dataItem(e.item.index());
        $.post("@Url.Action("SetSelectedDepotSession", "PartialView")", { id: dataItem.Value });
    }
}

function onDepotsChangeEvent(e)
{
    if (this.value() && this.selectedIndex === -1) {
        this._filterSource({
            value: "",
            field: this.options.dataTextField,
            operator: "contains"
        });
        this.select(1);
    }
}

function onDepotsDataBoundEvent(e)
{
    var widget = e.sender;

    if (widget.dataSource.view().length === 0) {
        widget.text("");
        widget.enable(false);
    }
}

SOLUTION

Here is the databound event code with the fix:

function onDepotsDataBoundEvent(e)
{
    var widget = e.sender;

    if (widget.dataSource.view().length === 0) {
        widget.text("");
        widget.enable(false);
    }

    if (widget.select() === -1) {
        widget.select(0);
    }
}

What it does is, at first if there is no items at all, the combobox is disabled. Then, if the initial value does not exist on the list, the first item on the list is selected instead.


Solution

  • Yes, this is an odd behaviour though. It is like if the widget adds the invalid value to its list. I checked that if you do .val() directly in the input element or .value() in the widget instance, you get the invalid value, but if you do .select(), it returns -1, as there is no DataItem related to that value. That is a start.

    What works for me is to clear the widget's value on dataBound event if the .select() returns -1. Something like:

    if (this.select() == -1) {
        this.value(null);
    }
    

    Demo