ajaxjquery-selectorszotonic

jquery selector on ajax loaded content failing


I have a dialog that's loaded via ajax. The paylaod of that ajax contains both html and javascript.

The dialog displays just fine and the JS included in that payload executes.

However, I am unable to select any elements (whether its by id, class or element type) from the JS in the payload.

lets say the payload had:

<div>
   <ul id="testid">
     <li>A</li>
     <li>B</li>
   </ul>
</div>
<script type="text/javascript">
    $(document).ready(function() {
        console.info('test: ' + $("#testid").length);
    });
</script>

This results in test: 0 appearing in the console.

If I change the selector to select on 'body' then it results in a non-zero value.

Clearly the loaded content is being displayed and the JS it contains IS being executed and my understanding is that the .ready() call should allow the DOM time to be updated to include the html payload.

Unfortunately in this instance I have no direct control over the ajax load itself as I'm using a framework that does the dialog functionality for me (zotonic).

The weird thing is, other ajax loaded pages I have that have JS which selects elements in the ajax loaded payload are working - its just the dialog stuff that (so far) seems to be failing.

I'm at a bit of a loss as to why just this is going wrong. I've done my due diligence and searched google etc for the last couple of days with no solution so thought I'd shout out for help on here.

Jason


Solution

  • I believe ready only works the first time the page loads. If you're depending on the result of an AJAX call, you need to use a callback since the operation is asynchronous. Does zotonic offer you any hooks that you can use? Otherwise it's going to be a little harder. Perhaps you can poll the DOM like this, on page load:

    <script type="text/javascript">
        $(document).ready(function() {
            var interval = setInterval(function() {           
                if($("#testid").length > 0) {
                   clearInterval(interval);
                   console.info('test: ' + $("#testid").length);
                }
            }, 750);
        });
    </script>
    

    This will query they page every 750ms for #testid. If it finds the element, the interval is cancelled and you should get a console output.