Reputation: 56912
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
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
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