jQuery append not completing before next statement?
I have a survey-type form that's being populated from a web database on the client. I can populate the questions fine, but then I try to go through and trigger the click event where there is an existing answer (edit scenario), I'm finding that the new elements are not yet in the DOM so this doesn't work. Here's the code:
$(function() {
var db = openDatabase(...);
db.transaction(function(tx) {
tx.executeSql("select ....", [surveyId], function(tx, results) {
var items = "", answers = [];
for (var i = 0; i < results.rows.length; i++) {
var id = results.rows.item(i).id;
开发者_如何学运维 items += "<div><input type='radio' name='q-" + id + "' id='q-" + id + "-1' /><label for='q-"+id+"-1'>Yes</label><input type='radio' name='q-" + id + "' id='q-" + id + "-2' /><label for='q-"+id+"-2'>No</label></div>";
if (result.rows.item(i).answer) {
answers.push('#q-'+id+'-'+results.rows.item(i).answer);
}
}
$('#questions-div').append(items);
$.each(answers, function(i, e) { $(e).click(); });
});
});
});
Any tips how I can make this work, or better generally?
I think here:
answers.push('#q-'+id+'-'+result);
You meant to push this:
answers.push('#q-'+id+'-'+result.rows.item[i].answer);
Otherwise you're getting '#q-XX-[object Object]'
as a selector, where I think you're after the 1
or 2
version of '#q-XX-1'
.
I suspect this is actually a race condition. My bet is that if you execute your each
statement after a tiny delay, things will work as expected. Is so, the reason for this is that you can't be 100% sure when the browser will actually get around to updating the DOM when you programmaticallly insert new elements. I'm not sure what the best solution would be: if you were attaching events, I'd say you should do it at the same time you are building the elements; but if you are triggering the clicks, I'm leaning toward just continually testing for the existance of the elements and then triggering the clicks as soon as you know they are there.
So I came up with a solution:
I replaced the line items += "<div> ...."
with
var item = "<div><input type='radio' name='q-" + id + "' id='q-" + id + "-1' ";
if (results.rows.item(i).answer == 1) item += "checked ";
item += "/><label for='q-"+id+"-1'>Yes</label><input type='radio' name='q-" + id + "' id='q-" + id + "-2' ";
if (results.rows.item(i).answer == 2) item += "checked ";
item += "/><label for='q-"+id+"-2'>No</label></div>";
items += item;
... which means I no longer need the answers array or to trigger click events on the radio buttons.
I was hoping for something a bit neater, but this seems to work OK. Thanks @Nick Craver & @Andrew for helping me arrive at it!
精彩评论