Chosen dropdown list not working with Modal

user picture user · Aug 9, 2013 · Viewed 8.3k times · Source

I am trying to get a jQuery Chosen select / dropdown list to work in a Bootbox modal. I have almost the same exact code working on a standard HTML page, so I thought it would be straight forward to just pop my list into a modal. I generate my divs and select objects in the modal, and then after it is "shown", I call Chosen:

div.on("shown", function() {
    $(".chzn-select").chosen();
    $(".chzn-select-deselect").chosen({allow_single_deselect:true});
    myApp.init();
});

After this, Chosen seems to be broken. The select items are grayed out--I cannot click them.

Inside myApp.init(), I populate the select items, and it works.

enter image description here

Behind the scenes for the modal, I can see that the Chosen container seems to have initialized, but it doesn't transfer the select options to the chzn-drop div. In the image, the chzn-results UL should be filled with options. Here is the modal version: enter image description here

Here is what it should look like, from the HTML version: the goal

In the HTML version, my code is at the bottom of the body tag (similarly the select options are populated in myApp.init()), and it seems to work just fine. The order of calls seems to be identical...

$(".chzn-select").chosen(); $(".chzn-select-deselect").chosen({allow_single_deselect:true});
$(document).ready(function(){   
  myApp.init();
});

This is not just a matter of z-index--I have already played around with that with no luck. It seems like inside the modal, the Chosen plugin is somehow getting confused and not binding or updating, even though it has initialized properly. I'm not sure how to troubleshoot it and cannot find other people with the same problem...this makes me think it might be a timing issue (but why does it work in HTML?), or I am doing something stupid (highly likely). Does anyone have any suggestions on where to look or what is wrong?

Thanks!

============================

Adding HTML for the select inputs (per Christopher's question)

For both versions, I populate the select with the following code (edited version of what is in myApp.init()):

$.ajax call to a RESTful URL

var callbackSuccess = function(data){
    if ( data ) {
    populateDropDownById(data, 'objectiveBanks');

        //Other things
    }
};

function populateDropDownById(data, elementId) {
    $('#' + elementId).append('<option value = "null"> -- Select -- </option>');
    $.each( data, function( id, bean ) {
    var name = bean.displayName.text;
    var id =  bean.id;
        $('#' + elementId).append('<option value =' + id + '>' + name + '</option>');
    });
}

The actual elements themselves are as follows. In the non-working modal version:

var obj_banks_select = $('<select id="objectiveBanks" name="objectiveBank" onchange="populateObjectives()" tabindex="2"></select>')
                            .addClass('chzn-select')
                            .css({
                                'width': '330px',
                                'display': 'none'
                            });

And in the working HTML version:

<div id="objectiveBanksWrapper">    
      <span id="objectiveBanksLabel" class="label"></span>
      <select id="objectiveBanks" name="objectiveBank" onchange="populateObjectives()" class="chzn-select" tabindex="2" style="width: 330px; display: none;"></select>
      <span id=objectiveBanksLoader class="dropDownLoader"></span>
    </div>

Answer

Omar picture Omar · Aug 9, 2013

I can't exactly tell what the problem is without seeing your actual code structure, but generally I think it's a good idea to populate you selects before initializing the plugin, so the best approach would be to add the plugin initialization on your elements in your ajax callback after the options have been added.

var callbackSuccess = function(data){
    if ( data ) {
        populateDropDownById(data, 'objectiveBanks');
        $(".chzn-select").chosen();
        $(".chzn-select-deselect").chosen({allow_single_deselect:true});
        //Other things
    }
};

If you need to add options to your <select> elements after the plugin is initialized, you'd need to trigger the chosen:updated event on the field, ex:

$(.chzn-select").trigger("chosen:updated");