Search code examples
javascriptjqueryajaxpromisedocument-ready

Javascript not firing with dynamically loaded form and scripts


I'm loading a form and accompanying JS scripts into a modal via .ajax, but the JS isn't firing or initialising the elements as expected. (Nothing happens) The HTML and scripts work as expected elsewhere except when loaded via ajax into a modal.

Here's how I'm loading the content using a Promise to make sure and load the scripts only after the HTML is loaded. Any pointers where I may be going wrong?

$(document).on('click', '#post-offer', function() {
        $.when(
              $('head').append('<link rel="stylesheet" href="' + baseURL + '/css/jquery-ui.css">'),
            $('head').append('<link rel="stylesheet" href="' + baseURL + '/css/jquery.tagit.css">'),
            $('head').append('<link rel="stylesheet" href="' + baseURL + '/slim/slim.min.css">'),
            $.getScript( "//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"),
            openModal(baseURL + '/ajax.cgi?a=showoffer'), // << THIS IS THE HTML FORM
            $.Deferred(function(deferred){
                $(deferred.resolve);
            })
        ).done(function(){
            $.getScript( "//maps.googleapis.com/maps/api/js?v=3&key=xxxxxxxxxxxxxx"),
            $.getScript( baseURL + "/js/tag-it.js" ),
            $.getScript( baseURL + "/slim/slim.jquery.js" ),
            $.getScript( baseURL + "/js/listing.js" );
            
        });
});

For completeness, here's the openModal function (which works as expected):

function openModal(arg) {
    $('#loading').show();
    if (arg.match(/^http/)) { //If query, then send it.
        var $query = arg;
        $.ajax({
            url: $query,
            success: function(result) {
                $('#modalWrap').show();
                $('#modalContent').html(result);
                $('#loading').hide();
            },
            error: function(xhr) {
                $("#loading").hide();
                alert('Communication error! [Details: ' + xhr.status + ' - ' + xhr.statusText + ']');
            }
        });
    } else { //Or just return the input argument
        $('#modalWrap').show();
        $('#modalContent').html(arg);
        $('#loading').hide();
    };
};

Solution

  • Here's how I solved it for anyone else with this problem.

    It wasn't a loading problem. All the scripts and HTML loaded fine. The problem was that one of the dynamically loaded scripts listing.js had a document.ready() wrapper which wasn't firing since DOM was already loaded, so JS elements on the dynamically-loaded form weren't being initialized. However, when I removed the document.ready(), it still wasn't initializing the dynamically-loaded elements.

    To get around this, I changed the document.ready() to a function initialize() and called that last from the dynamically-loaded HTML. It all works fine now:

    //DYNAMICALLY LOADED SCRIPT FIRST    
    function initialize(){
    
        //INITIALIZE JS FORM ELEMENTS...
    
        }
    

    Then, in the same AJAX call:

    <form class="dynamically-loaded-HTML">
    
    <!-- FORM ELEMENTS -->
    
    </form>
    <script>
    initialize();
    </script>