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.
numaroth
  • 1,295
  • 4
  • 25
  • 36
AmirTNinja
  • 357
  • 3
  • 5
  • 15
  • I think the `k-animation-container` has the id of the dropdown with `-list` appended to it. (using your example: `id="dropdownlist-list"`) – Pedro Estrada Jun 25 '14 at 13:31

2 Answers2

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();
Lars Höppner
  • 18,252
  • 2
  • 45
  • 73
  • 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). – AmirTNinja Jun 25 '14 at 14:11
  • 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. – AmirTNinja Jun 25 '14 at 14:27
  • the k-list-container is child of k-animation-container, and it'll be removed by widget.destroy(); check this: http://jsfiddle.net/lhoeppner/mEf4N/ – Lars Höppner Jun 25 '14 at 14:46
  • 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? – AmirTNinja Jun 25 '14 at 22:11
  • are you using angular-kendo? it's difficult to help without seeing the code - if possible, try to create a minimal demo (plnkr/jsbin) – Lars Höppner Jun 25 '14 at 22:34
  • 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? – AmirTNinja Jun 25 '14 at 22:39
  • 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 on – Lars Höppner Jun 25 '14 at 22:41
  • 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) – AmirTNinja Jun 26 '14 at 14:34
  • 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 dropdown – Lars Höppner Jun 26 '14 at 17:55
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]);
    }
}
  • 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]); }` – chinh nguyen van Jun 19 '18 at 15:59