Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bootstrap 3 - Event hidden.bs.collapse not fired if the accordion is inside a modal populated via ajax

I have a simple bootstrap modal populated via ajax. The content is an Accordion made by the bootstrap plugin Collapse. If I try to detect the hidden.bs.collapse (or any other Event detectable), it won't be fired.

http://jsfiddle.net/Diac/n2jm5cy8/

HTML

<!-- Button trigger modal -->
<a href="/echo/html/" data-remote="false" data-toggle="modal" data-target="#myModal">Launch demo modal</a>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" id="myModalLabel">Modal title</h4>
            </div>
            <div class="modal-body" id="modalbody">
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary">Save changes</button>
            </div>
        </div>
    </div>
</div>

accordion.html (loaded via ajax)

<div class='panel-group' id='accordion'>
    <div class='panel panel-default' id='panel1'>
        <div class='panel-heading'>
            <h4 class='panel-title'>
                <a data-toggle='collapse' data-parent='#accordion' href='#collapseOne'>Collapsible Group Item #1</a>
            </h4>
        </div>
        <div id='collapseOne' class='panel-collapse collapse in'>
            <div class='panel-body'> Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. </div>
        </div>
    </div>
</div>

JavaScript

$('a[data-toggle]').click(function(e) {
    e.preventDefault();
});

$('#myModal').on('show.bs.modal', function(event) {
    $.ajax({
        url: "accordion.html",
        success: function(responseText) {
            $("#modalbody").html(responseText);
        }
    });
});

$('.panel').on('hidden.bs.collapse', function (e) {
    alert('Event fired on #' + e.currentTarget.id);
})
like image 203
Daniele Avatar asked Oct 14 '15 17:10

Daniele


1 Answers

You are trying to attach your event listener to elements with the .panel class before any elements with the .panel class exist in the DOM.

To make your code work, you can move your $('.panel').on(...) inside the AJAX success callback, after the .panels have actually been inserted to the DOM. Alternatively, and probably preferably, you may use event delegation instead:

$('#modalbody').on('hidden.bs.collapse', '.panel', function (e) {
    alert('Event fired on #' + e.currentTarget.id);
});

See the discussion regarding event delegation in the jQuery documentation.

A relevant excerpt:

Event handlers are bound only to the currently selected elements; they must exist at the time your code makes the call to .on(). To ensure the elements are present and can be selected, place scripts after the elements in the HTML markup or perform event binding inside a document ready handler. Alternatively, use delegated events to attach event handlers.

like image 108
Thernys Avatar answered Oct 29 '22 14:10

Thernys