From 3969105d0698af3c572c9de6f4974a49d3c683ff Mon Sep 17 00:00:00 2001
From: Dave Long <dave@longwaveconsulting.com>
Date: Fri, 11 Mar 2011 22:38:56 +0000
Subject: [PATCH] Issue #1071332: Convert address zone selector to Ajax.

---
 shipping/uc_shipping/uc_shipping.js |    4 --
 uc_cart/uc_cart.js                  |    4 --
 uc_cart/uc_cart_checkout_pane.inc   |   62 ++++++++++++++++++++++++----------
 uc_order/uc_order.js                |    4 --
 uc_store/uc_country_select.js       |   44 ------------------------
 uc_store/uc_store.module            |   29 ----------------
 6 files changed, 44 insertions(+), 103 deletions(-)
 delete mode 100644 uc_store/uc_country_select.js

diff --git a/shipping/uc_shipping/uc_shipping.js b/shipping/uc_shipping/uc_shipping.js
index 8a068a4..91e73be 100644
--- a/shipping/uc_shipping/uc_shipping.js
+++ b/shipping/uc_shipping/uc_shipping.js
@@ -26,10 +26,6 @@ function apply_address(type, json_address) {
 
     if (jQuery('#edit-' + type + '-country').val() != address.country) {
       jQuery('#edit-' + type + '-country').val(address.country);
-      try {
-        uc_update_zone_select('edit-' + type + '-country', address.zone);
-      }
-      catch (err) {}
     }
 
     jQuery('#edit-' + type + '-zone').val(address.zone);
diff --git a/uc_cart/uc_cart.js b/uc_cart/uc_cart.js
index cf40ca8..1a763de 100644
--- a/uc_cart/uc_cart.js
+++ b/uc_cart/uc_cart.js
@@ -137,10 +137,6 @@ function apply_address(type, address_str) {
 
   if (jQuery('#edit-panes-' + temp + '-country').val() != address.country) {
     jQuery('#edit-panes-' + temp + '-country').val(address.country).trigger('change');
-    try {
-      uc_update_zone_select('edit-panes-' + temp + '-country', address.zone);
-    }
-    catch (err) { }
   }
 
   jQuery('#edit-panes-' + temp + '-zone').val(address.zone).trigger('change');
diff --git a/uc_cart/uc_cart_checkout_pane.inc b/uc_cart/uc_cart_checkout_pane.inc
index a6d2dab..2b217f8 100644
--- a/uc_cart/uc_cart_checkout_pane.inc
+++ b/uc_cart/uc_cart_checkout_pane.inc
@@ -263,22 +263,29 @@ function uc_checkout_pane_delivery($op, $order, $form = NULL, &$form_state = NUL
         $delivery_city = $order ? $order->delivery_city : '';
         $contents['delivery_city'] = uc_textfield(uc_get_field_name('city'), $delivery_city, uc_address_field_required('city'));
       }
+      $delivery_country = $order ? $order->delivery_country : NULL;
       if (uc_address_field_enabled('country')) {
-        $delivery_country = $order ? $order->delivery_country : NULL;
         $contents['delivery_country'] = uc_country_select(uc_get_field_name('country'), $delivery_country, NULL, 'name', uc_address_field_required('country'));
       }
       if (uc_address_field_enabled('zone')) {
-        if (isset($_POST['panes']['delivery']['delivery_country'])) {
-          $country_id = intval($_POST['panes']['delivery']['delivery_country']);
-        }
-        else {
-          $country_id = $delivery_country;
-        }
         $delivery_zone = $order ? $order->delivery_zone : NULL;
-        $contents['delivery_zone'] = uc_zone_select(uc_get_field_name('zone'), $delivery_zone, NULL, $country_id, 'name', uc_address_field_required('zone'));
-        if (isset($_POST['panes']) && count($contents['delivery_zone']['#options']) == 1) {
+        $contents['delivery_zone'] = uc_zone_select(uc_get_field_name('zone'), $delivery_zone, NULL, $delivery_country, 'name', uc_address_field_required('zone'));
+        if (count($contents['delivery_zone']['#options']) == 1) {
           $contents['delivery_zone']['#required'] = FALSE;
         }
+        $contents['delivery_zone']['#prefix'] = '<div id="delivery-zone">';
+        $contents['delivery_zone']['#suffix'] = '</div>';
+        if (uc_address_field_enabled('country')) {
+          $contents['delivery_country']['#ajax'] = array(
+            'callback' => 'uc_checkout_pane_ajax_country',
+            'wrapper' => 'delivery-zone',
+            'progress' => array(
+              'type' => 'throbber',
+            ),
+            '#pane' => 'delivery',
+            '#field' => 'delivery_zone',
+          );
+        }
       }
       if (uc_address_field_enabled('postal_code')) {
         $delivery_postal_code = $order ? $order->delivery_postal_code : '';
@@ -357,22 +364,29 @@ function uc_checkout_pane_billing($op, $order, $form = NULL, &$form_state = NULL
         $billing_city = $order ? $order->billing_city : '';
         $contents['billing_city'] = uc_textfield(uc_get_field_name('city'), $billing_city, uc_address_field_required('city'));
       }
+      $billing_country = $order ? $order->billing_country : NULL;
       if (uc_address_field_enabled('country')) {
-        $billing_country = $order ? $order->billing_country : NULL;
         $contents['billing_country'] = uc_country_select(uc_get_field_name('country'), $billing_country, NULL, 'name', uc_address_field_required('country'));
       }
       if (uc_address_field_enabled('zone')) {
-        if (isset($_POST['panes']['billing']['billing_country'])) {
-          $country_id = intval($_POST['panes']['billing']['billing_country']);
-        }
-        else {
-          $country_id = $billing_country;
-        }
         $billing_zone = $order ? $order->billing_zone : NULL;
-        $contents['billing_zone'] = uc_zone_select(uc_get_field_name('zone'), $billing_zone, NULL, $country_id, 'name', uc_address_field_required('zone'));
-        if (isset($_POST['panes']) && count($contents['billing_zone']['#options']) == 1) {
+        $contents['billing_zone'] = uc_zone_select(uc_get_field_name('zone'), $billing_zone, NULL, $billing_country, 'name', uc_address_field_required('zone'));
+        if (count($contents['billing_zone']['#options']) == 1) {
           $contents['billing_zone']['#required'] = FALSE;
         }
+        $contents['billing_zone']['#prefix'] = '<div id="billing-zone">';
+        $contents['billing_zone']['#suffix'] = '</div>';
+        if (uc_address_field_enabled('country')) {
+          $contents['billing_country']['#ajax'] = array(
+            'callback' => 'uc_checkout_pane_ajax_country',
+            'wrapper' => 'billing-zone',
+            'progress' => array(
+              'type' => 'throbber',
+            ),
+            '#pane' => 'billing',
+            '#field' => 'billing_zone',
+          );
+        }
       }
       if (uc_address_field_enabled('postal_code')) {
         $billing_postal_code = $order ? $order->billing_postal_code : '';
@@ -402,6 +416,18 @@ function uc_checkout_pane_billing($op, $order, $form = NULL, &$form_state = NULL
 }
 
 /**
+ * Updates the zone selection using Ajax when the country is changed.
+ */
+function uc_checkout_pane_ajax_country($form, &$form_state) {
+  $pane = $form_state['triggering_element']['#ajax']['#pane'];
+  $field = $form_state['triggering_element']['#ajax']['#field'];
+  $element = $form['panes'][$pane][$field];
+
+  unset($element['#title']);
+  return $element;
+}
+
+/**
  * Allows a customer to make comments on the order.
  */
 function uc_checkout_pane_comments($op, $order, $form = NULL, &$form_state = NULL) {
diff --git a/uc_order/uc_order.js b/uc_order/uc_order.js
index 45ef7d8..4695110 100644
--- a/uc_order/uc_order.js
+++ b/uc_order/uc_order.js
@@ -134,10 +134,6 @@ function apply_address(type, address_str) {
 
   if (jQuery('#edit-' + type + '-country').val() != address['country']) {
     jQuery('#edit-' + type + '-country').val(address['country']);
-    try {
-      uc_update_zone_select('edit-' + type + '-country', address['zone']);
-    }
-    catch (err) {}
   }
 
   jQuery('#edit-' + type + '-zone').val(address['zone']);
diff --git a/uc_store/uc_country_select.js b/uc_store/uc_country_select.js
deleted file mode 100644
index b4a6aa7..0000000
--- a/uc_store/uc_country_select.js
+++ /dev/null
@@ -1,44 +0,0 @@
-
-/**
- * @file
- * Switches the zones list when a country is chosen for an address.
- */
-
-/**
- * Sets the select box change behavior for the country selector
- */
-Drupal.behaviors.ucCountrySelect = {
-  attach: function(context, settings) {
-    jQuery('select[id$=-country]:not(.ucCountrySelect-processed)', context).addClass('ucCountrySelect-processed').change(
-      function() {
-        uc_update_zone_select(this.id, '', settings);
-      }
-    );
-  }
-}
-
-/**
- * Updates the zone select element with new options.
- */
-function uc_update_zone_select(country_select, default_zone, settings) {
-  settings = settings || Drupal.settings;
-
-  var zone_select = country_select.substr(0, country_select.length - 8) + '-zone';
-
-  var options = { 'country_id' : jQuery('#' + country_select).val() };
-
-  jQuery('#' + zone_select).parent().siblings('.zone-throbber').attr('style', 'background-image: url(' + settings.basePath + 'misc/throbber.gif); background-repeat: no-repeat; background-position: 100% -20px;').html('&nbsp;&nbsp;&nbsp;&nbsp;');
-
-  jQuery.post(settings.basePath + '?q=uc_js_util/zone_select', options,
-         function (contents) {
-           if (contents.match('value="-1"') != null) {
-             jQuery('#' + zone_select).attr('disabled', 'disabled');
-           }
-           else {
-             jQuery('#' + zone_select).removeAttr('disabled');
-           }
-           jQuery('#' + zone_select).empty().append(contents).val(default_zone).change();
-           jQuery('#' + zone_select).parent().siblings('.zone-throbber').removeAttr('style').empty();
-         }
-  );
-}
diff --git a/uc_store/uc_store.module b/uc_store/uc_store.module
index 86228ba..ff1a453 100644
--- a/uc_store/uc_store.module
+++ b/uc_store/uc_store.module
@@ -172,13 +172,6 @@ function uc_store_menu() {
     'file' => 'uc_store.admin.inc',
   );
 
-  $items['uc_js_util/%'] = array(
-    'title' => 'JS utilities',
-    'page callback' => 'uc_store_js_util',
-    'page arguments' => array(1),
-    'access arguments' => array('access content'),
-    'type' => MENU_CALLBACK,
-  );
   $items['admin/store/customers/orders/%'] = array(
     'title' => 'Customer orders',
     'description' => 'View a list of orders placed by this customer.',
@@ -677,26 +670,6 @@ function uc_store_address_fields_form_reset($form_id, &$form_state) {
   drupal_set_message(t('The configuration options have been reset to their default values.'));
 }
 
-/**
- * A handler for Javascript helper functions...
- */
-function uc_store_js_util($func) {
-  switch ($func) {
-    case 'zone_select':
-      $country_id = intval($_POST['country_id']) > 0 ? intval($_POST['country_id']) : uc_store_default_country();
-      $title = isset($_POST['title']) ? check_plain($_POST['title']) : NULL;
-      $display = isset($_POST['display']) ? check_plain($_POST['display']) : 'name';
-      $select = uc_zone_select($title, NULL, NULL, $country_id, $display);
-      $select['#parents'] = array();
-      $match = array('`<[/]*div[^>]*>`', '`<[/]*select[^>]*>`', '`\n|\r`');
-      $replace = array('', '', '');
-      $output = preg_replace($match, $replace, theme('select', array('element' => $select)));
-  }
-
-  print $output;
-  exit();
-}
-
 /*******************************************************************************
  * Module and Helper Functions
  ******************************************************************************/
@@ -1223,8 +1196,6 @@ function uc_country_select($title, $default = NULL, $description = NULL, $displa
     '#required' => $required,
   );
 
-  drupal_add_js(drupal_get_path('module', 'uc_store') . '/uc_country_select.js');
-
   return $select;
 }
 
-- 
1.6.0.4

