I have a series of functions which populate a series of drop down boxes.
This is a product data page, and serves both to add a new item, or edit an existing one. In the latter case, once all the drop down boxes are populated, it grabs an item data from a database as a JSON string and selects the appropriate values in the drop down bozes using $('#elem').val('value')
This all works fine, except I can't get it to things in the right order.
1. function loadBrands() {
2. $('#brand').empty().append('<option value="">Select...</option>').addClass('centreLoader');
3. $.getJSON('/jsonData/brands.txt', function (data) {
4. $.each(data, function (i, item) {
5. $('#brand').append('<option value="' + data[i].label + '">' + data[i].brandName+ '</option>');
6. });
7. $('#brand').removeClass('centreLoader');
8. loadSavedItem();
9. });
10. };
I've added line numbers to explain simply (although you'll all know what this does!)
Line 3 gets the JSON data from my file (this is valid data as it populates fine), then line 4 begins looping the data returned and populating the drop down.
Line 8 is where things go wrong, this calls the function loadSavedItem
which looks a bit like this:
1. function loadSavedItem(thisItemId) {
2. $.getJSON('/jsonData/QUERY_DB_FOR_THIS_PRODUCT (thisItemId)', function (data) {
3. $('#brand').val(data[0].brand);
4. });
5. };
Again, pretty simple, line 2 gets the JSON output (which is again valid, it populates other fields fine) and sets the field values as applicable (this is obviously a shortened version of the code)
The problem appears to be that loadSavedItem()
is being called too soon, before #brands
is fully populated, so it cannot set the value correctly. If I put a time delay in, then it works.
BUT... I thought that anything after the $(each...
jQuery statement should not happen until $(each)
has finished?
How can I ensure that this is the case?
I have a series of functions which populate a series of drop down boxes.
This is a product data page, and serves both to add a new item, or edit an existing one. In the latter case, once all the drop down boxes are populated, it grabs an item data from a database as a JSON string and selects the appropriate values in the drop down bozes using $('#elem').val('value')
This all works fine, except I can't get it to things in the right order.
1. function loadBrands() {
2. $('#brand').empty().append('<option value="">Select...</option>').addClass('centreLoader');
3. $.getJSON('/jsonData/brands.txt', function (data) {
4. $.each(data, function (i, item) {
5. $('#brand').append('<option value="' + data[i].label + '">' + data[i].brandName+ '</option>');
6. });
7. $('#brand').removeClass('centreLoader');
8. loadSavedItem();
9. });
10. };
I've added line numbers to explain simply (although you'll all know what this does!)
Line 3 gets the JSON data from my file (this is valid data as it populates fine), then line 4 begins looping the data returned and populating the drop down.
Line 8 is where things go wrong, this calls the function loadSavedItem
which looks a bit like this:
1. function loadSavedItem(thisItemId) {
2. $.getJSON('/jsonData/QUERY_DB_FOR_THIS_PRODUCT (thisItemId)', function (data) {
3. $('#brand').val(data[0].brand);
4. });
5. };
Again, pretty simple, line 2 gets the JSON output (which is again valid, it populates other fields fine) and sets the field values as applicable (this is obviously a shortened version of the code)
The problem appears to be that loadSavedItem()
is being called too soon, before #brands
is fully populated, so it cannot set the value correctly. If I put a time delay in, then it works.
BUT... I thought that anything after the $(each...
jQuery statement should not happen until $(each)
has finished?
How can I ensure that this is the case?
Share Improve this question edited Feb 20, 2012 at 16:35 John Strickler 25.4k5 gold badges55 silver badges70 bronze badges asked Feb 20, 2012 at 16:30 Jamie HartnollJamie Hartnoll 7,36114 gold badges63 silver badges100 bronze badges 2-
label
andbrandName
are your value/display properties? Then in your 2nd request, you usebrand
to set your value - I'm guessing this corresponds tolabel
since you said this works after a short delay. – John Strickler Commented Feb 20, 2012 at 16:38 -
Yes, that's correct. The data sources are different in each JSON call so therefore the label names are too, but yes, in example 1, the drop down is populated with a
label
value, the output of the second example givesbrand
as the value to select. – Jamie Hartnoll Commented Feb 20, 2012 at 16:43
3 Answers
Reset to default 4In my experience, $(each) can loop while the rest of the script is running, if that makes sense (in Chrome, at least). Maybe it's something to do with "optimisation".
I've solved this problem before by checking data.length
, setting a counter that increments by one and then firing the code off if the counter equals the length.
function loadBrands() {
$('#brand').empty().append('<option value="">Select...</option>').addClass('centreLoader');
$.getJSON('/jsonData/brands.txt', function (data) {
var dataNum = data.length;
var counter = 1;
$.each(data, function (i, item) {
$('#brand').append('<option value="' + data[i].label + '">' + data[i].brandName+ '</option>');
if (dataNum == counter) {
$('#brand').removeClass('centreLoader');
loadSavedItem();
}
counter ++;
});
});
}
My suggestion would be to add the method "loadSavedItem()" in the Success function something like below. This should solve the problem.
$.ajax({
url: url,
dataType: 'json',
async: true,
data: myData,
success: function(data) { // loadSavedItem(); }
});
Hope this Helps!!
I believe the clue is async
setting for jQuery.ajax()
.
http://api.jquery./jQuery.ajax/