My use case is this:

  • 80 - 90% of my traffic is from one country
  • Therefore I want to have a default country set on address fields
  • But i need to support the other 10% of traffic from other countries
  • I want that address field to be fully optional, even if the default country remains selected in the widget

I'm guessing this is the case for very many vendors, so I'm not sure how this keeps getting jammed up.
I swear this was possible previously, but maybe I'm misremembering.

Please can we make this happen without having to implement custom code?

Comments

AaronBauman created an issue. See original summary.

Anonymous’s picture

I've tried replicating this issue using the development version of this module, PHP8.0.10 and Drupal 9.4.5.

I've enabled the module, added the non-required address field to the content type and set the Country default value with the option provided in the field setup. Then I've checked if the Countries default value gets populated and it is.

I am wondering whether you've been using any custom code or other module that interacts with the address field?

aaronbauman’s picture

Yes, the other address values are optional, but the address data is still saved, and the address considered "not empty" if a country is selected.

Maybe a better way to describe the request is: "Allow fields other than country to indicate whether the address field is empty"

igork96’s picture

I tested this and it works properly. Maybe you can set the fields (name, city, street) as required so you'll always have a legit address. Can you be more specific on how you intend to use this? ( why allow the user to save an address with just the country filled)

igork96’s picture

Status: Active » Postponed (maintainer needs more info)
swentel’s picture

I more or less had the same use case too. I solved it by creating my own widget, where I override the form element and massage form values to only save the address field when postal code and locality had a value.

I also override the field_overrides for delta 0 and a specific field to make that one required. If you don't need that, you can leave out that code of course.


namespace Drupal\project\Plugin\Field\FieldWidget;

use Drupal\address\Plugin\Field\FieldWidget\AddressDefaultWidget;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;

/**
 * Plugin implementation of the 'address_default' widget.
 *
 * @FieldWidget(
 *   id = "project_address_default_country",
 *   label = @Translation("Default country - optional fields"),
 *   field_types = {
 *     "address"
 *   },
 * )
 */
class AddressDefaultCountryWidget extends AddressDefaultWidget {

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $element = parent::formElement($items, $delta, $element, $form, $form_state);

    if (empty($element['address']['#default_value']['country_code'])) {
      $element['address']['#default_value']['country_code'] = 'BE';
    }

    if ($delta === 0 && $items->getFieldDefinition()->getName() == 'field_zone_location') {
      $field_overrides = $element['address']['#field_overrides'];
      $field_overrides['postalCode'] = 'required';
      $field_overrides['locality'] = 'required';
      $element['address']['#required'] = TRUE;
      $element['address']['#field_overrides'] = $field_overrides;
    }

    return $element;
  }

  /**
   * {@inheritdoc}
   */
  public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {

    if ($this->isDefaultValueWidget($form_state)) {
      return parent::massageFormValues($values, $form, $form_state);
    }

    $new_values = [];
    $delta_custom = 0;
    foreach ($values as $value) {
      if (!empty($value['address']['locality']) && !empty($value['address']['postal_code'])) {
        $new_values[$delta_custom] = $value['address'];
        $delta_custom++;
      }
    }
    return $new_values;
  }

}
fallenturtle’s picture

This is something I need a solution for as well. I'd like to have the field not be required, but also not make my fully domestic audience select the country when they want to add an address. If I select the country to default to United States, then the rest of the address field becomes required.

bojanz’s picture

Category: Feature request » Support request
Status: Postponed (maintainer needs more info) » Fixed

A custom solution like #6 is the only way.

We can't preselect the country without making the field required. We tried many hacks in the early addressfield days but nothing truly worked for everyone.

Status: Fixed » Closed (fixed)

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