7.x-3.2 release:

I was playing with adding a location field to one of my forms and getting it to update the province select dropdown when the user changed the country. It would not work. If the province field was 'autocomplete' then the autocomplete did work; however, it would not work if the province field was a 'select'. This worked fine though if the location field was added to the account settings form.

After digging into the location module code I have a fix (or at least a workaround) for this for consideration in a future release.

Use case: Here is how I am creating the location field in my form:

function my_form($form, $form_state) {
  .
  .
    $form['Address'] = array (
        '#type'          => 'location_element',
        '#title'         => 'Location',
        '#attributes'    => array('class' => array('my-address'),),
        '#collapsible'   => TRUE,
        '#collapsed'     => FALSE,
        '#location_settings' => array (
                                'form' => array(
                                    'fields' => array (
                                        'name'          => array('collect' => 0, 'weight' => 0),
                                        'country'       => array('collect' => 1, 'weight' => 2, 'default' => 'us'),
                                        'street'        => array('collect' => 1, 'weight' => 4),
                                        'additional'    => array('collect' => 1, 'weight' => 6),
                                        'city'          => array('collect' => 1, 'weight' => 8),
                                                // when widget is 'autocomplete', province changes, but if 'select', it does not work
                                                // need change in location module ajax callback for this
                                        'province'      => array('collect' => 1, 'weight' => 10, 'widget' => 'select'),
                                        'postal_code'   => array('collect' => 1, 'weight' => 12),
                                        'locpick'          => array('collect' => 0, 'weight' => 0),
                                    ),
                                ),
                       ),
        );

  .
  .
}

Fix/Workaround for the problem:
Release 7.x-3.2 Location module, file 'location.module', line 1155, function: _location_country_ajax_callback($form, $form_state)

================================
Modify function FROM:
================================

function _location_country_ajax_callback($form, $form_state) {
  // The isset() checks, ideally, wouldn't ever have to happen because, ideally,
  // this code would never get called, because, ideally, we wouldn't add an
  // ajax call to the country field.  Unfortunately, however, there's no easy
  // way to check whether or not the province is being collected when putting
  // together the country form element in location_locationapi() when that
  // function is called with $op == 'field_expand'
  if (arg(2) == 'locations' && isset($form['locations'][arg(3)]['province'])) {
    return $form['locations'][arg(3)]['province'];
  }
  elseif (isset($form[arg(2)][arg(3)][arg(4)])) {
    if (isset($form[arg(2)][arg(3)][arg(4)]['#entity_type']) && $form[arg(2)][arg(3)][arg(4)]['#entity_type'] == 'field_collection_item') {
      $selected_country_value = $form[arg(2)][arg(3)][arg(4)][arg(5)][arg(6)][arg(7)]['country']['#value'];
      $form[arg(2)][arg(3)][arg(4)][arg(5)][arg(6)][arg(7)]['province']['#options'] = array('' => t('Please select'), 'xx' => t('NOT LISTED')) + location_get_provinces($selected_country_value);
      return $form[arg(2)][arg(3)][arg(4)][arg(5)][arg(6)][arg(7)]['province'];
    }
    return $form[arg(2)][arg(3)][arg(4)]['province'];
  }
}

================================
TO: (3 lines added, 0 lines deleted, 0 lines modified)
================================


function _location_country_ajax_callback($form, $form_state) {
  // The isset() checks, ideally, wouldn't ever have to happen because, ideally,
  // this code would never get called, because, ideally, we wouldn't add an
  // ajax call to the country field.  Unfortunately, however, there's no easy
  // way to check whether or not the province is being collected when putting
  // together the country form element in location_locationapi() when that
  // function is called with $op == 'field_expand'
  if (arg(2) == 'locations' && isset($form['locations'][arg(3)]['province'])) {
    return $form['locations'][arg(3)]['province'];
  }
  elseif (isset($form[arg(2)][arg(3)][arg(4)])) {
    if (isset($form[arg(2)][arg(3)][arg(4)]['#entity_type']) && $form[arg(2)][arg(3)][arg(4)]['#entity_type'] == 'field_collection_item') {
      $selected_country_value = $form[arg(2)][arg(3)][arg(4)][arg(5)][arg(6)][arg(7)]['country']['#value'];
      $form[arg(2)][arg(3)][arg(4)][arg(5)][arg(6)][arg(7)]['province']['#options'] = array('' => t('Please select'), 'xx' => t('NOT LISTED')) + location_get_provinces($selected_country_value);
      return $form[arg(2)][arg(3)][arg(4)][arg(5)][arg(6)][arg(7)]['province'];
    }
    return $form[arg(2)][arg(3)][arg(4)]['province'];
  }
  elseif ((isset($form[arg(2)]['country'])) && (isset($form[arg(2)]['province']))) { // simple location_element with no [und][0] etc
      return $form[arg(2)]['province'];
  }
}

In addition, a one line bugfix and a one line addition has to be made (the bug appears to be a one char typo):
lines 318-331 changed to the following
(line 321 modified, one line added after line 325. Changed lines have comments on them)


    // If State/Province is using the select widget, update the element's options.
    if ($field == 'province' && $fsettings[$field]['widget'] == 'select') {
      // We are building the element for the first time
      // if (!isset($element['value']['country'])) {    // bugfix: 'value' changed to '#value' below
      if (!isset($element['#value']['country'])) {      //
        $country = $fdefaults['country'];
      }
      else {
        $country = $element['#value']['country'];
        $element[$field]['#value'] = '';          // reset selection to top since choices have changed
      }
      $provinces = location_get_provinces($country);
      // The submit handler expects to find the full province name, not the
      // abbreviation. The select options should reflect this expectation.
      $element[$field]['#options'] = array('' => t('Please select'), 'xx' => t('NOT LISTED')) + $provinces;
    }

Comments

gpvdo’s picture

Issue summary: View changes
gpvdo’s picture

Issue summary: View changes
gpvdo’s picture

Issue summary: View changes
gpvdo’s picture

Issue summary: View changes
learnbydrop’s picture

States/Provinces drop down not updating with country change
i tried with above modifications, but itsn't working with 3.2 version.

gpvdo’s picture

Issue summary: View changes
gpvdo’s picture

Soorepalli, this code is working for me. May be you can post your code and I can take a look at it.

Another thing you can do is to print arg(1) through arg(7) in function _location_country_ajax_callback($form, $form_state).
If you trace the execution path inside this, you can see whether this function is actually returning something (a modified select dropdown should be what is returned). Also make sure you have both sets of changes I listed.

gpvdo’s picture

Issue summary: View changes
gpvdo’s picture

Issue summary: View changes
djdevin’s picture

Status: Active » Closed (duplicate)