I have to replace the label "Company" with "Building". Using 8.x-1.0-rc3, I was able to do this via hook_form_alter:

function mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if (in_array($form_id, array('node_location_edit_form', 'node_location_form'))) {
    $form['field_address']['widget'][0]['organization']['#title'] = t('Building');
  }
}

However, this no longer works in rc4 (and when I look at the form array, I can see that $form['field_address']['widget'][0]['organization'] no longer exists). I've also tried overriding the string in settings.php:

$settings['locale_custom_strings_en'][''] = array(
  'Company' => 'Building',
);

I'm able to override other strings this way (so I'm confident that it's working in general), but it doesn't work for address fields.

What's the best way to change the label of an address field? Thanks in advance for any advice.

Comments

noah created an issue. See original summary.

bojanz’s picture

Status: Active » Fixed

You'd add a #process callback to the address form element, then alter it from there.

  $form['field_address']['widget'][0]['address']['#process'][] = 'mymodule_change_labels'; 
function mymodule_change_labels($element, $form_state, $complete_form) {
  $element['organization']['#title'] = 'Building';
}

That said, it feels like you're abusing the Organization field for something it was not intended for. I'd rather use the address_line2 for that.

noah’s picture

Status: Fixed » Active

Thanks @bojanz -- I'm not sure if it's a bug or if I was doing something wrong, but adding anything to #process as described above was causing the entire address widget to show up empty (even if I just returned the element unchanged). This put me on the right track, though, and I was able to make it work using #after_build. In case anyone comes across this looking to achieve something similar, here's what seems to have worked:

// change the title of the "Company" field to "Building"
function mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if (in_array($form_id, array('node_location_edit_form', 'node_location_form'))) {
    $form['field_address']['widget'][0]['address']['#after_build'][] = 'mymodule_address_label';
  }
}
function mymodule_address_label($element, $form_state) {
  $element['organization']['#title'] = t('Building');
  return $element;
}

I agree with you that we're stretching the semantics a bit re: "Company" vs. "Building", but it sort of makes sense in this instance because here "Building" is analogous to "Organization" (also, we're already using address_line2).

Thanks again!

bojanz’s picture

Status: Active » Fixed

but adding anything to #process as described above was causing the entire address widget to show up empty (even if I just returned the element unchanged).

You probably didn't have "return $element;" at the end of you process callback. Forgot to mention that. Anyway, after_build is just as fine.

Status: Fixed » Closed (fixed)

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

finne’s picture

If you only need to change the labels, you can also use a translation:
- enable the interface translation module
- for the English (built-in) language, enable Interface translation to English: /admin/config/regional/language/edit/en
- visit a form or display with an address field to generate the translation source strings
- translate the labels: /admin/config/regional/translate

The advantage is that the labels are changed everywhere using 1 setting.

budalokko’s picture

At least for current versions (Drupal 8.5.3, Address 1.3), when adding following code to the form_alter the original field element's process callback (Drupal\address\Element\Address::processAddress) is not called at all:
$form['field_address']['widget'][0]['address']['#process'][] = 'mymodule_change_labels';
That's why even if this function returns $element the wiget is empty.

For it to work its necessary calling the original field element's process callback explicitely for example like this:

$form['field_address']['widget'][0]['address']['#process'][] = ['Drupal\address\Element\Address', 'processAddress']; 
$form['field_address']['widget'][0]['address']['#process'][] = 'mymodule_change_labels'; 
FirstSanny’s picture

Hello Guys,

I'm currently working with the versions Drupal Core 8.5.5 and Address 1.4. But the following code isn't changing anything. I do know it is called because i get the drupal message, but no change is made. Am I doing something wrong here?

@budalokko Maybe you should update to Address version 1.4? I don't need the original process call.

/*
 * Implementation of hook_form_alter()
 */
function mymodule_form_alter(&$form, &$form_state, $form_id){
  // Change form id here
   if ($form_id == 'myFormId') {
       $form['myAdressField']['widget'][0]['address']['#process'][] = 'mimi_wizard_address_label';
   }
}

function mymodule_address_label($element, $form_state, $complete_form) {
  drupal_set_message('mymodule_address_label() executed.');
  $element['given_name']['#size'] = 30;
  return $element;
}
johnpitcairn’s picture

Version: 8.x-1.0-rc4 » 8.x-1.x-dev

The example code above does not work for me, nor does the documentation example at drupalcommerce.org. These appear to assume the addressfield is a standard field in the form.

In my case the addressfield is a field on a profile checkout pane, added via Commerce Profile Panes, using inline entity form. It's necessary to add the after_build callback via hook_inline_entity_form_entity_form_alter(), and I must add it to the widget base element, not the widget address element. The code below successfully alters the address_line1 field label:

function MYMODULE_inline_entity_form_entity_form_alter(&$entity_form, FormStateInterface &$form_state) {
  if ($entity_form['#entity_type'] == 'profile' && isset $entity_form['address']) {
    $entity_form['address']['widget']['#after_build'][] = 'MYMODULE_address_after_build';
  }
}

function MYMODULE_address_after_build($element, FormStateInterface $form_state) {
  $element[0]['address']['address_line1']['#title'] = t('Postal address');
  return $element;
}

Hope this helps. I do wonder when the address_line1 label default got changed from simply "Address" to "Street address"? That's a big assumption to make.

bojanz’s picture

Just a note to say that there are docs now: https://docs.drupalcommerce.org/commerce2/developer-guide/customers/addr...

Of course, checkout will be a different story, especially if using a contrib module that does its own embedding.

djg_tram’s picture

Bojan, the form id is something like profile_customer_address-book-add_form, note the dashes instead of underlines. Is this a bug that can't be fixed any more because people rely on it, or is it on purpose?

sagesolutions’s picture

Also, for editing an existing address, the form id is profile_customer_address-book-edit_form.

Has anyone figured out how to override the address line during the checkout process? I tried #9, but my MYMODULE_inline_entity_form_entity_form_alter function is never called.

luksak’s picture

@sagesolutions no, I am trying the same right now. Did you figure this out?

luksak’s picture

I figured it out like this:

function MODULE_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'commerce_checkout_flow_multistep_custom' && $form['#step_id'] == 'order_information') {
    if (isset($form['shipping_information']['shipping_profile']['address']['widget'][0]['address'])) {
      $form['shipping_information']['shipping_profile']['address']['widget'][0]['address']['#after_build'][] = 'MODULE_customize_address';
    }
  }
}

function MODULE_customize_address($element, FormStateInterface $form_state) {
  ...
  return $element;
}
luksak’s picture

@bojanz Should we update the docs at https://docs.drupalcommerce.org/commerce2/developer-guide/customers/addr... ? For me those instructions didn't work.