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

Cascading Multiselect Initial Values

4 Answers 345 Views
MultiSelect
This is a migrated thread and some comments may be shown as answers.
Bob
Top achievements
Rank 1
Bob asked on 24 Sep 2014, 02:57 PM
I have created a set of 3 multiselect cascading lists.  It works fine, until...
I need to set the initial values.  IE the user selects some stuff. Saves and then returns to edit.  At this point I cannot seem to prepopulate the lists.
I know im going to go "Duh!" and hit myself in the forhead when I figure this out, but looking for any help here.  I am using MVC 5

 @(Html.Kendo().MultiSelect()
                      .Name("Trades")
                      .DataTextField("TradeName")
                      .DataValueField("Id")
                      .Placeholder("Select Trades ...")
                      .AutoBind(true)
                      .DataSource(source => source.Read(read => read.Action("GetTrades", "Skills"))
                          .ServerFiltering(true))
                      .Events(evt => evt.Change("onChangeTrades"))
                      )
 @(Html.Kendo().MultiSelect()
                          .Name("SubTrade")
                          .DataTextField("SubTradeName")
                          .DataValueField("Id")
                          .Placeholder("Select Subtrades ...")
                          .AutoBind(true)
                          .DataSource(source => source.Read(read => read.Action("GetSubTrades", "Skills")
                              .Data("subTradeFilters"))
                              .ServerFiltering(true))
                          .Events(evt => evt.Change("onChangeSubTrades"))
                      )
@(Html.Kendo().MultiSelect()
                                  .Name("Skills")
                                  .DataTextField("SkillName")
                                  .DataValueField("Id")
                                  .Placeholder("Select Skills ...")
                                  .AutoBind(false)
                                  .DataSource(source => source.Read(read => read.Action("GetSkills", "Skills")
                                      .Data("skillFilters"))
                                      .ServerFiltering(true))
                            )

and the script to go with this

    function subTradeFilters() {
        var values = $("#Trades").val().toString();
        return { text: values };
    }
    function skillFilters() {
        var trades = "";
        if ($("#Trades").val() != null) {
            trades = $("#Trades").val().toString();
        }
        var subTrades = "";
        if ($("#SubTrade").val() != null) {
            subTrades = $("#SubTrade").val().toString();
        }

        var values = JSON.stringify({ Trades: trades, SubTrades: subTrades });
        return { text: values };
    }
    function onChangeTrades() {
        filterSubTrades();
        filterSkills();
        return;
    }
    function onChangeSubTrades() {
        filterSkills();
        return;
    }
    function filterSubTrades() {
        var multiselect = $("#SubTrade").data("kendoMultiSelect");
        multiselect.dataSource.filter({});
        multiselect.dataSource.filter(subTradeFilters());
    }
    function filterSkills() {
        var multiselect = $("#Skills").data("kendoMultiSelect");
        multiselect.dataSource.filter({});
        multiselect.dataSource.filter(skillFilters());
    }

The above works GREAT until.... <Dum de dum dum music/>

I add this to the doc ready
        var tradeSel = $("#Trades").data("kendoMultiSelect");
        var subTradeSel = $("#SubTrade").data("kendoMultiSelect");
        var skillSel = $("#Skills").data("kendoMultiSelect");

        tradeSel.value(@Html.Raw(Json.Encode(Model.TradeIds)));        
        subTradeSel.value(@Html.Raw(Json.Encode(Model.SubTradeIds)));
        skillSel.value(@Html.Raw(Json.Encode(Model.SkillIds)));

Then what happens is the first box "trades" populates.
The 2nd box sits and spins and we end with the rest of the controls not rendering.properly.

it does work fine if I comment out the .Data property on the read action of the data source, but I loose the cascading effect.

What did I miss?














4 Answers, 1 is accepted

Sort by
0
Georgi Krustev
Telerik team
answered on 26 Sep 2014, 12:31 PM
Hello Bob,

In general, the MultiSelect widget selects items if they are present in the data source. If the value that the one tries to set are not there then widget will ignore them. What happens in this case is that the second widget does not have any items related to the values coming from Model.SubTradeIds. In order to solve this problem, you will need set the values after the widgets are bound:
var tradeSel = $("#Trades").data("kendoMultiSelect");
var subTradeSel = $("#SubTrade").data("kendoMultiSelect");
var skillSel = $("#Skills").data("kendoMultiSelect");
 
var tradeIds = @Html.Raw(Json.Encode(Model.TradeIds));
var subTradeIds = @Html.Raw(Json.Encode(Model.SubTradeIds));
var skillIds = @Html.Raw(Json.Encode(Model.SkillIds));
 
//First widget is bound
tradeSel.one("dataBound", function() {
  //Second widget is bound
  subTradeSel.one("dataBound", function() {
 
    //Set the value of the third widget
    skillSel.value(skillIds);
  });
 
  //Set the value of the second widget
  subTradeSel.value(subTradeIds);
]);
 
//Set the value of the first widget
tradeSel.value(tradeIds);
Give it a try and let me know how it goes.

Regards,
Georgi Krustev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Bob
Top achievements
Rank 1
answered on 26 Sep 2014, 02:14 PM


:( no joy, same result.  However, if I do something as goofy as this:
 
setTimeout(function () {
            var tradeSel = $("#Trades").data("kendoMultiSelect");
            var subTradeSel = $("#SubTrade").data("kendoMultiSelect");
            var skillSel = $("#Skills").data("kendoMultiSelect");
 
 
            tradeSel.value(@Html.Raw(Json.Encode(Model.TradeIds)));
            subTradeSel.value(@Html.Raw(Json.Encode(Model.SubTradeIds)));
            skillSel.value(@Html.Raw(Json.Encode(Model.SkillIds)));
        }, 1000);


Not that I can use this as a solution, but it leads me to believe that the controls have not finished loaded in the doc ready.  So now I just need to find the event that will signal that the controls have finished rendering and loading.
0
Accepted
Georgi Krustev
Telerik team
answered on 26 Sep 2014, 03:47 PM
Hi Bob,

In that case, the easiest solution will be to wire the dataBound event of the last widget and set the values when it is triggered. The problem with this implementation is that you cannot be sure whether the last widget is bound lastly. Another approach which is much more complicated is to use Promises. Here is a simple Dojo demo that demonstrates such implementation.

All these suggestions are completely general, as I am not sure about the complete implementation (what data is provided and etc). In order to provide a better and more concrete solution, I will need a repro demo. 

Regards,
Georgi Krustev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Bob
Top achievements
Rank 1
answered on 27 Sep 2014, 06:55 PM
Perfect!  both the databound worked and the promise.  For the databound I just had to wait until all three controls were databound.

and I leaned all about promises (which I think I like as a solution better);
Tags
MultiSelect
Asked by
Bob
Top achievements
Rank 1
Answers by
Georgi Krustev
Telerik team
Bob
Top achievements
Rank 1
Share this question
or