homepage Welcome to WebmasterWorld Guest from 54.161.147.106
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Visit PubCon.com
Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
Forum Library, Charter, Moderator: open

JavaScript and AJAX Forum

    
help with possible timing issue when replacing portion of dom element.
nelsonm




msg:4454996
 1:08 pm on May 18, 2012 (gmt 0)

hi all,

I'm dynamically inserting rows into a table in a for loop. After the table row has been inserted, i get and load the select option contents into the empty select tag field named wi-PLID using the jquery .load method. Everything works fine so far.

The problem occurs after i bind the jquery .html method to replace a select "option value" string in the select tag with "option selected='selected' value". If the for loop inserts 3 table rows each containing a loaded select tag, only the last table row select tag get its option string replaced when all table row select tags should be affected.

If i un-comment the alert('x') method below the jquery .load statement line then every table row select tag gets modified as it should as opposed to just the last one. Am i correct in that the problem appears to be a timing issue? And if so, how do i fix it?



// get all work order items.
for(i = 0; i < response.records; i++){
row = response.rows[i]; // row is cell array shortcut.

var id = row["cell"]["0"];

// construct and display all category sales lines.
$('#sa-table-2 tbody').append('<tr id="'+id+'"><td><select name="wi-PLID" class="wi-PLID"></select></td></tr>');

$('tr#'+id+' select[name="wi-PLID"]').load('php/wo-pricelist-se-script.php?wo.SVID='+SVID, data, function(data){$('tr#'+id+' select[name="wi-PLID"]').html(data.replace('option value="'+row['cell']['3']+'"', 'option selected="selected" value="'+row['cell']['3']+'"'));});

// alert('x');

}


Any help would be greatly appreciated.

 

Fotiman




msg:4455018
 2:00 pm on May 18, 2012 (gmt 0)

Try replacing this:


$('tr#'+id+' select[name="wi-PLID"]').load('php/wo-pricelist-se-script.php?wo.SVID='+SVID, data, function(data){$('tr#'+id+' select[name="wi-PLID"]').html(data.replace('option value="'+row['cell']['3']+'"', 'option selected="selected" value="'+row['cell']['3']+'"'));});


with this


$('tr#'+id+' select[name="wi-PLID"]').load('php/wo-pricelist-se-script.php?wo.SVID='+SVID, data, function(data){$(this).html(data.replace('option value="'+row['cell']['3']+'"', 'option selected="selected" value="'+row['cell']['3']+'"'));});

nelsonm




msg:4455064
 3:52 pm on May 18, 2012 (gmt 0)

ok, i replace the second selector definition $('tr#'+id+' select[name="wi-PLID"]') with $(this).

All it did was replace the same option value in all table row select tags.

However, in both cases, it only works correctly when the alert method is un-commented.

I'm completely confused.

Fotiman




msg:4455113
 8:03 pm on May 18, 2012 (gmt 0)

Ok, I think I see the problem. load() is probably an asynchronous call (though the documentation is not clear). In any case, think of it as doing this:

$(el1).load(...);
$(el2).load(...);
callback1();
$(el3).load(...);
callback2();
callback3();

In other words, the order that the callbacks will fire may not be immediate or in the order you expect them.

Now, look at what the callback does:

function(data){
$(this).html(data.replace('option value="' +
row['cell']['3'] + '"',
'option selected="selected" value="' +
row['cell']['3'] + '"'));
}

The problem is that row['cell']['3'] is referring to the value of row when the callback executes, vs. the value of row when load was called. So a bunch of load calls are executed, and the value of row changes for each of those, but none of the callbacks fire until you've already gone through all of the load calls, which is why only the last item is being modified.

To fix this, you need a closure. This is easy, and you already have one for id. Just modify your code slightly:

var id = row["cell"]["0"],
cell3 = row["cell"]["3"];

Then in your callback function, reference cell3 instead of row["cell"]["3"]:


$('tr#'+id+' select[name="wi-PLID"]').load('php/wo-pricelist-se-script.php?wo.SVID='+SVID, data, function(data){$(this).html(data.replace('option value="'+cell3+'"', 'option selected="selected" value="'+cell3+'"'));});

:)

nelsonm




msg:4455132
 8:49 pm on May 18, 2012 (gmt 0)

Nice try but - sorry, it did not work... i'm still getting the same results.

Any other ideas?

Fotiman




msg:4455169
 9:50 pm on May 18, 2012 (gmt 0)

Hmmm... well, I think that's along the correct line. Perhaps, as a workaround, after it finished all the load's you could loop through again to do the replace. But you'd need to keep track of when all the callbacks finished before starting the loop.

nelsonm




msg:4455177
 11:44 pm on May 18, 2012 (gmt 0)

ok, thanks.

Fotiman




msg:4455488
 5:32 am on May 20, 2012 (gmt 0)

Ok, so looking more closely, I can see why that didn't work. We still didn't end up with a closure for the callback function. Try this, keep the cell3 variable as defined above, then add another function which returns a function. We'll execute this function passing in the cell3 variable, and thereby creating the closure:

function dynamicCallback(cell3) {
return (function (data) {
$(this).html(data.replace('option value="'+cell3+'"', 'option selected="selected" value="'+cell3+'"'));
});
}
$('tr#'+id+' select[name="wi-PLID"]').load('php/wo-pricelist-se-script.php?wo.SVID='+SVID, data, dynamicCallback(cell3));

nelsonm




msg:4455574
 2:57 pm on May 20, 2012 (gmt 0)

It worked! Thank you so much...

I didn't know you could call the anonymous function from a named function in the .load method callback parameter in order to preserve the value of cell3 or even the returned data parameter value.

I was going to preserve the cell3 value by passing it to and from the php script via the data variable. That would have required me to modify the php script in order to get the cell3 value from the .load method post variable and pass the value back to the anonymous function. I know it's dirty coding, but i could not think of anything else to do.

Thanks to you... i don't have to modify the php script and i still get to preserve the cell3 value by passing it through the named function. Way more elegant.

thanks again.

Fotiman




msg:4455633
 7:17 pm on May 20, 2012 (gmt 0)

Glad to help. :-)

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved