This is a migrated thread and some comments may be shown as answers.

Setting value() after (re)read selects a value not in list

2 Answers 976 Views
DropDownList
This is a migrated thread and some comments may be shown as answers.
Jay
Top achievements
Rank 2
Iron
Iron
Veteran
Jay asked on 13 Apr 2016, 01:22 PM

I've got a drop down list declared as follows

@(Html.Kendo().DropDownList()
    .Name("CodeDropDown")
    .OptionLabel(" ")
    .DataValueField("Code")
    .DataTextField("DisplayDescription")
    .DataSource(source =>
    {
        source.Read(read =>
        {
            read.Action("_CodeDropDown", "Gainful")
                .Data("CodeDropDownData");
        })
        .Events(events => events.Error("onCodeDropDownError"))
        .ServerFiltering(true);
    })
    .AutoBind(true)
    .Animation(false)
    .HtmlAttributes(new { style = "width: 512px; font-size: 12px;" })
    .Events(events => events.Change("onCodeDropDownChange"))
)

I then also have a checkbox which when toggled, causes a reread via this function:

function loadCodeDropdownList() {
    var codeList = $("#CodeDropDown").data("kendoDropDownList");
    codeList.dataSource.read(CodeDropDownData());
}

This works great; the items in the dropdown change and everything is fine. I have seen some examples where a refresh() is invoked on the DDL after the read, but that didn't seem to be necessary for me.

So what's the problem? Some of the items in the lists overlap so if an item is currently selected which isn't in the newly read data, I'm trying to clear it. My naive approach was to get the value, read the new data, set the value again and if the selectedIndex isn't then set, set the value to null, as in

function loadCodeDropdownList() {
    var codeList = $("#CodeDropDown").data("kendoDropDownList");
    var code = codeList.value();
    var oldSel = codeList.selectedIndex;
    codeList.dataSource.read(CodeDropDownData());
    codeList.refresh();         // doesn't seem to matter if this is here
    codeList.value(code);
    if (codeList.selectedIndex == 0) {
        // selectedIndex is always the same as it was before the read
        codeList.value(null);
    }
}

However, this doesn't work. The value always gets set, even if it's not in the newly read items and the selectedIndex goes back to what it was.

I've also tried setting the value to null before the read, and that doesn't seem to help; true, the value becomes null and the selectedIndex is zero, but then setting the value still results in it getting set to a value not in the list and the selectedIndex goes back to what it was, even though it may be greater than the number of items that were just read.

What I have noticed, though, is that setting a breakpoint on the line where I set the value after the read makes it work. When the breakpoint is hit, the value is no longer displayed in the drop down list, and the rest works as expected. But if I just let it run, it doesn't work.

So am I running into some kind of timing issue? I've tried binding to the dataBound event and doing the setting there, but it works just the same.

2 Answers, 1 is accepted

Sort by
0
Jay
Top achievements
Rank 2
Iron
Iron
Veteran
answered on 13 Apr 2016, 02:14 PM

Here's what I ended up with. It appears that the drop down list's items are not yet repopulated when the dataBound event fires, but the dataSource's data is, so I was able to use that. Still seems a bit hacky though.

function loadCodeDropdownList() {
    var codeList = $("#CodeDropDown").data("kendoDropDownList");
    var oldVal = codeList.value();
    if (oldVal != null && oldVal != "") {
        codeList.one("dataBound", function (e) {
            var data = codeList.dataSource.data();
            var newVal = "";
            for (var k = 0; k < data.length; k++) {
                if (oldVal == data[k].Code) {
                    newVal = oldVal;
                    break;
                }
            }
            codeList.value(newVal);
            if (newVal == "") {
                codeList.trigger("change");
            }
        });
    }
    codeList.dataSource.read(CodeDropDownData());
}

0
Ivan Danchev
Telerik team
answered on 15 Apr 2016, 12:26 PM
Hello Jay,

It seems timing has indeed been responsible for the item not being set as selected when using the value() method. I tested it setting a timeout and it worked at my end:
function loadCodeDropdownList() {
    var codeList = $("#CodeDropDown").data("kendoDropDownList");
    var code = codeList.value();
    var oldSel = codeList.selectedIndex;
    codeList.dataSource.read(CodeDropDownData("rebindDDL"));
    setTimeout(function () {
        codeList.value(code);
    }, 500);
}

Regards,
Ivan Danchev
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
DropDownList
Asked by
Jay
Top achievements
Rank 2
Iron
Iron
Veteran
Answers by
Jay
Top achievements
Rank 2
Iron
Iron
Veteran
Ivan Danchev
Telerik team
Share this question
or