Index: addresses.css
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/addresses/addresses.css,v
retrieving revision 1.1
diff -u -p -r1.1 addresses.css
--- addresses.css	4 Aug 2008 15:52:59 -0000	1.1
+++ addresses.css	11 Dec 2009 05:05:50 -0000
@@ -1,6 +1,20 @@
 dl.adr dt {
   display: none;
 }
+
 dl.adr dt.show, dl.adr dd {
   display: inline;
 }
+
+/** Edit screens **/
+.addresses-form {
+  margin: 0 0 1em;
+}
+
+.addresses-form .form-item {
+  margin: 0;
+}
+
+.addresses-form .progress-disabled {
+  float: none;
+}
\ No newline at end of file
Index: addresses.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/addresses/addresses.module,v
retrieving revision 1.62
diff -u -p -r1.62 addresses.module
--- addresses.module	11 Feb 2009 07:24:29 -0000	1.62
+++ addresses.module	11 Dec 2009 05:05:50 -0000
@@ -21,7 +21,7 @@ define('ADDRESSES_FIELD_HIDDEN',    3);
  * Its a specific Addresses module hook function, to
  * allow other modules to add more fields to the addresses
  */
-function addresses_addressesfieldapi($op, $fields = array(), $values = array()) {
+function addresses_addressesfieldapi($op, $fields = array(), $values = array(), $parents = NULL, $id) {
   if ($op == 'fields') {
     return array(
       'aname' => array(
@@ -117,7 +117,7 @@ function addresses_addressesfieldapi($op
   }
   elseif ($op == 'form') {
     module_load_include('settings.inc', 'addresses');
-    return _addresses_addressesfieldapi_form($fields, $values);
+    return _addresses_addressesfieldapi_form($fields, $values, $parents, $id);
   }
 }
 
@@ -158,13 +158,12 @@ function addresses_elements() {
  */
 function addresses_elements_process($element, $edit, $form_state, $form) {
   $fields = $element['#fields'];
-  $values = $element['#default_value'];
+  $values = $element['#value'];
 
   // Reset the required fields based on the general required value
   if (empty($element['#required'])) {
     foreach ($fields as $field => $required) {
-      if ($required == ADDRESSES_FIELD_REQUIRED
-          and $form['#id'] == 'content-field-edit-form') {
+      if ($required == ADDRESSES_FIELD_REQUIRED && $form['#id'] == 'content-field-edit-form') {
         $fields[$field] = ADDRESSES_FIELD_SHOW;
       }
     }
@@ -185,12 +184,10 @@ function addresses_elements_process($ele
 
   // Include the main module file
   module_load_include('inc', 'addresses');
-
-  // Get other fields from hook_addressesfieldsapi
-  $element = array_merge(
-    $element,
-    module_invoke_all('addressesfieldapi', 'form', $fields, $values)
-  );
+  // Retrieve fields from modules invoking hook_addressesfieldsapi
+  $additional = module_invoke_all('addressesfieldapi', 'form', $fields, $values, $element['#parents'], $element['#id']);
+  // Merge the additional fields with our element
+  $element = array_merge($element, $additional);
 
   return $element;
 }
@@ -216,11 +213,12 @@ function addresses_menu() {
     'title'             => 'Addresses Format',
     'type'              => MENU_CALLBACK
   );
-  $items['admin/settings/address/autocomplete'] = array(
-    'access callback'   => TRUE,
-    'file'              => 'addresses.settings.inc',
-    'page callback'     => '_addresses_autocomplete',
-    'type'              => MENU_CALLBACK
+  $items['addresses/province_js/%'] = array(
+    'type' => MENU_CALLBACK,
+    'page callback' => '_addresses_province_js',
+    'page arguments' => array(2),
+    'access callback' => TRUE,
+    'file' => 'addresses.settings.inc',
   );
 
   return $items;
Index: addresses.settings.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/addresses/addresses.settings.inc,v
retrieving revision 1.25
diff -u -p -r1.25 addresses.settings.inc
--- addresses.settings.inc	22 Jan 2009 02:52:52 -0000	1.25
+++ addresses.settings.inc	11 Dec 2009 05:05:50 -0000
@@ -7,136 +7,159 @@
  */
 
 /**
- * It splits the _addresses_addressesfieldapi_form into more pieces,
- * reducing the memory consumption on non related pages.
+ * It splits the _addresses_addressesfieldapi_form into more pieces, reducing
+ * the memory consumption on non related pages.
  *
  * @ingroup form
  */
-function _addresses_addressesfieldapi_form($fields = array(), $values = array()) {
+function _addresses_addressesfieldapi_form($fields = array(), $values = array(), $parents = NULL, $id = NULL) {
   $field_weights = variable_get('addresses_field_weight', array());
 
+  $form['#tree'] = TRUE;
   // Let users select if the address is the primary
-  if (!empty($fields['is_primary'])) {
+  if ($fields['is_primary']) {
     $form['is_primary'] = array(
-      '#type'           => 'checkbox',
-      '#title'          => t('Default address'),
-      '#default_value'  => isset($values['is_primary']) ? $values['is_primary'] : '',
-      '#weight'         => empty($field_weights['is_primary']['weight']) ? 0 :
-        $field_weights['is_primary']['weight'],
+      '#type' => 'checkbox',
+      '#title' => t('Primary address'),
+      '#default_value' => isset($values['is_primary']) ? $values['is_primary'] : FALSE,
+      '#attributes' => array(
+        'class' => 'addresses-is-primary',
+      ),
+      '#weight' => empty($field_weights['is_primary']['weight']) ? 0 : $field_weights['is_primary']['weight'],
     );
   }
 
   // Adds the Address Name (Home, Office, Rio de Janeiro...)
-  if (!empty($fields['aname'])) {
+  if ($fields['aname']) {
     $form['aname'] = array(
-      '#type'           => 'textfield',
-      '#title'          => t('Address name'),
-      '#default_value'  => isset($values['aname']) ? $values['aname'] : '',
-      '#size'           => 50,
-      '#maxlength'      => 75,
-      '#description'    => t('e.g. a place of business, venue, meeting point'),
-      '#attributes'     => NULL,
-      '#required'       => ($fields['aname'] == ADDRESSES_FIELD_REQUIRED),
-      '#weight'         => empty($field_weights['aname']['weight']) ? 0 :
-        $field_weights['aname']['weight'],
+      '#type' => 'textfield',
+      '#title' => t('Name'),
+      '#description' => t('i.e. a place of business, venue, meeting point'),
+      '#default_value' => empty($values['aname']) ? '' : $values['aname'],
+      '#attributes' => array(
+        'class' => 'addresses-name',
+      ),
+      '#required' => ($fields['aname'] == ADDRESSES_FIELD_REQUIRED),
+      '#weight' => empty($field_weights['aname']['weight']) ? 0 : $field_weights['aname']['weight'],
+      '#maxlength' => 75,
+      '#size' => 50,
     );
   }
 
   // Adds the Country
-  if (!empty($fields['country'])) {
+  if ($fields['country']) {
     // Get a list of enabled countries
+    $country = empty($values['country']) ? variable_get('addresses_country_default', 'us') : $values['country'];
     $countries = _addresses_country_get(variable_get('addresses_country_list', array()));
-    if (count($countries) > 1) {
-      $countries = array('' => '') + $countries;
-    }
-
     $form['country'] = array(
-      '#type'           => 'select',
-      '#title'          => t('Country'),
-      '#default_value'  => isset($values['country']) ? $values['country'] : '',
-      '#options'        => $countries,
-      '#description'    => NULL,
-      '#extra'          => 0,
-      '#multiple'       => FALSE,
-      '#required'       => ($fields['country'] == ADDRESSES_FIELD_REQUIRED),
-      '#weight'         => empty($field_weights['country']['weight']) ? 0 :
-        $field_weights['country']['weight'],
+      '#type' => 'select',
+      '#title' => t('Country'),
+      '#default_value' => $country,
+      '#attributes' => array(
+        'class' => 'addresses-country',
+      ),
+      '#required' => ($fields['country'] == ADDRESSES_FIELD_REQUIRED),
+      '#weight' => empty($field_weights['country']['weight']) ? 0 : $field_weights['country']['weight'],
+      '#options' => $countries,
     );
   }
 
   // Adds the Province field
-  if (!empty($fields['province'])) {
+  if ($fields['province']) {
+    if ($fields['country']) {
+      // Filter provinces based on country
+      $form['country']['#ahah'] = array(
+        'path' => 'addresses/province_js/'. serialize($parents),
+        'effect' => 'fade',
+        'wrapper' => $id .'-province-wrapper',
+      );
+    }
+
+    // Get a list of the countries provinces
+    $provinces = _address_province_get($country);
     $form['province'] = array(
-      '#default_value'  => isset($values['province']) ? $values['province'] : '',
-      '#maxlength'      => 16,
-      '#required'       => ($fields['province'] == ADDRESSES_FIELD_REQUIRED),
-      '#size'           => 16,
-      '#title'          => t('State / Province'),
-      '#type'           => 'textfield',
-      '#weight'         => empty($field_weights['province']['weight']) ? 0 :
-        $field_weights['province']['weight'],
+      '#type' => 'select',
+      '#title' => t('State / Province'),
+      '#default_value' => empty($values['province']) ? '' : $values['province'],
+      '#attributes' => array(
+        'class' => 'addresses-province',
+      ),
+      '#required' => ($fields['province'] == ADDRESSES_FIELD_REQUIRED),
+      '#weight' => empty($field_weights['province']['weight']) ? 0 : $field_weights['province']['weight'],
+      '#options' => $provinces,
     );
-    $form['#element_validate'][] = '_addresses_province_validate';
   }
 
   // Adds the City
-  if (!empty($fields['city'])) {
+  if ($fields['city']) {
     $form['city'] = array(
-      '#type'           => 'textfield',
-      '#title'          => t('City'),
-      '#default_value'  => isset($values['city']) ? $values['city'] : '',
-      '#size'           => 50,
-      '#maxlength'      => 255,
-      '#required'       => ($fields['city'] == ADDRESSES_FIELD_REQUIRED),
-      '#weight'         => empty($field_weights['city']['weight']) ? 0 :
-        $field_weights['city']['weight'],
+      '#type' => 'textfield',
+      '#title' => t('City'),
+      '#default_value' => empty($values['city']) ? '' : $values['city'],
+      '#attributes' => array(
+        'class' => 'addresses-city',
+      ),
+      '#required' => ($fields['city'] == ADDRESSES_FIELD_REQUIRED),
+      '#weight' => empty($field_weights['city']['weight']) ? 0 : $field_weights['city']['weight'],
+      '#maxlength' => 255,
+      '#size' => 50,
     );
   }
 
-  // Adds the Streets and the Additional fields
-  if (!empty($fields['street'])) {
+  // Adds the Streets
+  if ($fields['street']) {
     $form['street'] = array(
-      '#type'           => 'textfield',
-      '#title'          => t('Street'),
-      '#default_value'  => isset($values['street']) ? $values['street'] : '',
-      '#size'           => 50,
-      '#maxlength'      => 255,
-      '#required'       => ($fields['street'] == ADDRESSES_FIELD_REQUIRED),
-      '#weight'         => empty($field_weights['street']['weight']) ? 0 :
-        $field_weights['street']['weight'],
-    );
-    if (!empty($fields['additional'])) {
-      $form['additional'] = array(
-        '#type'           => 'textfield',
-        '#title'          => t('Additional'),
-        '#default_value'  => isset($values['additional']) ? $values['additional'] : '',
-        '#size'           => 50,
-        '#maxlength'      => 255,
-        '#weight'         => empty($field_weights['additional']['weight']) ? 0 :
-          $field_weights['additional']['weight'],
-      );
-    }
+      '#type' => 'textfield',
+      '#title' => t('Street'),
+      '#default_value' => empty($values['street']) ? '' : $values['street'],
+      '#attributes' => array(
+        'class' => 'addresses-street',
+      ),
+      '#required' => ($fields['street'] == ADDRESSES_FIELD_REQUIRED),
+      '#weight' => empty($field_weights['street']['weight']) ? 0 : $field_weights['street']['weight'],
+      '#maxlength' => 255,
+      '#size' => 50,
+    );
+  }
+
+  // Adds the Additional
+  if ($fields['additional']) {
+    $form['additional'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Additional'),
+      '#default_value' => empty($values['additional']) ? '' : $values['additional'],
+      '#attributes' => array(
+        'class' => 'addresses-additional',
+      ),
+      '#required' => ($fields['additional'] == ADDRESSES_FIELD_REQUIRED),
+      '#weight' => empty($field_weights['additional']['weight']) ? 0 : $field_weights['additional']['weight'],
+      '#maxlength' => 255,
+      '#size' => 50,
+    );
   }
 
   // Adds the Postal Code
-  if (!empty($fields['postal_code'])) {
+  if ($fields['postal_code']) {
     $form['postal_code'] = array(
-      '#type'           => 'textfield',
-      '#title'          => t('Postal code'),
-      '#default_value'  => isset($values['postal_code']) ? $values['postal_code'] : '',
-      '#size'           => 16,
-      '#maxlength'      => 16,
-      '#required'       => ($fields['postal_code'] == ADDRESSES_FIELD_REQUIRED),
-      '#weight'         => empty($field_weights['postal_code']['weight']) ? 0 :
-        $field_weights['postal_code']['weight'],
+      '#type' => 'textfield',
+      '#title' => t('Postal code'),
+      '#default_value' => empty($values['postal_code']) ? '' : $values['postal_code'],
+      '#attributes' => array(
+        'class' => 'addresses-postal-code',
+      ),
+      '#required' => ($fields['postal_code'] == ADDRESSES_FIELD_REQUIRED),
+      '#weight' => empty($field_weights['postal_code']['weight']) ? 0 : $field_weights['postal_code']['weight'],
+      '#maxlength' => 16,
+      '#size' => 16,
     );
   }
 
+  // If the field is set to be hidden, change its type accordingly
   foreach (array_keys($fields) as $ftype) {
     if ($fields[$ftype] == ADDRESSES_FIELD_HIDDEN) {
       $form[$ftype] = array(
-        '#type'           => 'hidden',
-        '#value'          => isset($values[$ftype]) ? $values[$ftype] : '',
+        '#type'   => 'hidden',
+        '#value'  => isset($values[$ftype]) ? $values[$ftype] : '',
       );
     }
   }
@@ -145,70 +168,44 @@ function _addresses_addressesfieldapi_fo
 }
 
 /**
- * Create a list of states from a given country.
- *
- * @param $country
- *   String. The country code
- * @param $string
- *   String (optional). The state name typed by user
+ * Callback function for loading provinces when changing the country of an
+ * address.
+ * 
+ * @param $parents
+ *   The serialized array of the elements parents that has been modified.
  * @return
- *   Javascript array. List of states
+ *   None. Code is returned to the calling javascript function via drupal_json.
  */
-function _addresses_autocomplete($country, $string = '') {
-  $matches  = array();
-
-  // Check if the country code is there
-  if ($country) {
-
-    $string   = drupal_strtolower($string);
-    $string   = '/^'. $string .'/';
+function _addresses_province_js($parents) {
+  module_load_include('inc', 'address');
+  $parents = unserialize($parents);
+  // Make a copy of post
+  $post = $_POST;
+  foreach ($parents as $key => $parent) {
+    $post = $post[$parent];
+  }
+  $country = $post['country'];
+  $provinces = _address_province_get($country);
+
+  // Build a replacement province form element
+  $item = array(
+    '#type' => 'select',
+    '#title' => t('State / Province'),
+    '#options' => $provinces,
+  );
 
-    $provinces   = _addresses_province_get($country);
-
-    // Get only the first 5 provinces that matches
-    // partially with the given piece of text
-    if (!empty($provinces)) {
-      while (list($code, $name) = each($provinces)) {
-        if ($counter < 5) {
-          if (preg_match($string, drupal_strtolower($name))) {
-            $matches[$code] = drupal_strtolower($name);
-            ++$counter;
-          }
-        }
-      }
-    }
+  // Generate the form id
+  $id = form_clean_id('edit-'. implode('-', $parents) .'-province');
+  // Generate the input name
+  $name = array_shift($parents);
+  if (count($parents)) {
+    $name .= '['. implode('][', $parents) .']';
   }
-  // Print the results as a JS array.
-  echo drupal_to_js($matches);
 
-  // Finish the page. Its necessary to not continue
-  // to build a regular page
-  exit();
-}
-
-/**
- * Validate the province field
- */
-function _addresses_province_validate($form, &$form_state) {
-  // Check if its a valid province.
-  // It should be the Province code listed on the
-  // given COUNTRY.inc file
-  if ($province = $form['province']['#value']
-      and $country = $form['country']['#value']
-      and $provinces = _addresses_province_get($country)
-      and empty($provinces[drupal_strtoupper($province)])) {
-
-    // Get the province fieldname
-    $field_name = $form['province']['#name'];
-    $field_name = drupal_substr($field_name, 0, -1);
-    $field_name = preg_replace('/([^]])\[/', '\1][', $field_name);
-
-    $countries = _addresses_country_get();
-    form_set_error($field_name, t('Could not find %province as a province from %country. Try to use the province abbreviation or number.',
-      array('%province' => $form['province']['#value'],
-      '%country' => $countries[$country])));
-
-  }
+  // Generate the replacement HTML
+  $output = '<label for="'. $id .'">'. t('State / Province: ') . '</label>';
+  $output .= '<select id="'. $id .'" name="'. $name .'[province]">'. form_select_options($item) .'</select>';
+  drupal_json(array('status' => TRUE, 'data' => $output));
 }
 
 /**
@@ -288,8 +285,8 @@ function _addresses_settings(&$form_stat
 }
 
 /**
- * Generate a settings form that will allow admins to choose
- * which addresses fields shuold be used.
+ * Generate a settings form that will allow admins to choose which addresses
+ * fields should be used.
  *
  * @param field_values
  *   Array (optional). The default values for each field, if any
@@ -382,6 +379,9 @@ function _addresses_settings_format(&$fo
  * @ingroup themeable
  */
 function theme_addresses_elements(&$element) {
+  // Include the addresses.css file on any page loading the form
+  drupal_add_css(drupal_get_path('module', 'addresses') .'/addresses.css');
+
   return theme('form_element', $element, '<div class="addresses-form">'. $element['#children'] .'</div>');
 }
 
@@ -437,4 +437,4 @@ function theme_addresses_field_weight(&$
     );
   }
   return theme('table', array(), $rows, array('id' => 'addresses-field-weight')) . drupal_render($form);
-}
\ No newline at end of file
+}
Index: addresses_cck/addresses_cck.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/addresses/addresses_cck/addresses_cck.module,v
retrieving revision 1.16
diff -u -p -r1.16 addresses_cck.module
--- addresses_cck/addresses_cck.module	11 Dec 2008 18:20:24 -0000	1.16
+++ addresses_cck/addresses_cck.module	11 Dec 2009 05:05:50 -0000
@@ -5,7 +5,9 @@
  * @file
  * You can associate a geographic address with content, using CCK.
  *
- * @todo Ensure this will work with the Views and GMap
+ * @TODO: Ensure this will work with the Views and GMap
+ * @TODO: Default weights of fields seems to be inconsistent. Need to
+ *   standardize weighting of fields between forms.
  */
 
 /**
@@ -246,9 +248,9 @@ function addresses_cck_widget(&$form, &$
 
   // The Addresses field
   $element = array(
-    '#type'           => 'addresses_elements',
-    '#fields'         => $fields,
-    '#default_value'  => $items[$delta],
+    '#type' => $field['widget']['type'],
+    '#default_value' => isset($items[$delta]) ? $items[$delta] : '',
+    '#fields' => $fields,
   );
 
   return $element;
Index: addresses_phone/addresses_phone.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/addresses/addresses_phone/addresses_phone.module,v
retrieving revision 1.10
diff -u -p -r1.10 addresses_phone.module
--- addresses_phone/addresses_phone.module	20 Jan 2009 20:31:42 -0000	1.10
+++ addresses_phone/addresses_phone.module	11 Dec 2009 05:05:50 -0000
@@ -12,7 +12,7 @@
  * Its a specific Addresses module hook function, to
  * allow other modules to add more fields to the addresses
  */
-function addresses_phone_addressesfieldapi($op, $fields = array(), $values = array()) {
+function addresses_phone_addressesfieldapi($op, $fields = array(), $values = array(), $parents = NULL, $id = NULL) {
   if ($op == 'fields') {
     return array(
       'phone' => array(
