Issues such as #1285980: hook_form_alter() doesn't affect #default_values as expected and #2070311: hook_form_alter only partially refreshing locality fields to reflect country have stumbled upon a big problem: there is no way to programatically set default values for an addressfield.

Addressfield intentionally clobbers #default_value with its own defaults, but even if it didn't, hook_form_alter() and hook_field_widget_form_alter() still couldn't work.
Why? Because when they run the form has already been built, and the address.inc plugin has already added the country-specific element based on $address['country'].

Obviously, the defaults need to be determined before the rest of the form generation happens.
I experimented with using a plugin with a very low weight, but plugins don't have enough context to perform this role, since they can't distinguish between values that are intentionally empty (emptied by the user), and empty by default.

My suggested solution is to add a hook_addressfield_default_values_alter($default_values, $context); which will run before the plugins are called.

Once #2159251: Clear country specific fields when changing the country is fixed, every country change will actually remove the administrative_area, locality, dependent_locality, postal_code (list of fields still under consideration) fields, allowing the defaults to be added again. This will allow for per-country defaults.

So for example, the hook could select a different default country based on the active language, and could provide different defaults for different selected countries.

Blockers:
#2392863: Remove the default values instance setting, introduce a default country instance setting
#2159251: Clear country specific fields when changing the country

Comments

bojanz’s picture

Title: Provide a hook for providing address defaults » Provide a hook for altering address defaults
swentel’s picture

A hook is fine for me.

bojanz’s picture

Issue summary: View changes
bojanz’s picture

Status: Active » Fixed

  • bojanz committed bb4b1d9 on 7.x-1.x
    Issue #2392855: Provide a hook for altering address defaults
    
swentel’s picture

Looks to be working nicely, thank!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

bkeller’s picture

I don't know what I could be doing wrong here, but I can't get this hook to fire.
I've added it to my module with standard format

my_module_addressfield_default_values_alter(&$default_values, $context) {
  dpm($default_values);
}

And I get nothing. Have also tried setting country here with no effect.
I've cleared caches, verified the module was updated on the server. Even used hook_field_widget_addressfield_standard_form_alter which does work (though not for my purpose).
addressfield 7.x-1.2; Drupal 7.59; webform 7.x-3.27

I'm trying to load data into a webform based on existing user data. Everything works in hook_form_alter except the states don't update, so if the country is not the form default, the states won't update to the new country. I found this hook and thought my problems were solved...

Anonymous’s picture

closed thread but for future google searchers,

@bkeller did you flush caches?

works perfectly for me, I only wish I had found this earlier.

function MYMODULE_addressfield_default_values_alter(&$default_values, $context) {
  // user register form as address values are empty
  if(isset($context['instance']) && $context['instance']['field_name'] === 'field_user_address' && empty($context['address'])) {
    dpm($context);
  }
}

thanks @bojanz

bkeller’s picture

@pintoflager
Yup, drush cc all is always my first line of defense!
I ended up taking a different path with my solution, but if I could have figured out why that was not working for me, it would have been much simpler and way more elegant!

Thank you though.