How to remove all Kendo DropDownList elements from document.body (DOM)
Asked Answered
D

2

7

We are using about 3 DropDownList components inside a cardView kendo.ui.Window item. When the window is closed, we're calling the 'destroy' method for each of the contained DropDownList items.

The problem is that the following code is not removing all the DropDownList's related DIVS, that had been appended to the document body:

var dropdownlist = $("#dropdownlist").data("kendoDropDownList");
dropdownlist.destroy();

After some searching, we noticed the following comment at the documentation for the destroy method (from Telerik): Important: This method does not remove the DropDownList element from DOM.

Therefore, each time someone opens and closes our kendo's windows (card view), many DropDownList's divs are appended without being removed from DOM - this can cause serious performance issues at the DOM.

The appended DIVS that stay put at the DOM are - "k-list-container' and "k-animation-container for instance.

  1. How can I solve this problem?
  2. Is there a way to destroy each DropDownList's elements completely (include deleting all its related elements from DOM)?
  3. Is this problem relevant when we need to destroy other kendo.ui components? (such as combobox, dateTimePicker, Tooltip etc.) Since our kendo.ui card window also contains other basic kendo.ui components.
Doig answered 25/6, 2014 at 13:17 Comment(1)
I think the k-animation-container has the id of the dropdown with -list appended to it. (using your example: id="dropdownlist-list")Epimenides
L
7

The destroy method will remove elements that are appended to the document body and that can't clearly be associated with the widget just by looking at the DOM. So, for example, the element with class k-animation-container is removed for dropdowns. The comment in the documentation is saying that in-place elements don't get removed.

In order to remove everything, you should call destroy on the widget, and then remove the remaining elements yourself. The easiest option is to have a wrapping div element around all widgets you want to destroy and remove that. If you want to remove a specific widget, you can typically also reference the wrapper property, which contains the jQuery element representing the outermost DOM element of this widget:

$(widget.wrapper).remove();

so in your case, this will remove all elements and events for the dropdown:

var dropdownlist = $("#dropdownlist").data("kendoDropDownList");
dropdownlist.destroy();
dropdownlist.wrapper.remove();

If you want to remove everything you created for a kendo window, you can do the same:

var window = $("#window").data("kendoWindow");
// recursively call destroy for all widgets it finds
kendo.destroy(window.wrapper); 
window.wrapper.remove();
Lurleen answered 25/6, 2014 at 13:44 Comment(9)
Thanks for you response. I'll try the wrapper.remove. However, i didn't understand some manner in your respond- how can i make all our's window widgets (which need to be destroyed) to be under some wrapping div? When we create DropDownList for example, it's owner div is some div inside the kendo window, and the dropDownList component itself appends some extra managed divs to the document.body (all the k-animation-container and k-list-container div which represents the popup panel of the dropDown, i gathered).Doig
I've tried the dropdownlist.wrapper.remove() - but it didn't worked. the 'k-list-container' divs had not been removed from the document.body. Also, i checked the dropdownlist.wrapper in debug mode (chrome developer tools) and i've noticed that the dropdownlist.wrapper were pointing to '.k-dropdown' elements which are under the window div, and weren't pointing to one of the outer (body .k-list-container) divs.Doig
the k-list-container is child of k-animation-container, and it'll be removed by widget.destroy(); check this: jsfiddle.net/lhoeppner/mEf4NAttalanta
For some reason, even when we call widget.destroy(), the k-list-container/k-animation-container still exists the at document.body.It seems that we're experiencing the opposite case of the jsfiddle example - In our web page (which is developed under angularJS + typescript) the dropDownList div, is the one that being removed from the DOM (after calling widget.destory), and not its related k-list-container/k-animation-container Div (which is under the document.body). What can cause this scenario? can it be caused by AngularJS framework somehow?Doig
are you using angular-kendo? it's difficult to help without seeing the code - if possible, try to create a minimal demo (plnkr/jsbin)Attalanta
yop, it's quiet complex to create a minimal demo which recreates this problem, but we'll check it out. But generally, without considering angularJS, is there maybe any other cause which can be responsible for the problem above ? which causing the opposite scenario of the jsfiddle you linked?Doig
can't think of anything ATM, sorry; which version of Kendo UI are you using? might be a bug in that version (or angular-kendo); I'd also double check that you're calling .destroy on the widgets you think you're calling it onAttalanta
Can it be related to the fact that in our scenario, the dropDownList components are created inside kendo.ui window component, which is closed and destroyed? (along with the dropDownList items inside it)Doig
the dropdown should get destroyed when you destroy the window in that case; I would investigate whether the k-animation-container actually belongs to a dropdown in your window, or whether it's from another dropdownAttalanta
F
0

For whatever reason none of the prior solutions worked for me, and this is what I ended up implementing.

var grid = $('#GridName').data("kendoGrid");

//get grid data
var gridData = grid.dataSource.data();

//set the length (cannot use data.length in for loop as it changes when you remove the data items)
var dataLength = gridData.length;

//remove data from the grid
if (dataLength > 0) {
    for (var i = 0; i < dataLength; i++) {
        //must delete the first object in the array else it throws index out of bounds 
        //error because the data array changes when you remove an object
        grid.dataSource.remove(data[0]);
    }
}
Featherstitch answered 28/2, 2017 at 17:3 Comment(1)
You can use below code to prevent index out of bounds var oldData = grid.dataSource.data(); for (var i = oldData.length - 1; i >= 0; i--) { comboBox.dataSource.remove(oldData[i]); }Snuffer

© 2022 - 2024 — McMap. All rights reserved.