0

I already asked a similar question on SO here: Bootstrap jquery to populate modal content does not fire when delivered by ajax

However, I have since done more testing and have been able to mock up a demo of the issue hence I am raising a new question with a more detailed description of the issue and a demo to show the issue on a live site.

I have some HTML and Javascript code.

The basic concept is that if a user clicks some HTML like this:

HTML to call code to populate Bootstrap Modal

<a href='#' data-toggle='modal' data-target='#MyModal' data-content='char'>char</a>

The Modal HTML

Then data in this Bootstrap Modal:

<!-- Modal -->
<div class="modal fade" id="MyModal" role="dialog">
    <div class="modal-dialog">

        <!-- Modal content-->
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title">Modal Test</h4>
                <button type="button" class="close" data-dismiss="modal">&times;</button>
            </div>
            <div class="modal-body">
            
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
            </div>
        </div>
    </div>
</div>

jQuery to load data into the Modal

Is populated in the modal-body div via this jQuery:

$("a[data-target='#MyModal']").on('click',function(){
  var gotBack = $(this).attr('data-content');
  console.log("gotBack: " + gotBack);
  $(".modal-body").html("<p>Loaded word: <code>" + gotBack + "</code></p>");
});

The Problem

The abovbe works fine, as per the snippet below (though I realise the remote ajax content on the snippet is not populated as it's on an external site).

I also have javascript to remotely load in content via ajax as the user scrolls down the page.

That adds additional table rows which contain the identically formatted HTML to load data into the modal window.

However, as you can see on this demo page, when clicking on the table cells loaded via ajax (you may need to resize your browser to make the scroll bar appear so you need to scroll down to make records appear as you go past row 15), the content is not loaded into the modal window.

There are no errors in the console, no nothing - I worked on this all weekend but cannot get to the bottom of it.

It feels like whatever happens, the load-data-into-the-modal functionality only works if the HTML is rendered on page load, but if the HTML is rendered via ajax, then it's like bootstrap doesn't know about it / recognise it, and therefore the functionality to populate the modal with data will not work.

I have also tried loading data into the modal using jQuery like this:

 $('.music_info').click(function(){
   var id = $(this).data('id');
   $.ajax({
    url: '_ajax_player.php',
    type: 'post',
    data: {id: id},
    success: function(response){ 
      $('.modal-body').html(response);
      $('#MusicModal').modal('show'); 
    }
  });
 });

But that also does not work when the HTML is rendered via the content delivered by ajax.

Snippet Below

    $(document).ready(function(){

        var fetching = false;

        function lastPostFunc()
        {
            fetching = true;
            $('div#lastPostsLoader').html('');
            $.get("https://jimpix.co.uk/testing/modal-test-ajax.php?action=getLastPosts&lastID="+$(".wrdlatest:last").attr("id"),
            function(data){
                if (data != "") {
                $(".wrdlatest:last").after(data);
                setTimeout(function(){
                    fetching = false;
                },300);
                $('div#lastPostsLoader').empty();
            }
        });
        };

        $(window).scroll(function(){
            var bufferzone = $(window).scrollTop() * 0.20;
            if($(window).scrollTop() + $(window).height() > $(document).height() - 100 && !fetching) {
                lastPostFunc();
            }
        });

        $("a[data-target='#MyModal']").on('click',function(){
          var gotBack = $(this).attr('data-content');
          console.log("gotBack: " + gotBack);
          $(".modal-body").html("<p>Loaded word: <code>" + gotBack + "</code></p>");
        });

    });
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">

    <div class="container-fluid">

        <h1>Bootstrap Modal Remote Load Test</h1>

        <table border='1' cellspacing='5' cellpadding='5'>
            <tr class='wrdlatest' id='1'><td>1</td><td><a href='#' data-toggle='modal' data-target='#MyModal' data-content='nothing'>nothing</a></td></tr>
            <tr class='wrdlatest' id='2'><td>2</td><td><a href='#' data-toggle='modal' data-target='#MyModal' data-content='mammering'>mammering</a></td></tr>
            <tr class='wrdlatest' id='3'><td>3</td><td><a href='#' data-toggle='modal' data-target='#MyModal' data-content='lunctured'>lunctured</a></td></tr>
            <tr class='wrdlatest' id='4'><td>4</td><td><a href='#' data-toggle='modal' data-target='#MyModal' data-content='pensive'>pensive</a></td></tr>
            <tr class='wrdlatest' id='5'><td>5</td><td><a href='#' data-toggle='modal' data-target='#MyModal' data-content='croutons'>croutons</a></td></tr>
            <tr class='wrdlatest' id='6'><td>6</td><td><a href='#' data-toggle='modal' data-target='#MyModal' data-content='befriend'>befriend</a></td></tr>
            <tr class='wrdlatest' id='7'><td>7</td><td><a href='#' data-toggle='modal' data-target='#MyModal' data-content='boot'>boot</a></td></tr>
            <tr class='wrdlatest' id='8'><td>8</td><td><a href='#' data-toggle='modal' data-target='#MyModal' data-content='sage'>sage</a></td></tr>
            <tr class='wrdlatest' id='9'><td>9</td><td><a href='#' data-toggle='modal' data-target='#MyModal' data-content='fingling'>fingling</a></td></tr>
            <tr class='wrdlatest' id='10'><td>10</td><td><a href='#' data-toggle='modal' data-target='#MyModal' data-content='ajar'>ajar</a></td></tr>
            <tr class='wrdlatest' id='11'><td>11</td><td><a href='#' data-toggle='modal' data-target='#MyModal' data-content='chine'>chine</a></td></tr>
            <tr class='wrdlatest' id='12'><td>12</td><td><a href='#' data-toggle='modal' data-target='#MyModal' data-content='moan'>moan</a></td></tr>
            <tr class='wrdlatest' id='13'><td>13</td><td><a href='#' data-toggle='modal' data-target='#MyModal' data-content='visa'>visa</a></td></tr>
            <tr class='wrdlatest' id='14'><td>14</td><td><a href='#' data-toggle='modal' data-target='#MyModal' data-content='murmur'>murmur</a></td></tr>
            <tr class='wrdlatest' id='15'><td>15</td><td><a href='#' data-toggle='modal' data-target='#MyModal' data-content='char'>char</a></td></tr>
            <div id="lastPostsLoader"></div>
        </table>

        <!-- Modal -->
        <div class="modal fade" id="MyModal" role="dialog">
            <div class="modal-dialog">

                <!-- Modal content-->
                <div class="modal-content">
                    <div class="modal-header">
                        <h4 class="modal-title">Modal Test</h4>
                        <button type="button" class="close" data-dismiss="modal">&times;</button>
                    </div>
                    <div class="modal-body">
                    
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                    </div>
                </div>
            </div>
        </div>

    </div> <!-- /container outer -->

<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
4532066
  • 2,042
  • 5
  • 21
  • 48
  • 1
    The `a` elements are created from the AJAX response after the DOM has loaded so you need to use a delegated event handler: `$(document).on('click', 'a[data-target="#MyModal"]', function() { ...`. See the duplicate for more information – Rory McCrossan Jan 18 '21 at 16:22
  • This line `$("a[data-target='#MyModal']")` will only affect lines that exist at the time the code runs - change it to event delegation `$(document).on("click", "a[data-target='#MyModal']", function...` (same for `$('.music_info').click`) – freedomn-m Jan 18 '21 at 16:22
  • Thanks @RoryMcCrossan, that sorted it! Changed '$("a[data-target='#MyModal']").on('click',function(){' to '$(document).on('click', 'a[data-target="#MyModal"]', function() {' and all sorted! – 4532066 Jan 18 '21 at 20:32
  • Thanks for your advice @freedomn-m, that sorted it – 4532066 Jan 18 '21 at 20:33

0 Answers0