How to clean up dropdownlist lists

8 posts, 1 answers
  1. Jaap
    Jaap avatar
    96 posts
    Member since:
    Oct 2012

    Posted 13 Feb 2012 Link to this post

    Hi,

    I am loading content to my page with ajax calls. This content contains dropdownlists. They create a list DIV in the BODY tag. When the content is updated with a new ajax call, these DIV tags remain in the BODY tag, so they are accumulating there.
    How to clean this up? This is especially a problem when you have a one page setup of your application. It is a kind of a 'memory leak' all these DIV tags which will not be used anymore.
    Ideally they should not be in the BODY tag, but near the location in the DOM where they are used. But I can imagine that will give trouble with display the list on top of other content.

    Ofcourse this applies also for other widgets which have such popups, like e.g. combobox and grid (filter dialogs).

    Any thoughts on this housekeeping issue appreciated.

    Regards, Jaap
  2. Georgi Krustev
    Admin
    Georgi Krustev avatar
    3706 posts

    Posted 14 Feb 2012 Link to this post

    Hello Jaap,

     
    You can get the popup element from the corresponding widget and remove it. Something like this:

    var popup =  $("#combobox").data("kendoComboBox").popup;
    //wrapper will be empty if popup has never been opened
    var element = popup.wrapper[0] ? popup.wrapper : popup.element;
     
    element.remove(); // remove popup from the DOM
    Regards,
    Georgi Krustev
    the Telerik team
    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. Jaap
    Jaap avatar
    96 posts
    Member since:
    Oct 2012

    Posted 15 Feb 2012 Link to this post

    Hi Georgi,

    Ok, but my problem is when to call this code?
    I have an application setup where I have an container element which gets new content everytime through the jQuery.load ajax method. That load method removes all the content of the container element including the kendo objects contained in the data() object of the elements. But the elements in the body remain.
    You need a kind of a dispose method.
    I have implemented it now this way:

    Just after creation of a widget like a dropdownlist or combobox I add a dispose function to the data object ($ddlSort is my input element on which a kendoDropDownList is created ($ddlSort.kendoDropDownList({...});)
    $ddlSort.data('x.dispose', function () { 
    var popup = $ddlSort.data("kendoDropDownList").popup;
    var element = popup.wrapper[0] ? popup.wrapper : popup.element;
    element.remove();
    });
    and I use this method to switch the content of my container element:
          /* Loads the response from the url in the element and initializes the content */
        $x.loadAndSwitchContent = function ($element, url) {
            /* Dispose oldContent */
            $element.children().find(':hasData(x.dispose)').each(function () {
                $(this).data('x.dispose')();
            });
            $element.empty();
            /* the $element is now empty and will be empty during the request.
            * Would be nicier if we could dispose just before the $element.html is changed.
            * But then we need an own version of the jQuery.load method */
            $element.load(url);
        }

    BTW: the :hasData selector is custom selector defined this way:
        /* hasData selector for jQuery */
        $.expr[':'].hasData = function (obj, index, meta, stack) {
            return $.hasData(obj) && ($(obj).data(meta[3]) !== undefined);
        };

    Regards, Jaap
  5. Answer
    Georgi Krustev
    Admin
    Georgi Krustev avatar
    3706 posts

    Posted 16 Feb 2012 Link to this post

    Hello Jaap,

     
    I will forward your request regarding the dispose method to our developers for further investigation and consideration. For now you can try the dispose method implemented in this jsFiddle demo. You probably will call it before you try to reinitialize the widget.

    All the best,
    Georgi Krustev
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  6. Bryan Brannon
    Bryan Brannon avatar
    65 posts
    Member since:
    Aug 2012

    Posted 26 Feb 2013 Link to this post

    Please look at this JsFiddle - http://jsfiddle.net/bryanb/bWRTm/1/

    I have multiple KendoUI enabled dropdownlists that I need to dispose of.  How can I do that?

    Here is what I have tried:  (as shown in the fiddle)
    function comboboxDispose() {
        $(".suppliers").each(function () {
            var combobox = $(this).data("kendoComboBox"),
                popup = combobox.popup,
                element = popup.wrapper[0] ? popup.wrapper : popup.element;
     
            //remove popup element;
            element.remove();
     
            //unwrap element
            combobox.element.show().insertBefore(combobox.wrapper);
            combobox.wrapper.remove();
     
            combobox.element.removeData("kendoComboBox");
        });
    }
  7. Bryan Brannon
    Bryan Brannon avatar
    65 posts
    Member since:
    Aug 2012

    Posted 26 Feb 2013 Link to this post

    I have this figured out.

    I (finally) realized I was selecting the wrong elements in my jquery selector.

    fixed: http://jsfiddle.net/bryanb/bWRTm/2/
  8. Jaap
    Jaap avatar
    96 posts
    Member since:
    Oct 2012

    Posted 27 Feb 2013 Link to this post

    Hi Bryan,

    As far as I know you don't need to implement your own dispose logic.
    In the current version of Kendo each widget has it's dispose method.

    Regards, Jaap
  9. Bryan Brannon
    Bryan Brannon avatar
    65 posts
    Member since:
    Aug 2012

    Posted 27 Feb 2013 Link to this post

    In my testing it seems to be a problem but it might be the way I can using it.

    Example:

    I have a regular <telerik:RadGrid> that I am using PageMethods to client databind a large collection of data on ready() and then a again at a subsequent interval - every 60 seconds.  Upon success of the RadGrid.set_dataSource() method, I am calling the following to Init() the <input type="text" class="location" /> into a KendoUI ComboBox:
    $(input[class='location']).kendoComboBox({
    placeholder: "",
    dataSource: my_location_json_data
    });

    The problem I have found is that during my subsequent refreshes... i.e. getting fresh data from my source and calling the set_dataSource() method on my RadGrid (client side) that my memory footprint for the browser grows... and after about 2 hours of refreshes it crashes on a standard configured machine.

    I am hoping my newly implemented dispose method will work:

    $("input[class='location']").each(function () {
         var combobox = $(this).data("kendoComboBox"),
                        popup = combobox.popup,
                        element = popup.wrapper[0] ? popup.wrapper : popup.element;
          
         //remove popup element
         element.remove();
     
         //unwrap element
         combobox.element.show().insertBefore(combobox.wrapper);
         combobox.wrapper.remove();
          
         combobox.element.removeData("kendoComboBox");
    });


    -Bryan
Back to Top
Kendo UI is VS 2017 Ready