We have a content type with the address field. The address entry is optional. When a user decides not to provide an address, the default country is saved to the node. It would be desirable to provide a null value by default. Would it be possible to provide an inline button that would add an address field to the node, rather than having the country and address fields displayed by default?
Proposed resolution
This issue contains a patch using hook_field_presave().
The preferred way is to use hook_field_is_empty(), to determine if an empty/default value should be stored in the database.
However, hook_field_is_empty() does not contain info about the field instance settings. See #1489484: Add $instance parameter to hook_field_is_empty().
| Comment | File | Size | Author |
|---|---|---|---|
| #48 | addressfield_required_fields_for_non_empty_address.jpg | 53.2 KB | Naomi79 |
| #37 | addressfield-country_value_check-7411314-37.patch | 1.53 KB | rudiedirkx |
Comments
Comment #1
brylie commentedI am working on a directory of organizations. Most of the organizations have addresses, or a country of origin. However, some organizations do not provide such information.
I would like to omit the address information on some nodes. Even with the address field being optional, there is no way to omit the country field. I have not selected a default country, so Afghanistan is the automatic selection.
Please provide the option (default or otherwise) to omit a country field.
Comment #2
brylie commentedThis problem becomes more complicated when allowing multiple addresses to be entered on a node. By default, the address field is rendered with two automatic address field entry widgets featuring the default address settings. Now, every node that I enter has an additional address, with the default address settings, even though there may be only one primary address.
E.g. I am making a local directory for Olympia, WA. I have set the default address form parameters to be Olympia, Washington, USA. I have also enabled multiple addresses to be used, for organizations with multiple locations. When I enter a new location, it has multiple addresses, one primary mailing address and another generic address "Olympia, Washington, USA."
Comment #3
brylie commentedComment #4
cristian100Subscribing, this is very annoying, each time a user edits a node, a new entry for the address is populated just with the default country.
Comment #5
sheldonkreger commentedEven if the other address fields are required, we should be able control the requirement of the country field.
Comment #6
pounardThis is more than annoying, this is a real bug.
Comment #7
pounardHere is an ugly patch working for my use case (read and use it wisely before using it).
Comment #8
sheldonkreger commented#7 just cleans up existing empty address fields, it doesn't prevent any more from being created, correct?
Comment #9
pounardThe presave hook implementation actually avoid the field_(base|revision)_* rows to be created too.
Comment #10
johnvFYI, the following comment gives an alternative implementation: #968112-111: Allow addressfield to be optional
but current patch with hook_field_presave() is better then hook_node_presave() or hook_entity_presave().
Comment #11
johnvAttached patch is reworked from #7.
It still uses hook_field_presave(), which now checks against the default value from the field instance.
There was no need anymore to change hook_field_is_empty().
FYI, see also #1489484: Add $instance parameter to hook_field_is_empty() , which is prerequisite for doing this properly in hook_field_is_empty().
Comment #12
johnv#11 did a weird thing when the default field instance value contains not only Country. Correcting that.
Comment #13
sheldonkreger commentedPatch in #12 allows me to save nodes with no address info other than the country, when the field settings are configured correctly (address field is optional). It still sets up a DB entry with null values, other than the country field. Whether that's a good thing or bad, I'm not sure, but it was mentioned in #6.
Comment #14
giuvax commentedI know this is really ugly as workaround but I gave up finding a solution with empty saved profile because of mandatory country field. I'm tired of searching solutions.
So I decided to create a rule, and here it is:
I put two conditions just to be sure.
Comment #15
mrfelton commented#12 works well for me too, bar the empty database entries. I'm setting this back to needs work because of the issue with saving blank data.
Comment #16
johnvFYI: Patch #12 contains a correction for element_key.
That part may be a duplicate of #1928166: element key didn't use parents element and override default item with field collection
Comment #17
johnvAttached patch should deal with #6, too.
Comment #18
mrfelton commentedSame patch as #17 but without the extra whitespace
Comment #19
rudiedirkx commentedComparing an item to the instance defaults is bad logic. It's bad for two reasons:
I changed it to compare field names of non-empty fields, to fix bug # 2, but that's also faulty, but it still removes items with the same value as the default value.
Time allowing I'll create a good patch today. Maybe tomorrow.
Comment #20
johnv@rudiedirkx, I don't understand your point. This issue is exactly to resolve the 2 points you mention:
- Addressfield comes with a prefilled, required subfield 'country'. Submitting this should NOT generate a db-entry
- changing data from the default implies that the user has thought about the new, better input, and SHOULD result in a db-entry.
Indeed, this behaviour might be different from a 'normal' field, but it all stems from the Addressfield's premiss, that the country is prefilled and required.
Comment #21
rudiedirkx commented@johnv Don't use the default value to check for the Country field. Only Country is special. You can have defaults for the others. If have a City in default and submit, it should save that. If you'd remove the city, it shouldn't submit that, because only the Country is (pre)filled and the rest is empty. The last patch checked for difference, so if you have a default City (and Country, hidden) and you remove that City, it would save the empty (except for Country) item.
So the fix should check:
if ((only the country is non-empty AND the 'hide country' option is ON) OR (everything is empty)): don't save
The default value is irrelevant, because the default value includes all other fields too (2 streets, postal, city).
Right?
Comment #22
johnv@rudiedirkx,
I don't agree with: If have a City in default and submit, it should save that.
I agree with: If you'd remove the city, it shouldn't submit that,
Perhaps it changes on the use case.
More opinions are welcome!
Comment #23
manuel garcia commentedThis is indeed a tough one to figure out... let me try to analize the problem see if we can organize our thoughts.
The default country is used mainly for when the field is only going to get addresses from a certain country, so we set a default value to save time and clicks for the content creators. I believe this is pretty much the use case.
The problem comes when the address field is optional. This means that the content creator does not want to want to HAVE to enter an address in order to save the content. Currently this saves an emtpy value for everything except for the country, which is not what the content creators expect/want.
I suppose the same can be said for the rest of address fields.
The problem comes from address field being really a "multi-fields-field", and what I think we need is a set of configuration options (per field in address filed?):
"Set a default value for this field" and then two sub-options:
-- "If the others are empty, don't save the field's data if it is on default value"
-- "Save the default value regardless of the rest of data entered."
To me this seems a bit messy perhaps, but this is the situation we have, any other ideas?
Comment #24
mxtWhat Manuel Garcia proposes in #23 make sense to me: +1 for this solution.
Comment #25
giuvax commentedI agree with Manuel Garcia's #23.
Comment #26
rudiedirkx commented#23 seems complex... Why not handle defaults as all other Drupal fields do? If you don't change the default and submit (and the item isn't empty), it's saved. The only special thing in this case is the country field. If all other fields are optional (and only the country relevant), the 'address-hide-country' option will never be ON, so we have to check that option.
This function does that:
It allows an item with JUST the country filled IF the 'address-hide-country' option is OFF. (Which makes total sense to me, otherwise you'd submit a completely empty form and expect it to save, which is weird IMO.)
I don't have time to roll a patch against dev or stable. Try it out and roll it.
Comment #27
pounardThe problem is user experience, if a user does not care about the address, he wont empty it manually, makes no sense to ask a user to do that. IMO defaults should never be saved for an address if the user don't want to input it. I think the algorithm should be: if no fields have been changed, nothing should be saved, if one or more values have been changed, everything should be saved. From the user point of view, I think it's the expected behavior.
Comment #28
phiscock commentedBut if it doesn't save if nothing has changed then in a scenario where the correct entry is the default country it wouldn't save when the user could realistically expect that it would.
From my perspective the logical answer is to be able to offer the option of the country field being empty or "none" country option that saves as empty. That offers the most flexibility to both administrator and user to choose what result they get from the form.
Comment #29
rooby commentedThere are legitimate use cases where you would want the default value to always save unless manually emptied, and there are use cases where you would not want that.
Comment #30
pounardThen this can be an instance level setting, or widget setting? It's possible implement multiple behaviors, but at least these:
+ One which cares only about required fields (country) and does not save if this specific value is default and other are empty (which is actually #23 if I understood it well)
+ One which cares about all default values, and does not save when all values are default
+ One other which keep the default stupid behavior
+ Any other suggestion?
And leave the site builder choose whatever behavior he wants.
Comment #31
manuel garcia commentedWe cannot save the country alone, this results in problems later on when trying to build maps out of this content, etc. Unless that's the only thing you want to record in your field I suppose.
This problem is indeed complex, perhaps we should make a list of usecases / configuration posibilities and take it from there? @rudiedirkx I'm not sure I can follow what you said... sorry! :S
Coming to think about it I believe the problem arises from the fact that we are forced to select a default country even if the field is set to optional. So perhaps we should tackle that? If we could select no country as default when the field is optional, we would not be saving address fields with just a country in it....
Comment #32
rudiedirkx commentedAll the edge-case configuration is unnecessary IMO. If the site builder really wants something special, they can alter and validate stuff. They can even add a field_presave. Addressfield should go with ONE method (a strict method IMO, so no empty or almost empty stuff is stored) and leave specificities up to the site builder. You can assume they know a little bit of Drupal and PHP to 'fix' that. You can never get ALL use cases in configuration, so you shouldn't try any.
@Manuel Garcia You can save an address with just a country. And you should. A country might be all that's relevant. If that's the case, the 'address-hide-country' will be OFF (otherwise the form would be EMPTY), so my solution would work.
You should try my solution (sorry, no patch today) and try every use case (including defaults) you can think of. If it breaks, let us know, so we can specify. No point in mapping out ALL use cases. It's impossible to program and impossible to understand (for site builders).
Comment #33
deanflory commentedYeah, I just need my addressfields to stop adding additional ones each time the entity is edited and saved with the required default country since there is no "none" in the default form setup. Just add a - None - in the default form just like in the actual entity form. I've read all these alternate uses/configuration comments in multiple issues and can't fathom why it's so difficult to have this field act like pretty much every other field in it's default state, then just add optional checkboxes with other settings for those edge cases. Why the discussion? I know that sounds rude and/or novice but I'm confused why a default state across the board shouldn't apply to this field also unless it's manually set to be required as a form field. #overthinkingit
Comment #34
rudiedirkx commented@deanflory Because you must be able to set a non-empty default and since there's an option to hide the non-empty country field, that should sometimes be ignored. Your use case might be simple, but getting them all is apparently the goal.
Comment #35
deanflory commentedYou mention "must be able to set a non-empty default" but isn't that an "able" and not a "have to"? Did a miss the point why a country is required, default or selected?
Isn't the "option to hide the non-empty country field" for sites based in one country and not for providing a default "- None -" so defaults don't continually add additional addresses?
I apologize if I'm completely missing the sticking point here and wasting everyone's time trying to wrap my head around this.
Comment #36
rudiedirkx commentedI don't understand. There's no "have to" in "must be able to set a non-empty default". If you mean the "must be", it absolutely is must be. The only issue IMO is to check the hidden Country field. Solution (not patch) in #26 does that.
Alright, I'll create the patch.
Comment #37
rudiedirkx commentedAttached patch does exactly #26. It's rolled against stable, so might not apply to dev? (Function added to the very end of the module file.)
I don't know how to enable the country to have an empty default value (for if you can't use the 'address-hide-country' option). The ctools plugins are very weird, without values and field instance config to check.
What it should do is enable you to set the default (in the field instance config) to an empty country and then create all new address widget with an empty country. I've no idea how. Adding
#empty_optionto$format['country']inaddressfield_format_address_generate()isn't enough.Attached patch is perfect for if you have only 1 country, but not if you allow several, I understand now. Sorry.
Comment #38
deanflory commentedHere are the problems I'm seeing now:
1) Country is still required in the default field settings, there is no "- None -" option which would allow the field to be completely optional and not save an address if no country or other address fields are selected/filled-in. In all these comments people keep saying "country is required" but I haven't seen one comment that steps out of that small box and says. Someone asks "why is country required" and someone immediately answers "because Drupal already expects it to have a value". Other fields don't require a default setting that has actual saved data like a specific country, they can be empty (which may be a saved value but that's what I'm getting at here). If I set up a text field that isn't set to be required, and the user doesn't fill in anything, that field doesn't have a presentable value, can thus be set to be hidden if it has no value and then not show up at all, field data or label.
2) The edit entity form widget does allow a "- None -" now (can't remember if this is with a patch or not, thinking it was applied to the latest dev). While this helps, it requires every user on every submission that has an addressfield to manually set it to "- None -" or else whatever the default country is, it will save it as such. So this dumps the problem on the end user which in turn, due to end user laziness or oversight, still makes the country required in the real world and thus adds a 1st and 2nd address entry since it always displays 2 sets of addressfield fields (multiple instances).
I'm unsure why it was set-up to allow "- None -" on one but not on the other, seems like the default field settings were overlooked as another instance of where "- None -" should have been applied as an option. Or maybe it doesn't show up for an existing field?
In case my use case clarifies my viewpoint: I have addressfields on most entities, allowing users to add a location to most anything. Not just one country, but anywhere, since they could post photos from vacation etc. outside of the origin country that connects the private users. So having 1 country and hiding that 1 country is not applicable or helpful in achieving an addressfield that doesn't save an address when saved or edited and saved. Also, don't like the 2nd field having to be there, totally unnecessary if there is an "Add another" button, but that's another issue that's still not resolved.
I've tried several of the patches and they're either outdated with current versions or they overlap and alter the same lines which makes a non-module-coder like me unable to make it all work. Does anyone have any advice? Some of these issues have been going on for 2.5 years and I haven't really seen much feedback from the module maintainers to let us know if something is in the works or not. All effort is appreciated but all these issues are puzzling to try and get it working properly.
Comment #39
groovedork commentedI, too, am flabbergasted that I have found 4 threads around this issue, starting all the way back in 2011.
To me just setting the default to "don't save to the database if the user hasn't changed anything" would be preferable to always saving the country, which it does now. While not perfect, it seems like a more sane default.
__Use cases__
I can conceive more use-cases where people would fill in a complete address, than use cases where just the country alone would be valuable.
Situations where just the country alone would be logical to save:
- What is your favourite holiday destination? at a travel website
- Which national branch is this employee a part of? at a multinational firm
Situations where the entire address would be logical to save:
- User details (CRM, etc)
- Event location
- Location-based services/mapping
I recognise there are cases where just the country alone is a valid input. But I think most use-cases wouldn't concider just the country data to constitute an address.
Comment #40
mbrakken commentedA minor clarification: "- None - " is not in the dev branch. It's from #968112: Allow addressfield to be optional.
Given that there are 3 or 4 issues that deal with aspects of this issue and that none in my mind fully satisfy requirement, I feel we should try to pull together different threads and assess how they can interact with each other.
Unless I am mistaken, the goals of the different issues are as follows:
This thread (#1844846: Make Addressfield optional, (even if country is required) ) deals with content being saved in the database even if fields are empty. This means, too, that if a user does not touch the addressfield, they are defaulted as living in Afghanistan, since that's the first country value in the dropdown.
#968112: Allow addressfield to be optional adds a country value of " - none - " to the top of the list. It has some admin UI issues, leading to site builder uncertainty about how to configure it. Also, it still registers the field as populated, so values get saved. This means if you're using https://drupal.org/project/location_taxonomize with Addressfield like I am, you end up with a series of "Unknown" values attached to an entity.
#1263316: Configurable non-empty value conditions allows admin to define which elements of addressfield need to be have data in order to be determined complete and saved to the database. I think this addresses one of @groovdork's issues in #1844846-39: Make Addressfield optional, (even if country is required) . However, it has a UI problem in that it still has Afghanistan as the lead value, as opposed to " - none - " or just empty. It does have a check to see if default value was changed, but this isn't ideal in my opinion. An end user has no reason to think that a field showing Afghanistan is actually empty, and in my current tests where I have set country and city as both required, if I don't touch the address field on the form it still kicks an error at me telling me either to also add a city or to clear the country. There is no way to clear the country without some type of null value or reset function. I should note, though, that I applied the patch manually and so need to verify my code. (I'm learning PHP, and find it useful to manually manually patch in order to see how others structure their logics.)
I think the fourth issue referenced by @groovedork in #1844846-39: Make Addressfield optional, (even if country is required) might be #984788: Add "Remove" button to clear out values in a multi-value address field widget, which would as the title says, add a "Remove" button to a multivalue addressfield, in order to prevent populating excess empty addresses, or to eliminate existing ones. I haven't really looked at it since multivalue addressfields is not my use case, but thought I should include it.
I'm sure I missed some things, and have probably misinterpreted others, but I think the conversations across different issues need to be brought together so we don't work at cross purposes.
The main issue behind all this, that addressfield has problems with the concept of empty, is pretty huge as many others have noted. I'm going to try and assemble across the different issues above, because getting this right so that forms process as expected and users aren't confused or stuck is a leading concern for me. Let me know if I completely missed something that needs to go into this.
Comment #41
artusamakIf someone wants to test it, this issue is solved when using #1263316: Configurable non-empty value conditions - #66 and #970048: Define and use addressfield as a form element type - #79
The only point left will be the removal but should be handled in #984788: Add "Remove" button to clear out values in a multi-value address field widget as mbrakken efficiently summarized it.
Comment #42
klonos@Artusamak: Thanx mate! Just a note to make your life easier. You can format direct links to issue comments like so: [#issue_id-comment_number]
It would make...
#1263316-66: Configurable non-empty value conditions: #1263316-66: Configurable non-empty value conditions#970048-79: Define and use addressfield as a form element type: #970048-79: Define and use addressfield as a form element typeTry it next time ;)
Comment #42.0
klonosAdded some data about the used hook.
Comment #43
johnvITMT, the current -dev version contains a hook_field_presave(), which we are also implementing in this issue.
So, we need to re-assess the patch.
Comment #44
jsibley commentedI am hoping that this is the best place to ask this question, as I am finding the multiple threads about optional addressfields somewhat confusing.
I believe that, if one is geocoding addressfield data, there needs to be a country. If true, then it makes sense for the country to be mandatory, even if the addressfield is optional.
If a user might have multiple addresses, the issue is made worse, as I believe that each time the user profile is saved, another address is saved and there is, as pointed out in other threads, no "remove" button yet for the additional fields.
So, for now, what is the best solution for multiple, optional addressfields with a mandatory country? I'm tempted to limit users to only one address until this gets straightened out, but that seems overly limiting for users that might have multiple addresses (I'm creating a user directory).
Are we at all close to a workable solution?
Comment #45
klonosRelated D8 core issue.
Comment #46
deanflory commentedThanks klonos for the related link, looks like this may be a while...
Comment #47
klonosI recently came across Field Suppress. I haven't actually used the module, so I don't know in what shape it is, but from its description:
I'm not sure if or how, but the
field_suppress_blankfield setting seems that might prove useful if we used it for our cause.PS: cross-posting this to the other related issues for those that don't follow here.
Comment #48
Naomi79 commentedThere is a patch here https://www.drupal.org/node/1263316#comment-8995979 that add new address field settings. Please see the screenshot attached.
Notes:
- Field Suppress module doesn't solve the issue because it does not apply to existing nodes.
- I tried to apply #37, #18, #12 with the patch manager module and got a fatal error "cannot redeclare function..." (back and front broken, if it happens to you: you just need to reinstall the address field module manually in sites/all/modules/addressfield to go back to normal).
Comment #49
bojanz commentedAddressfield has never been designed to be optional.
The "optional addressfield" issues have gathered over 200 comments with dozens of different approaches and use cases. Most wrong.
Therefore, it is not surprising that the issue has stayed unsolved for years.
I am going to close this issue as a duplicate of #968112: Allow addressfield to be optional, because that issue is the closest to a solution. I will post my proposal and patch there.
Comment #50
johnvThis is just to confirm that #49 is OK.
I am updating to version 1.0 and was using patch #17. Setting the default country to 'None' ( using the new functionality ) makes that no address field is stored when a country is not filled. If a default country is filled, the field is effectively required.
I do like the first feauture, do not care about the second feature.