IAmYourFaja
IAmYourFaja

Reputation: 56912

jQuery doesnt invoke alert box

I have the following:

<script language="javascript" type="text/javascript">
    $(document).ready(function() {
        $.getJSON(
            "/myServer/getAllWidgets",
            function(data) {
                var optionsHTML = "<select id='widget-sel'>";
                optionsHTML += "<option selected='selected' id='default'>Select an option</option>";
                var len = data.length;
                for(var i = 0; i < len; i++) {
                    optionsHTML += '<option value="' + data[i] + '">'
                        + data[i] + '</option>';
                }

                optionsHTML += "</select>";

                $('#widget-sel-div').html(optionsHTML);
            }
        );

        $("#widget-sel").change(function() {
            alert("Hello!");
        });
    });
</script>

<div id="widget-sel-div"></div>

So, the idea is that when document.ready fires, it populates the widget-sel-div with a select box (widget-sel) and then creates a change handler for that select that simply prints "Hello!" to the screen via alertbox.

When I run this, I get no errors (Firebug doesn't complain at all) and the select gets populated with all my widgets from the AJAX call to /myServer/getAllWidgets. The problem is, the change handler isn't working: when I select a widget I don't get the alertbox. Can anybody spot where I'm going awrye? Thanks in advance.

Upvotes: 0

Views: 105

Answers (2)

Rory McCrossan
Rory McCrossan

Reputation: 337560

This is due to the asynchronous nature of the AJAX call. The change handler will be executed before the AJAX call has completed and therefore there will be no element in the DOM for it to bind to. Instead, place the change in the AJAX call back:

$.getJSON(
    "/myServer/getAllWidgets",
    function(data) {
        var optionsHTML = "<select id='widget-sel'>";
        optionsHTML += "<option selected='selected' id='default'>Select an option</option>";
        var len = data.length;
        for(var i = 0; i < len; i++) {
            optionsHTML += '<option value="' + data[i] + '">' + data[i] + '</option>';
        }
        optionsHTML += "</select>";

        $('#widget-sel-div').html(optionsHTML);
        $("#widget-sel").change(function() {
            alert("Hello!");
        }
    }
);

Or alternatively you can leave the change handler where it is and delegate the event listener to a static parent element like this:

 $('#widget-sel-div').on('change', '#widget-sel', function() {
      alert("Hello!");
 });

Upvotes: 2

James Allardice
James Allardice

Reputation: 165971

At the time the code runs, the #widget-sel element doesn't exist in the DOM, because you add it in the callback to getJSON (which is asynchronous). You can't bind an event handler to it when it doesn't exist yet.

To get around this, you can delegate the event handler higher up the DOM tree (looks like you can use the parent div in this case) with the .on() method (jQuery 1.7+, if you're using an older version, use .delegate() instead):

$("#widget-sel-div").on("change", "#widget-sel", function () {
    alert("Hello!");
});

Upvotes: 5

Related Questions