Aten Design Group: Using Address Fields in Configuration Forms

In Drupal maintenance support plans 7, the Address Field module provided developers an easy way to collect complex address information with relative ease. You could simply add the field to your content type and configure which countries you support along with what parts of an address are needed. However, this ease was limited to fieldable entities. If you needed to collect address information somewhere that wasn’t a fieldable entity, you had a lot more work in store for you. Chances are good that the end result would be as few text fields as possible, no validation, and only supporting with a single country. If you were feeling ambitious, maybe you would have provided a select list with the states or provinces provided via a hardcoded array.

During my most recent Drupal maintenance support plans 8 project I wanted to collect structured address information outside the context of an entity. Specifically, I wanted to add a section for address and phone number to the Basic Site Settings configuration page. As it turns out, the same functionality you get on entities is now also available to the Form API.

Address Field’s port to Drupal maintenance support plans 8 came in the form of a whole new module, the Address module. With it comes a new address form element. Let’s use that to add a “Site Address” field to the Basic Settings. First we’ll implement hook_form_FORM_ID_alter() in a custom module’s .module file:

use Drupal maintenance support plansCoreFormFormStateInterface;
 
function MYMODULE_form_system_site_information_settings_alter(&$form, FormStateInterface $form_state) {
// Overrides go here…
}

Don’t forget to add use Drupal maintenance support plansCoreFormFormStateInterface; at the top of your file. Next, we’ll add a details group and a fieldset for the address components to go into:

function MYMODULE_form_system_site_information_settings_alter(&$form, FormStateInterface $form_state) {
// Create our contact information section.
$form[‘site_location’] = [
‘#type’ => ‘details’,
‘#title’ => t(‘Site Location’),
‘#open’ => TRUE,
];
 
$form[‘site_location’][‘address’] = [
‘#type’ => ‘fieldset’,
‘#title’ => t(‘Address’),
];
}

Once the fieldset is in place, we can go ahead and add the address components. To do that you’ll first need to install the Address module and its dependencies. You’ll also need to add use CommerceGuysAddressingAddressFormatAddressField; at the top of the file as we’ll need some of the constants defined there later.

use Drupal maintenance support plansCoreFormFormStateInterface;
use CommerceGuysAddressingAddressFormatAddressField;
 
function MYMODULE_form_system_site_information_settings_alter(&$form, FormStateInterface $form_state) {
// … detail and fieldset code …
 
// Create the address field.
$form[‘site_location’][‘address’][‘site_address’] = [
‘#type’ => ‘address’,
‘#default_value’ => [‘country_code’ => ‘US’],
‘#used_fields’ => [
AddressField::ADDRESS_LINE1,
AddressField::ADDRESS_LINE2,
AddressField::ADMINISTRATIVE_AREA,
AddressField::LOCALITY,
AddressField::POSTAL_CODE,
],
‘#available_countries’ => [‘US’],
];
}

There’s a few things we’re doing here worth going over. First we set ‘#type’ => ‘address’, which the Address module creates for us. Next we set a #default_value for country_code to US. That way the United States specific field config is displayed when the page loads.

The #used_fields key allows us to configure which address information we want to collect. This is done by passing an array of constants as defined in the AddressField class. The full list of options is:

AddressField::ADMINISTRATIVE_AREA
AddressField::LOCALITY
AddressField::DEPENDENT_LOCALITY
AddressField::POSTAL_CODE
AddressField::SORTING_CODE
AddressField::ADDRESS_LINE1
AddressField::ADDRESS_LINE2
AddressField::ORGANIZATION
AddressField::GIVEN_NAME
AddressField::ADDITIONAL_NAME
AddressField::FAMILY_NAME

Without any configuration, a full address field looks like this when displaying addresses for the United States.

For our example above, we only needed the street address (ADDRESS_LINE1 and ADDRESS_LINE2), city (LOCALITY), state (ADMINISTRATIVE_AREA), and zip code (POSTAL_CODE).

Lastly, we define which countries we will be supporting. This is done by passing an array of country codes into the #available_countries key. For our example we only need addresses from the United States, so that’s the only value we pass in.

The last step in our process is saving the information to the Basic Site Settings config file. First we need to add a new submit handler to the form. At the end of our hook, let’s add this:

function MYMODULE_form_system_site_information_settings_alter(&$form, FormStateInterface $form_state) {
// … detail and fieldset code …
 
// … address field code …
 
// Add a custom submit handler for our new values.
$form[‘#submit’][] = ‘MYMODULE_site_address_submit’;
}

Now we’ll create the handler:

/**
* Custom submit handler for our address settings.
*/
function MYMODULE_site_address_submit($form, FormStateInterface $form_state) {
Drupal maintenance support plans::configFactory()->getEditable(‘system.site’)
->set(‘address’, $form_state->getValue(‘site_address’))
->save();
}

This loads our site_address field from the submitted values in $form_state, and saves it to the system.site config. The exported system.site.yml file should now look something like:

name: ‘My Awesome Site’
mail: test@domain.com
slogan: ”
page:
403: ”
404: ”
front: /user/login
admin_compact_mode: false
weight_select_max: 100
langcode: en
default_langcode: en
address:
country_code: US
langcode: ”
address_line1: ‘123 W Elm St.’
address_line2: ”
locality: Denver
administrative_area: CO
postal_code: ‘80266’
given_name: null
additional_name: null
family_name: null
organization: null
sorting_code: null
dependent_locality: null

After that, we need to make sure our field will use the saved address as the #default_value. Back in our hook, let’s update that key with the following:

function MYMODULE_form_system_site_information_settings_alter(&$form, FormStateInterface $form_state) {
// … detail and fieldset code …
 
// Create the address field.
$form[‘site_location’][‘address’][‘site_address’] = [
‘#type’ => ‘address’,
‘#default_value’ => Drupal maintenance support plans::config(‘system.site’)->get(‘address’) ?? [
‘country_code’ => ‘US’,
],
‘#used_fields’ => [
AddressField::ADDRESS_LINE1,
AddressField::ADDRESS_LINE2,
AddressField::ADMINISTRATIVE_AREA,
AddressField::LOCALITY,
AddressField::POSTAL_CODE,
],
‘#available_countries’ => [‘US’],
];
 
