in cart/checkout sometimes the State/Provice field is not filled when an existing address is selected and the adress country field does not match the default country field

CommentFileSizeAuthor
#2 ubercart-zoneselect-race.patch1.99 KBneilnz

Comments

longwave’s picture

Version: 6.x-2.2 » 6.x-2.x-dev

Confirmed, this doesn't reliably occur, but happens on some occasions; it seems to be some sort of race condition between all the event triggers and AJAX requests that are attached to the address fields.

neilnz’s picture

Status: Active » Needs review
StatusFileSize
new1.99 KB

Here's a patch that I've crafted to fix it for me.

The cause of this is that apply_address() in uc_cart.js fills in the country field, then triggers change handlers. Since uc_country_select.js rigs up a change handler to the country field in Drupal.behaviors.ucCountrySelect, this triggers a refresh of the available zones. When that request returns, it selects the null zone ("Please select").

The problem is immediately after firing the change() on the country field (so the first AJAX request has been sent), apply_address() then explicitly calls uc_update_zone_select(), passing a zone. This triggers a second AJAX request to download a list of zones. When this one returns, it will select the correct zone.

This causes a race condition, with the assumption that the first request returns first, selects null, then shortly afterwards the second one returns and populates the correct zone. Unfortunately sometimes the second AJAX request returns first, selecting the right zone, then the other one comes back and selects null. You see this as the correct zone momentarily appearing in the select box followed by it changing to "please select".

My patch gets around this by adding a flag to the country select box before triggering the change handlers. This flag is checked in the change listener in uc_country_select.js, and if present, it doesn't trigger a zone refresh. This means that apply_address() can then call uc_update_zone_select() freely with no other request competing, and the box is reliably populated.

Some additional logic was required when "copy billing to delivery" is checked, as currently it's both copying the options from the source address as well as sending off an AJAX request to fetch the list. I've blocked that too, so now there should only be a single AJAX request for each country change, even with the copy address checkbox checked.

Please review!

Status: Needs review » Needs work

The last submitted patch, ubercart-zoneselect-race.patch, failed testing.

longwave’s picture

Status: Needs work » Fixed

Better late than never. Tested and committed #2 to 6.x-2.x. Not needed in 7.x-3.x.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.