views:

88

answers:

3

I'm improving a checkout page and have 2 identical 'country select' menus. One at the top of the page to calculate postage, and one at the bottom for entering delivery address. Our customers seem to have a lot of difficulty grasping that they need to pick the same country in both menus, or the price calculation will be incorrect.

So what i'm trying to do is to make a change on one menu update its pair and vice versa. At the moment, the first menu (menu A) that I change works fine repeatedly (affects menu B) but once menu A has been changed, changed to menu B are not picked up. Same thing in reverse, if menu B is changed first, changes to menu A are not picked up by the javascript.

The menus are written back into the page with the appropriate option selected. I was wondering if it is this re-writing with ajax that stops the menu from being able to be watched in the jquery.

Here's the full script (the UPDATE MENU... bits are the important functions, just thought I would leave the rest of my functions in the script in case they were causing a problem)

// wait for the DOM to be loaded 
$(document).ready(function() {

    // see if countryIsoTop menu has changed
    $("#countryIsoTop").change(function() {

     // UPDATE MENU IN SHIPPING OPTIONS
     $.ajax({
     type: "POST",
     url: "incViewbasketShippingBoxes.php", 
     data: $("#checkoutform").serialize(),
        success: function(response) {
         $('#shippingBoxes').html(response);
     }
     });
    // prevent actual form submission
    return false;
  }); 





    // see if countryIsoShipping menu has changed
    $("#countryIsoShipping").change(function() {


     // UPDATE MENU IN TOP COUNTRY BOX
     var data = 'countryIsoShipping=' + $("#countryIsoShipping").val();  
     $.ajax({
     type: "POST",
     url: "incViewbasketCountryChooser.php", 
     data: data,
        success: function(response) {
         $('#countryIsoTopBox').html(response);
     }
     });
    // prevent actual form submission
    return false;
  });   

});

Here is the HTML

<div name="countryIsoTopBox" id="countryIsoTopBox">
<?
require("incViewbasketCountryChooser.php");
?>
</div>

...

<div id="shippingBoxes">
<?
require("incViewbasketShippingBoxes.php");
?>
</div>

Here is an example of what the php produces

<select name="countryIsoTop" id="countryIsoTop">
<option value="">Choose delivery country</option>
<option value="AF">Afghanistan</option>
.
.
.
</select>

and

<select name="countryIsoShipping" id="countryIsoShipping">
<option value="">Choose delivery country</option>
<option value="AF">Afghanistan</option>
.
.
.
</select>
A: 

Ok it looks like the easiest thing to do for you would be to use one of the following two solutions

  1. change handler from change to live+click on option elements
  2. change it like this. Extract functions and then rebind after update of the select

Solution 1

Change these

$("#countryIsoTop").change(function() {
$("#countryIsoShipping").change(function() {

to

$("#countryIsoTop option").live("click", function() {
$("#countryIsoShipping option").live("change", function() {

Note of course now the this inside the function is the option itself not the select anymore. Thus you may have to adjust some code.


Solution 2

var topFn = function() {
    // UPDATE MENU IN SHIPPING OPTIONS
    ...
        success: function(response) {
            $('#shippingBoxes').html(response).find("#countryIsoShipping").change(shippingFn);
        }
    ...
}

var shippingFn = function() {
    // UPDATE MENU IN TOP COUNTRY BOX
    ...
        success: function(response) {
            $('#countryIsoTopBox').html(response).find("#countryIsoTop").change(topFn);
    }
    ...
});

$(document).ready(function() {
    $("#countryIsoTop").change(topFn);
    $("#countryIsoShipping").change(shippingFN);
}
jitter
Hi, I have done as you said, shortened the javascript and given responses of the output / HTML/.As for 'why' - at the moment I only have one menu for postage calculation, when customers get further down the page they complain that they don't know how to change the delivery country. It may seem obvious that they could just change the top menu again but I am trying to make it as easy as possible for all customers by linking the 2 menus.
Ashley
A: 

I think your best bet is to set handlers on both selects, when one is changed, update the other

 //ready
 var select1=$('#countryIsoTop'), select2=$('#countryIsoShipping');
 select1.change(function(){
   $('option[value='+$(this).val()+']', select2).attr({selected: 'selected'})
 });
 select2.change(function(){
   $('option[value='+$(this).val()+']', select1).attr({selected: 'selected'})
 });
czarchaic
A: 

I have a related question, which might answer the question above.

If I output a new element to a page with the ajax response, can I monitor this new element for click / change etc from within the jquery onload 'ready' function?

$(document).ready(function() {
  // see if newly created element has changed
  $("#newlycreatedelement").change(function() {
  .
  .
  });
});

Or should I move the tests for the new elements out of the onload part?

Ashley