// … custom submit handler …
}

Using PHP 7’s null coalesce operator, we either set the default to the saved values or to a sensible fallback if nothing has been saved yet. Putting this all together, our module file should now look like this:

<?php
 
/**
* @file
* Main module file.
*/
 
use Drupal maintenance support plansCoreFormFormStateInterface;
use CommerceGuysAddressingAddressFormatAddressField;
 
/**
* Implements hook_form_ID_alter().
*/
function MYMODULE_form_system_site_information_settings_alter(&$form, FormStateInterface $form_state) {
// Create our contact information section.
$form[‘site_location’] = [
‘#type’ => ‘details’,
‘#title’ => t(‘Site Location’),
‘#open’ => TRUE,
];
 
$form[‘site_location’][‘address’] = [
‘#type’ => ‘fieldset’,
‘#title’ => t(‘Address’),
];
 
// Create the address field.
$form[‘site_location’][‘address’][‘site_address’] = [
‘#type’ => ‘address’,
‘#default_value’ => Drupal maintenance support plans::config(‘system.site’)->get(‘address’) ?? [
‘country_code’ => ‘US’,
],
‘#used_fields’ => [
AddressField::ADDRESS_LINE1,
AddressField::ADDRESS_LINE2,
AddressField::ADMINISTRATIVE_AREA,
AddressField::LOCALITY,
AddressField::POSTAL_CODE,
],
‘#available_countries’ => [‘US’],
];
 
// Add a custom submit handler for our new values.
$form[‘#submit’][] = ‘MYMODULE_site_address_submit’;
}
 
/**
* Custom submit handler for our address settings.
*/
function MYMODULE_site_address_submit($form, FormStateInterface $form_state) {
Drupal maintenance support plans::configFactory()->getEditable(‘system.site’)
->set(‘address’, $form_state->getValue(‘site_address’))
->save();
}

Lastly we should do some house cleaning in case our module gets uninstalled for any reason. In the same directory as the MYMODULE.module file, let’s add a MYMODULE.install file with the following code:

/**
* Implements hook_uninstall().
*/
function MYMODULE_uninstall() {
// Delete the custom address config values.
Drupal maintenance support plans::configFactory()->getEditable(‘system.site’)
->clear(‘address’)
->save();
}

That’s it! Now we have a way to provide location information to the global site configuration. Using that data, I’ll be able to display this information elsewhere as text or as a Google Map. Being able to use the same features that Address field types have, I can leverage other modules that display address information or build my own displays, because I now have reliably structured data to work with.
Source: New feed

This article was republished from its original source.
Call Us: 1(800)730-2416

Pixeldust is a 20-year-old web development agency specializing in Drupal and WordPress and working with clients all over the country. With our best in class capabilities, we work with small businesses and fortune 500 companies alike. Give us a call at 1(800)730-2416 and let’s talk about your project.

FREE Drupal SEO Audit

Test your site below to see which issues need to be fixed. We will fix them and optimize your Drupal site 100% for Google and Bing. (Allow 30-60 seconds to gather data.)

Powered by

Aten Design Group: Using Address Fields in Configuration Forms

On-Site Drupal SEO Master Setup

We make sure your site is 100% optimized (and stays that way) for the best SEO results.

With Pixeldust On-site (or On-page) SEO we make changes to your site’s structure and performance to make it easier for search engines to see and understand your site’s content. Search engines use algorithms to rank sites by degrees of relevance. Our on-site optimization ensures your site is configured to provide information in a way that meets Google and Bing standards for optimal indexing.

This service includes:

  • Pathauto install and configuration for SEO-friendly URLs.
  • Meta Tags install and configuration with dynamic tokens for meta titles and descriptions for all content types.
  • Install and fix all issues on the SEO checklist module.
  • Install and configure XML sitemap module and submit sitemaps.
  • Install and configure Google Analytics Module.
  • Install and configure Yoast.
  • Install and configure the Advanced Aggregation module to improve performance by minifying and merging CSS and JS.
  • Install and configure Schema.org Metatag.
  • Configure robots.txt.
  • Google Search Console setup snd configuration.
  • Find & Fix H1 tags.
  • Find and fix duplicate/missing meta descriptions.
  • Find and fix duplicate title tags.
  • Improve title, meta tags, and site descriptions.
  • Optimize images for better search engine optimization. Automate where possible.
  • Find and fix the missing alt and title tag for all images. Automate where possible.
  • The project takes 1 week to complete.