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
Comment #1
pramodganore CreditAttribution: pramodganore commentedHad 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();
}
Comment #2
ronaldmulero CreditAttribution: ronaldmulero commentedHad 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.
Comment #3
Nchase CreditAttribution: Nchase commentedI 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.
Comment #4
bojanz CreditAttribution: bojanz commentedThis worked for me:
Also, #2302281: Plugins to hide street address or postal code fields. might provide an easier way to skip unneeded parts of the addressfield.
Comment #5
jsibley CreditAttribution: jsibley commentedHas 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.
Comment #6
bojanz CreditAttribution: bojanz commentedaddress1 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).
Comment #7
jsibley CreditAttribution: jsibley commentedThank 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
Comment #8
bojanz CreditAttribution: bojanz commentedI'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.
Comment #9
jsibley CreditAttribution: jsibley commentedI 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.
Comment #10
bojanz CreditAttribution: bojanz commentedYes, that goes in a module.
Comment #11
jsibley CreditAttribution: jsibley commentedCreating 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.
Comment #12
bunthorne CreditAttribution: bunthorne commentedOh, 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!
Comment #13
bojanz CreditAttribution: bojanz commented@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?
Comment #14
johnhanley CreditAttribution: johnhanley commentedI 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.
Comment #15
jay.lee.bio CreditAttribution: jay.lee.bio commentedFYI, #4 is no longer required: https://www.drupal.org/node/2396975, #17