ListBox leaves item selected after removing

11 posts, 0 answers
  1. CCC
    CCC avatar
    2 posts
    Member since:
    Jun 2014

    Posted 15 Jun 2018 Link to this post

    I have a listbox pair, and I am removing an item or items from one and transferring them to the other.  Some code is executed when this is done.

    The problem is that the ListBox selects an item in the list when the transfer is done, and this is not what I want it to do.

    I have tried to use javascript to unselect all items in the list to no avail.

    <div style="width:100%;">
        <div style="width:50%;float:left;">
            @(
                Html.Kendo()
                .ListBox()
                .Name("NotReviewers")
                .DataTextField("FullName")
                .DataValueField("user_name")
                .TemplateId("itemTemplate")
                .ConnectWith("Reviewers")
                .HtmlAttributes(new { style = "width:100%;" })
                .Selectable(ListBoxSelectable.Multiple)
                .Toolbar(toolbar =>
                                    {
                                        toolbar.Position(Kendo.Mvc.UI.Fluent.ListBoxToolbarPosition.Right);
                                        toolbar.Tools(
                                                        tools => tools
                                                                .Remove()
                                                                .TransferAllFrom()
                                                                .TransferAllTo()
                                                                .TransferFrom()
                                                                .TransferTo()
                                                                );
                                    }
                        )
                .BindTo((System.Collections.IEnumerable)ViewBag.nonreviewers)
            )
        </div>
        <div style="width:50%;float:right;">
            @(
                Html.Kendo()
                .ListBox()
                .HtmlAttributes(new { style = "width:100%;" })
                .Name("Reviewers")
                .Events( events=>{
                    events.Add("AddReviewer");
                    events.Remove("RemoveReviewer");
                }
                )
                .TemplateId("itemTemplate")
                .DataTextField("FullName")
                .DataValueField("user_name")
                .ConnectWith("NotReviewers")
                .Selectable(ListBoxSelectable.Multiple)
                .BindTo((System.Collections.IEnumerable)ViewBag.reviewers)
            )
        </div>
    </div>

     

     

    I use the following javascript to handle the transfer:

    function AddReviewer(e)
    {
        var dataItems = e.dataItems;
        var url = window.location.href.replace("Requestors", "AddRequestor");
        if (dataItems.length > 0) {
            for (var i = 0; i < dataItems.length; i++) {
                var dataItem = dataItems[i];
                $.ajax({
                    url: url,
                    dataType: "json",
                    type: "POST",
                    contentType: "application/json; charset=utf-8",
                    data: JSON.stringify({ user_name: dataItem.user_name }),
                    async: false,
                    processData: false,
                    cache: false,
                    error: function (xhr) {
                    }
     
                });
            }
        }
        var reviewers = document.getElementById("Reviewers");
        for ( i = 0; i < reviewers.options.length; i++) {
            reviewers.options[i].selected = false;
        }
        var notreviewers = document.getElementById("NotReviewers");
        for (i = 0; i < notreviewers.options.length; i++) {
            notreviewers.options[i].selected = false;
        }
        reviewers.value = "";
        notreviewers.value = "";
        reviewers.selectedIndex = -1;
        notreviewers.selectedIndex = -1;
        reviewers.blur();
        notreviewers.blur();
        return true;
    }

     

    None of the section of the code that I am using to remove the selection works.

    The other javascript callback works in a similar manner.

    Does anyone have any suggestions on how to remove the selection from the listbox once the work is done?

  2. Preslav
    Admin
    Preslav avatar
    516 posts

    Posted 19 Jun 2018 Link to this post

    Hello,

    What I could suggest is using the clearSelection method during the add and remove event handlers in a timeout.
    For example:

    setTimeout(function(){
      var NotReviewers = $("#NotReviewers").data("kendoListBox");
      var Reviewers = $("#Reviewers").data("kendoListBox");
     
      Reviewers.clearSelection();
      Reviewers.clearSelection();
    });


    Regards,
    Preslav
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  3. Tim
    Tim avatar
    5 posts
    Member since:
    Jun 2016

    Posted 19 Jun 2018 in reply to Preslav Link to this post

    I am the original poster.  I posted under our general account by mistake.

    The suggestion of using clearSelection has been tried and failed.

    I have stepped into the coding using the Visual Studio debugger, and the problem appears to be in the toolbar update process which occurs after the add/remove process has occurred.

    I have also tried the commented coding below as well:

    var listBox = $("#Reviewers").data("kendoListBox");
    listBox.clearSelection();
    listBox = $("#NotReviewers").data("kendoListBox");
    listBox.clearSelection();
    //var selected = document.getElementsByClassName("k-state-selected");
    //if (selected !== null && selected.length > 0) {
    //    for (var i = 0; i < selected.length; i++) {
    //        var item = selected[i];
    //        var node = document.createAttribute("class");
    //        node.value = item.attributes["class"].firstChild.textContent.replace("k-state-selected", "");
    //        item.attributes.setNamedItem(node);
    //    }
    //}

     

    The reselection occurs after all custom coding has processed.  I have tried to use other events to override the problem, but these fail as well.

  4. Preslav
    Admin
    Preslav avatar
    516 posts

    Posted 21 Jun 2018 Link to this post

    Hi Tim,

    Could you please check if using the clearSelection in a timeout works for you?

    For example, I used the code from my last post in the "ListBox / Basic usage" demo:
    and it seems that it works as expected:
    Now, the code of the demo looks like:

    <div id="example" role="application">
        <div class="demo-section k-content wide">
            <label for="optional" id="employees">Employees</label>
            <label for="selected">Developers</label>
            <br />
            @(Html.Kendo().ListBox()
            .Name("optional")
            .Toolbar(toolbar =>
            {
                toolbar.Position(Kendo.Mvc.UI.Fluent.ListBoxToolbarPosition.Right);
                toolbar.Tools(tools => tools
                    .MoveUp()
                    .MoveDown()
                    .TransferTo()
                    .TransferFrom()
                    .TransferAllTo()
                    .TransferAllFrom()
                    .Remove()
                );
            })
            .ConnectWith("selected")
            .Events(e => e.Add("onAdd").Remove("onRemove"))
            .BindTo(ViewBag.Attendees)
            )
     
            @(Html.Kendo().ListBox()
            .Name("selected")
            .BindTo(new List<string>())
            .Selectable(ListBoxSelectable.Multiple)
            )
        </div>
    </div>
     
    <script>
        function onAdd(e) {
            setTimeout(function () {
                var optional = $("#optional").data("kendoListBox");
                var selected = $("#selected").data("kendoListBox");
     
                optional.clearSelection();
                selected.clearSelection();
            });
        };
        function onRemove(e) {
            setTimeout(function () {
                var optional = $("#optional").data("kendoListBox");
                var selected = $("#selected").data("kendoListBox");
     
                optional.clearSelection();
                selected.clearSelection();
            });
        };
    </script>
     
    <style>
        .demo-section label {
            margin-bottom: 5px;
            font-weight: bold;
            display: inline-block;
        }
     
        #employees {
            width: 270px;
        }
     
        #example .demo-section {
            max-width: none;
            width: 515px;
        }
     
        #example .k-listbox {
            width: 236px;
            height: 310px;
        }
     
            #example .k-listbox:first-of-type {
                width: 270px;
                margin-right: 1px;
            }
    </style>


    Regards,
    Preslav
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  5. Tim
    Tim avatar
    5 posts
    Member since:
    Jun 2016

    Posted 21 Jun 2018 in reply to Preslav Link to this post

    I tried this by attaching the setTimeout to the error function of the ajax call, and using it instead of the direct call.

    Neither works.

  6. Preslav
    Admin
    Preslav avatar
    516 posts

    Posted 22 Jun 2018 Link to this post

    Hello Tim,

    I am sorry to hear that my suggestion did not work for you. Honestly speaking, for the time being, I am out of ideas how to overcome this behavior. It will help me a lot to continue my investigation if you can prepare and share a runnable project that clearly replicates the scenario. Examining and testing different approaches with this project will help me to eventually find a workaround faster.

    I look forward to your reply.


    Regards,
    Preslav
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  7. Tim
    Tim avatar
    5 posts
    Member since:
    Jun 2016

    Posted 22 Jun 2018 in reply to Preslav Link to this post

    The reason that it is doing this is because the selectedindex of the listbox is not set to -1 when the process is completed, and the routines in the listbox javascript cause the item nearest to the deleted item when an item is transferred to be selected.

    The listbox javascript will have to be modified.
  8. Viktor Tachev
    Admin
    Viktor Tachev avatar
    2392 posts

    Posted 26 Jun 2018 Link to this post

    Hi Tim,

    I created a sample project with the suggested approach and the selection seems to be cleared as expected on my end. You will find the sample attached.

    Please give it a try and let me know how it works for you. I would appreciate it if you can describe what should be changed in the sample in order to replicate the problematic behavior. 

    Regards,
    Viktor Tachev
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  9. Tim
    Tim avatar
    5 posts
    Member since:
    Jun 2016

    Posted 26 Jun 2018 in reply to Viktor Tachev Link to this post

    I tried to download the file and unzip it, but the Windows utility says it is corrupted.

    If you could clean the project, and then zip it up again, I might be able to get the code.  The .dlls came down, but the scripts and views did not.

  10. Tim
    Tim avatar
    5 posts
    Member since:
    Jun 2016

    Posted 26 Jun 2018 in reply to Viktor Tachev Link to this post

    It would be helpful if you just posted the code for the view with the javascript/jQuery/Ajax code that handles the user interface.  I really don't need the entire project.
  11. Viktor Tachev
    Admin
    Viktor Tachev avatar
    2392 posts

    Posted 27 Jun 2018 Link to this post

    Hello Tim,

    I zipped the project again and am sending the archive. Hopefully it will work this time. 

    Nevertheless, I will paste the code from the project just in case:

    Index.cshtml

    <div id="example" role="application">
        <div class="demo-section k-content wide">
            <label for="optional" id="employees">Employees</label>
            <label for="selected">Developers</label>
            <br />
            @(Html.Kendo().ListBox()
            .Name("optional")
            .Toolbar(toolbar =>
            {
                toolbar.Position(Kendo.Mvc.UI.Fluent.ListBoxToolbarPosition.Right);
                toolbar.Tools(tools => tools
                    .MoveUp()
                    .MoveDown()
                    .TransferTo()
                    .TransferFrom()
                    .TransferAllTo()
                    .TransferAllFrom()
                    .Remove()
                );
            })
            .ConnectWith("selected")
            .Events(e => e.Add("onAdd").Remove("onRemove"))
            .BindTo(ViewBag.Attendees)
            )
     
            @(Html.Kendo().ListBox()
            .Name("selected")
            .BindTo(new List<string>())
            .Selectable(ListBoxSelectable.Multiple)
            )
        </div>
    </div>
     
    <script>
        function onAdd(e) {
            setTimeout(function () {
                var optional = $("#optional").data("kendoListBox");
                var selected = $("#selected").data("kendoListBox");
     
                optional.clearSelection();
                selected.clearSelection();
            });
        };
        function onRemove(e) {
            setTimeout(function () {
                var optional = $("#optional").data("kendoListBox");
                var selected = $("#selected").data("kendoListBox");
     
                optional.clearSelection();
                selected.clearSelection();
            });
        };
    </script>
     
    <style>
        .demo-section label {
            margin-bottom: 5px;
            font-weight: bold;
            display: inline-block;
        }
     
        #employees {
            width: 270px;
        }
     
        #example .demo-section {
            max-width: none;
            width: 515px;
        }
     
        #example .k-listbox {
            width: 236px;
            height: 310px;
        }
     
            #example .k-listbox:first-of-type {
                width: 270px;
                margin-right: 1px;
            }
    </style>


    HomeController.cs

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewBag.Attendees = new List<string>
            {
                "Steven White",
                "Nancy King",
                "Nancy Davolio",
                "Robert Davolio",
                "Michael Leverling",
                "Andrew Callahan",
                "Michael Suyama"
            };
     
            return View();
        }
     
     
    }

     
    Let me know how this works for you.


    Regards,
    Viktor Tachev
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top