Search code examples
javascriptjqueryhtmlsymfonyfirebug

jQuery does not execute until I put a break point in Firebug


I am using twig to generate my html stuff and an external js file to call jQuery(document).ready(function() {....}); This probably is a simple problem but I can't figure it out.

Here's my code: base.html.twig

<script>
    var currentPage = "{{ path(app.request.attributes.get('_route'),app.request.attributes.get('_route_params')) }}".replace(/[0-9]|\//g, '').toLowerCase().replace('app_dev.php', '');
    $.ajax({
        type: 'GET',
        url: "{{ asset('/app_dev.php/GetMenuJson/') }}" + currentPage,
        success: function(data){
            constructMenuData(data);
        }
    });
    function constructMenuData(menuData)
    {
        var contentForDiv = "";
        //Bunch of other concatenation statements to generate the html
        contentForDiv += "<li><a href=''  class='menuLink'  id='"+result[j][k]["id"]+"'>" + result[j][k]["menuName"] + "</a></li>";
        contentForDiv += "</div>";
        // At the end
        $('#menu').html(contentForDiv);
    }
</script>

In my index.html.twig

{% extends "::base.html.twig" %}
{% block javascripts %}
{{ parent() }}
<script src="{{ asset('bundles/productorderlookup/js/ProductOrderEdit.js') }}" type="text/javascript"></script>

ProductOrderEdit.js

jQuery(document).ready(function() {
    $('a.menuLink').click(function (event) {
        event.preventDefault();
        console.log("IN THE FUNCTION");
    })
});

My generated html looks like this

<ul id="menu-item">
    <li>
        <a id="1" class="menuLink" href="">Release</a>
    </li>
    <li>
        <a id="17" class="menuLink" href="">Other Pos</a>
    </li>
    <li>
        <a id="18" class="menuLink" href="">FSC Labels</a>
    </li>
</ul>

Problem: The link when clicked on doesn't work. I have tried wrapping it up in another function explicitly and calling it in the index.html.twig file but it still won't work. The only time it works is when I put a breakpoint in firebug. I realize this probably is some kind of race condition or some other minor problem but I am not able to fix it. I have tried searching various questions on SO but it wasn't helpful so far. What might be the problem?

NOTE: I have multiple jQuery(document).ready(function() {...}); all over the page. Not sure if that matters.


Solution

  • This should be pretty straight.

    First, having multiple jQuery(document).ready(function() {...}); does not affect any code flow. It might negatively affect your app's performance if you have a lot of them, but the functionality should remain intact. That is as long as code in one ready does not depend on another ready - that is just plain bad :).

    Now, back to your problem: If I see it right, you send out ajax call that returns json containing menu items which are then converted to html and put into #menu element. The problem is that the page has announced ready event long before the items have been returned to your page. In turn, your code

    $('a.menuLink').click(function (event){ ... });
    

    should not have bound any element - those are not there yet.

    The quick fix would be to use delegated bind (on) instead of click which binds not only currently present elements but those that will be created in future. Assuming the #menu element is always present, you could do:

    $('#menu').on('click', 'a.menuLink', function(){
        // Here goes your code, same as you originally intended
    });
    

    Does this help?