Thursday, March 27, 2008

Fast cloning of dropdowns

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/fast_cloning_of_dropdowns.htm]

There are times that you'll want to dynamically add items to an html dropdown using JavaScript. It can be a huge performance gain, even with Ajax and update panels. You can easily do this like so:

 

      function DoStuff()
      {
        var selectbox = document.getElementById("Select1");
        addOption(selectbox, "AAA", "1");
        addOption(selectbox, "BBBBB", "2");
        addOption(selectbox, "CC", "3");
       
      }
   
      function addOption(selectbox, strText, strValue )
      {
        var optn2 = document.createElement("OPTION");
        optn2.text = strText;
        optn2.value = strValue;
        selectbox.options.add(optn2);    //This line is very slow
      }

 

The problem I wanted to solve was how to do this when adding 4000 items? It could take several seconds, and be very slow. (Yes, ideally a simple dropdown by definition doesn't have that many items, but let's say there are legacy constraints there, and the client wants a dropdown). For example, say you have a grid, each row has a dropdown, and that dropdown may be huge. A much faster way is to load only 1 dropdown, make it hidden (via JS on the client), and then clone it's nodes.

 

For example, have a hidden dropdown, which you populate from whatever server values:

 

<span id="Span1">span

And then, call this function to clone those values. It will clone the entire dropdown (sparing you from calling the very slow options.add method 4000 times), and then dump it in some nested container (like a span):

 

      function cloneDropdowns_fast(strSourceId, strContainerId)
      {
        o = document.getElementById(strSourceId).cloneNode(true);
        o.style.visibility = "";
        var container = document.getElementById(strContainerId);
        container.appendChild(o);
      }

 

      function PopulateDropdown()
      {
        cloneDropdowns_fast("Select2", "Span1");
      }

 

So, calling the method "PopulateDropdown" will copy the entire dropdown from "Select2", and dump a whole new dropdown in the "Span1" container. It works much faster (and appears to work in both IE and FF).

No comments:

Post a Comment