I'm trying to use hook_form_alter() to set #default_values in the commerce checkout form based on some session and product information.

I find that #default_value on the individual sub-elements doesn't work as expected due to the #process parameter indicating _addressfield_process_format_form() will run after any form alter hooks.

_addressfield_process_format_form() implements:

 $child['#default_value'] = $address[$key];

So, it appears the way to set #default_value is to instead create an #address parameter as an address array on the parent address element. This seems inconsistent with Drupal's core Form API.

I would argue that _addressfield_process_format_form() should at least check if the individual fields have #default_value set before overwriting with (possibly) blank information.

if (!isset($child['#default_value'])) {
  $child['#default_value'] = $address[$key];
}

Alternatively (at minimum), for the sake of consistency, the #address key on the parent element should probably be renamed to #default_value.

Comments

rtdean93’s picture

Did you ever figure out how to set a default element?

I have a GEO IP module which detects the country. I would like to set the country in the Customer Profile form to the detected country.

s_leu’s picture

Thanks c4rl, very usefull.

alexgreyhead’s picture

Thanks for the tip c4rl - I've spent the last few hours of my life on this - very frustrating!

I used a code snippet like this to change the default value of the country field:

/**
 * Implementation of hook_form_alter.
 *
 * @param $form
 * @param $form_state
 * @param $form_id
 */
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
  // If we're on the user_register_form or their edit profile form, hide the
  // country selector in the address field:
  if (($form_id == 'user_register_form') || ($form_id == 'user_register_form')) {
    global $language;

    switch ($language->language) {
      case 'fr':
        $form['field_user_address'][LANGUAGE_NONE][0]['#address']['country'] = 'FR';
        break;
      case 'ro':
        $form['field_user_address'][LANGUAGE_NONE][0]['#address']['country'] = 'RO';
        break;
      default:
        // Do nothing.
        break;
    }
  }
}
sokru’s picture

Version: 7.x-1.0-beta1 » 7.x-1.0-beta3
Status: Active » Needs review
StatusFileSize
new508 bytes

Any reason not to use c4rl's method? Attached is a patch against 7.x-1.0-beta3

BassistJimmyJam’s picture

StatusFileSize
new457 bytes

I ran into this same problem and the proposed solution worked for me. However, I had to re-roll the patch against the latest version of dev.

rszrama’s picture

Version: 7.x-1.0-beta3 » 7.x-1.x-dev

I ran into this same issue this evening, and this patch worked for me. This is simpler than fago's patch, but I'll review his to ensure we're not missing something in this fix before just going with this.

muschpusch’s picture

#1662680: Stop duplicating form state values in $form_state['addressfield'] this is fago's approach if someone wants to compare his options....

jody lynn’s picture

Patch in 5 fixed my issue which was the one described in #1662680: Stop duplicating form state values in $form_state['addressfield']: I had a multiple field collection containing an addressfield and the addresses were picking up default values from the first one entered.

Spoke too soon... I have the issue Fago described in #1662680: Stop duplicating form state values in $form_state['addressfield']: I had a multiple field collection containing an addressfield and the addresses were picking up default values from the first one entered. His patch fixed it but this one did not.

jody lynn’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community
jody lynn’s picture

Status: Reviewed & tested by the community » Needs review
dgtlmoon’s picture

Patch in #5 worked for me, @rszrama did you get a chance to do any further testing?

swentel’s picture

Priority: Normal » Major

Same comment as in #1662680: Stop duplicating form state values in $form_state['addressfield'].

This doesn't fix the trick. For instance, add 'Canada' as a country. Then do a form alter to set the country default to Canada (but the instance settings is something different) - the province field won't show up.

I'm raising this to major, there is no decent way to change the default value in code (say based on the current domain) and the form being right. I'll try to look deeper into this, but any more eyes on this would be great, because I've got a major headache already trying to get this right.

bojanz’s picture

Status: Needs review » Closed (duplicate)

swentel is right, this patch doesn't solve anything. It only allows you to set defaults for fields that are the same for all countries (name, company).
Per-country fields (administrative area, locality, etc) have already been built by the time hook_form_alter() runs, so the change doesn't work.

I've opened a new issue that documents the entire problem, please join me there: #2392855: Provide a hook for altering address defaults .