Problem/Motivation

I want to display an addressfield where only the country is required. I want this because I want to store people's locations (up till now I have always used addressfield for this) and in one instance I only really care about the country although having the rest of the address is a nice optional extra.

If I set the field to required, several of the values are needed. If I set the field to not be required none of them are.

I expected to have to write a small form alter hook to achieve this behaviour however, after two hours and a hook growing to 20-30 lines I have made no progress - this must be an API bug, there is no way that this should take that long!!!

Attempted Solutions

  • Setting the field to required and removing the required flag from the elements that are not needed. The asterixes disappear but the values are still treated as required.
  • Setting the field to be Not Required and adding the required flag to the country field. Has no effect.
  • As above and add a new process handler to run after addressfield_process_format_form that sets the country field back to being required. No asterix. Regardless of whether the country is filled the form fails validation - no error message is displayed.
  • Removing 'address' from the handlers array. No effect.
  • Removing the process handler from the element. Lose the widget completely

.

Is there a way of doing this without hacking the module?! There definitely should be. At this point it would have been quicker to right a new custom field widget.

Comments

pramodganore’s picture

Had a similar requirement: Note you can also use unset in place of for required false.

function custom_misc_form_alter(&$form, &$form_state, $form_id) {
switch ($form_id) {

case 'user_register_form':
case 'user_profile_form':

$country = $form['field_user_profile_address']['und'][0]['#address']['country']);
$sanctioned = (in_array($country, array('CA', 'MX', 'US', 'AS', 'FM', 'GU', 'MP', 'PR', 'PW', 'MH', 'VI')))?TRUE:FALSE;

if($sanctioned) {
$form['field_user_profile_address']['und'][0]['street_block']['thoroughfare']['#required'] = TRUE;
$form['field_user_profile_address']['und'][0]['locality_block']['postal_code']['#required'] = TRUE;
$form['field_user_profile_address']['und'][0]['locality_block']['locality']['#required'] = TRUE;
$form['field_user_profile_address']['und'][0]['locality_block']['administrative_area']['#required'] = TRUE;
}
else {
$form['field_user_profile_address']['und'][0]['street_block']['thoroughfare']['#required'] = FALSE;
$form['field_user_profile_address']['und'][0]['locality_block']['postal_code']['#required'] = FALSE;
$form['field_user_profile_address']['und'][0]['locality_block']['locality']['#required'] = FALSE;
$form['field_user_profile_address']['und'][0]['locality_block']['administrative_area']['#required'] = FALSE;
}
break;
}

Jquery :
// Country based display of address fields
if($.inArray(country, country_list) != -1) {
$('.street-block').show();
$('.locality-block').show();
}
else{
$('.street-block').hide();
$('.locality-block').hide();
}

ronaldmulero’s picture

Had a similar requirement as well.
I only needed the "State" field to be required, so I set the entire Address Field as required, then used the Context Form Alteration module to set the locality, thoroughfare, and postal_code as NOT required. See rows 3-5 of the first image at https://www.drupal.org/node/2333155.
In my case:
FORM ID: user_profile_form
PARENTS: profile_main, field_org_address, und, 0, locality_block, locality // (or thoroughfare or postal_code)
ATTRIBUTE: #required
VALUE: 0

As a bonus, additional adjustments to the Address Field can be made using the UI instead of in code.
e.g.

  • Rename the State field label.
  • Unset select list options (using the patch provided on the issue page)
Nchase’s picture

I suggest switching to locations https://www.drupal.org/project/location
you can granulary set the required fields within the address fields - This makes it possible to only set the country as required.

bojanz’s picture

Title: Making *only* the country required is very very difficulty » How to make only the country required
Category: Bug report » Support request
Priority: Major » Normal
Status: Active » Fixed

This worked for me:

/**
 * Implements hook_field_widget_form_alter().
 */
function mymodule_field_widget_form_alter(&$element, &$form_state, $context) {
  if ($context['field']['type'] == 'addressfield') {
    $element['name_block']['name_line']['#required'] = FALSE;
    $element['street_block']['thoroughfare']['#required'] = FALSE;
    $element['locality_block']['dependent_locality']['#required'] = FALSE;
    $element['locality_block']['locality']['#required'] = FALSE;
    $element['locality_block']['administrative_area']['#required'] = FALSE;
    $element['locality_block']['postal_code']['#required'] = FALSE;
  }
}

Also, #2302281: Plugins to hide street address or postal code fields. might provide an easier way to skip unneeded parts of the addressfield.

jsibley’s picture

Has this changed in the past few months? I thought that users had been able to input just a postal code, but am now seeing address1, locality, and postal code as required. Is this due to a module update, or am I just mistaken about previous behavior?

Thanks.

bojanz’s picture

address1 was always required, nothing changed there.
addressfield rc1 now knows which country-specific fields are required for each country, so it can be more precise (requiring the locality where mandated by postal rules, for example).

jsibley’s picture

Thank you for such a quick response.

I thought that addressfield was the path for the future, but is it recommended to use location instead, if one is not always collecting full postal addresses for each location?

Thanks

bojanz’s picture

I'm not familiar with location so I can't say.
You can use addressfield for an "incomplete address" use case, but you need to use an alter like the one in #4 to get around our safeguards.

jsibley’s picture

I realize that this question might suggest that I shouldn't be using #4, but what do I do with that code? Do I need to make a module out of it or does it go somewhere else?

Thanks.

bojanz’s picture

Yes, that goes in a module.

jsibley’s picture

Creating a module, changing "mymodule" to the name of the module, and pasting in the code from #4 did the trick for me.

For those new to creating modules (me, for example), it just took a simple .info file and the code from #4 in a .module file.

But isn't it considered best practice not to end with ?>

I don't know much about this, but I think I have read that somewhere.

bunthorne’s picture

Oh, my. This new requirement for country-specific address fields has completely destroyed my use case for this module. I was using it to locate places (venues) and organizations. Some organizations I only care about tracking to the city level; venues I usually track to the street level so that people can map to it if they want. But I have no reason to require postal code for anything!

I believe that by establishing rules for country-specific postal address requirements you have now narrowed the use case for this module enormously.

(As for Location, I was trying to use it 2 years ago and abandoned it in favor of Address Field because addressfield was keeping up to date and Location wasn't. It was still just a port of D6 if I recall correctly.)

Please re-consider the decision to make individual elements required based on country-specific address formats. This is not just for Commerce!

bojanz’s picture

@bunthorne
I hear you. Let's discuss it in the issue you created #2396975: Add an option for allowing incomplete data to be saved.

Also, please keep in mind that addressfield ships with a plugin that allows you to disable the postal code field. That would probably resolve your problem right now?

johnhanley’s picture

I have a special use-case where the addressfield is not required upon initial node creation (will be populated subsequently programmatically) and kudos to Bojanz for sharing this snippet.

jay.lee.bio’s picture

FYI, #4 is no longer required: https://www.drupal.org/node/2396975, #17

Status: Fixed » Closed (fixed)

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