Scott
Scott

Reputation: 3967

jQuery wait for above code execution to complete

I've written some javascript using jQuery to replace any select lists with a div and ul alternative so that it will give me some more styling control and make the drop downs look the same cross browser. The below code works 99% for me but I have one issue. At the bottom of the code I have had to use .delay() to tell the code in a way to wait for the .each() loop above to finish doing what its doing. The problem with this is that there is atleast one second untill the replacement happens leaving a flash of the old select boxes. Also I can forsee another problem is what if it takes more than one second for the each() loop to complete...

How can I get the code at the bottom to only run once the each loop has run and complete. Also I welcome any optimizations on the rest of the code.

EDIT: Some of the HTML has been stripped from the code so I have pastebinned it: http://pastebin.com/4HFLjHE1


// Check when ready
$(function() {

    // Find dropdowns
    $("select.dropdownreplace").each(function() {replaceDropDown(this);});
    // If document clicked anywhere hide drop downs
    $(document).click(function(event){
        $("div.dropdownreplace ul").hide();
    });

});

function replaceDropDown(that) {
    // Create HTML for new drop down
    // hidden field
    var hiddeninput = $('');
    // div
    var dropdowndiv = $(''+$(":selected", that).text()+'
    '); // loop through values and make li's $("option", that).each(function() { $("ul", dropdowndiv).append('
  • '+$(this).val()+''+$(this).text()+'
  • '); // set click handler for this drop down $(dropdowndiv).click(function() { $("ul", this).show(); return false; }); // set click handler for link items $("a", dropdowndiv).click(function() { // Get name of hidden input var nameofdropdown = $(this).parent().parent().parent().attr('id'); var nameofinput = nameofdropdown.replace("dropdownreplacement_", ""); // set hidden input value to whats been clicked $("[name='"+nameofinput+"']").val($(this).parent().find("span").text()); // set div $("div#"+nameofdropdown+" > span").text($(this).text()); $("div#"+nameofdropdown+" ul").hide(); return false; }); }); // Remove drop down then add in replacement html $(that).delay(1000).after(hiddeninput); $(that).delay(1100).after(dropdowndiv); $(that).delay(1200).remove(); }

    Thnaks

    Scott

    Upvotes: 3

    Views: 1591

    Answers (2)

    Leite
    Leite

    Reputation: 994

    Inside your function, compare the index jquery passes you, with the total number of items you have.

    I don't know your html, but I believe you can do this.

    Change your function so it receives the index param that jquery sends.

    $("option", that).each(function(index) {
    

    Then, at the end of that function compare the length with the index, if they are the same, then you're done

    if ( $('option', that).length == (index +1 ) ) {
        $(that).after(hiddeninput);
        $(that).after(dropdowndiv);
        $(that).remove();
    }
    

    From my tests, this should be what you need. Don't know if there is a more "standard" way to do it.

    Hope this helps

    Upvotes: 3

    Stephan Muller
    Stephan Muller

    Reputation: 27610

    What you have to do is create a callback functionl. In your each(), after the initial function you can indicate it has to do some more things when it's finished:

    $("option", that).each(function() {
    
      <...code...>
    
    }, function() {   
          <...code...>  //this gets performed after the previous function is complete
    });
    

    Upvotes: 0

    Related Questions