Cascading Multiselect Initial Values

5 posts, 1 answers
  1. Bob
    Bob avatar
    4 posts
    Member since:
    May 2014

    Posted 24 Sep 2014 Link to this post

    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?














  2. Georgi Krustev
    Admin
    Georgi Krustev avatar
    3706 posts

    Posted 26 Sep 2014 Link to this post

    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!
     
  3. Kendo UI is VS 2017 Ready
  4. Bob
    Bob avatar
    4 posts
    Member since:
    May 2014

    Posted 26 Sep 2014 in reply to Georgi Krustev Link to this post



    :( 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.
  5. Answer
    Georgi Krustev
    Admin
    Georgi Krustev avatar
    3706 posts

    Posted 26 Sep 2014 Link to this post

    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!
     
  6. Bob
    Bob avatar
    4 posts
    Member since:
    May 2014

    Posted 27 Sep 2014 in reply to Georgi Krustev Link to this post

    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);
Back to Top
Kendo UI is VS 2017 Ready