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

ListBox leaves item selected after removing

10 Answers 579 Views
ListBox
This is a migrated thread and some comments may be shown as answers.
CCC
Top achievements
Rank 1
CCC asked on 15 Jun 2018, 08:26 PM

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?

10 Answers, 1 is accepted

Sort by
0
Preslav
Telerik team
answered on 19 Jun 2018, 05:26 PM
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.
0
Tim
Top achievements
Rank 1
answered on 19 Jun 2018, 05:52 PM

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.

0
Preslav
Telerik team
answered on 21 Jun 2018, 10:32 AM
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.
0
Tim
Top achievements
Rank 1
answered on 21 Jun 2018, 05:17 PM

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.

0
Preslav
Telerik team
answered on 22 Jun 2018, 08:24 AM
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.
0
Tim
Top achievements
Rank 1
answered on 22 Jun 2018, 01:20 PM
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.
0
Viktor Tachev
Telerik team
answered on 26 Jun 2018, 11:48 AM
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.
0
Tim
Top achievements
Rank 1
answered on 26 Jun 2018, 01:47 PM

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.

0
Tim
Top achievements
Rank 1
answered on 26 Jun 2018, 01:57 PM
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.
0
Viktor Tachev
Telerik team
answered on 27 Jun 2018, 10:25 AM
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.
Tags
ListBox
Asked by
CCC
Top achievements
Rank 1
Answers by
Preslav
Telerik team
Tim
Top achievements
Rank 1
Viktor Tachev
Telerik team
Share this question
or