Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Resolution
Added on latest development version.
Remaining tasks
Only tests at this stage.
User interface changes
Provides a new countries selection widget that allows users to filter by continent before selecting the country.
API changes
This patch has added a new widget that handles this. The other widgets still sit on top of the options list fields.
Original report by pcambra
I needed a continent field widget for this module so as that you select a continent and get a country list filtered by contintent. In the end it's "just" a form widget and doesn't store anything additional.
Patch attached with some awesome #ajax magic ;)
Comments
Comment #1
Alan D. CreditAttribution: Alan D. commentedNice. I like. This is a huge UI improvement in a 250 element select list. :)
A few things:
1) Make sure that you use t() on all strings.
+ '#title' => 'Select a country',
+ '#title' => t('Select a country'),
2) I do not think that the #description is needed on the iso2 sub-element and just "Country" rather than "Select a country". On a multi-value field, both become very repetitive.
3) A bit of internal structure could be done to help themers to condense this. Maybe a wrapper DIV with a clearfix class. That should be enough to easily float the sub-widgets inline if someone so desires.
If you are really keen, a custom theme callback could be warranted. Looking at the results, I want to move the Continent and Country labels into #descriptions rather than #titles, but this is my preferred style for multi-component fields, others dislike this.
4) The array_intersect_key logic should be moved into the widget form logic, otherwise there is the danger of interfering with other fields (ie: updating the drupal_static() result).
Un-related: This will expose the following "@todo I18n for user defined overrides." for continents. This is a separate issue though. @webflo any thoughts on this?
Comment #2
pcambraOk, fixed #1 and #2
About #3, never been a huge fan of placing too much theme inside modules, added a clearfix for continents, but I don't thing that much more fancyness is required :)
I introduced #4 as a way to get continents filtered (there's no way to do that now) but it will probably make sense outside this patch and I moved the intersect to the widget.
Let's try again, thanks for the review :)
Comment #3
Alan D. CreditAttribution: Alan D. commentedThe patch didn't apply, so I'll try again tomorrow. I need to run through single / multiple entities and also the default value form field (post setting the widget).
BTW, I did mean wrapping both the continent and iso2 elements within the same DIV. I can not remember if you can just append to the base $element or not. Maybe:
Comment #4
pcambraAlso found a problem with intersect, I'm attaching a new one
Comment #5
pcambraAnd here it is, with a container wrapper, I hadn't any issues applying the patch btw.
Comment #6
Alan D. CreditAttribution: Alan D. commentedI found issues with the instance default value form. This gets regenerated a couple of times per submission, so the unique ID never seemed to match the settings. It works once, then fails. I think that it is fairly safe to create our own via the parameters passed in.
I've added a number of other slight modifications.
Comment #7
Alan D. CreditAttribution: Alan D. commentedAnother minor restructure.
Comment #8
pcambraI don't know why you changed the widget callback, I think it's nicer to do it as in the first version
Comment #9
Alan D. CreditAttribution: Alan D. commentedYou can not assume that the field form is in this structure (ie: because of Profile2 and Field Collections);
Does this seem cleaner? (untested)
Comment #10
pcambraOk, included #9 and also had to remove the container element as it is breaking the visible condition for the country. Replaced it for a simple prefix thing.
Comment #11
Alan D. CreditAttribution: Alan D. commentedI think that the "breaking the visible condition" was me overlooking the role of the JQuery selector. Reverting the empty value from NULL to 'none' should fix this.
ie:
Starting to focus on the minor details, reselecting '-- None --' does not reset the visibility of the country select loaded by Ajax. Any ideas?
Comment #12
Alan D. CreditAttribution: Alan D. commentedBut it is probably ready to go without the worrying too much about "reselecting '-- None --' does not reset the visibility". As per #7 with #empty_value bug that I introduced fixed. I'll re-roll in about 4 to 5 hours.
Comment #13
pcambraOk, let's finish this thing for once!
I've merged the changes starting from #7 but had to make some changes as the widget wasn't working properly yet. Prior to this patch, the widget worked just the first time, if you changed the continent, the countries weren't refreshed, that's because of the use of drupal_html_id, that is not really fitting us, you can see the reason in views_ui_add_ajax_trigger (http://api.drupal.org/api/views/includes!admin.inc/function/views_ui_add...)
I also needed to force that the country widget is not shown when there's no country present.
Hope this can get committed finally!
Let me know what you think
Comment #14
spouilly CreditAttribution: spouilly commentedHi there,
I am evaluating the possibility to use your continent widget, and it kind of conflict with the CAPTCHA module.
I added a country field on the user profile (core profile), with the continent widget. I am using the captcha module to prevent bots from registering on my site, and the captcha module come with some kind of protection against session reuse. When trying to register a new user on my site with the continent widget, after selecting the continent, and before selecting the country itself, the captcha module display an alert: "CAPTCHA session reuse attack detected".
I don't know whether all ajax requests on the user registration form would generate such error message.
Cheers,
Sylvain
ps: using dev version with the continent patch of the country module, and the latest stable version of catcha.
Comment #15
Alan D. CreditAttribution: Alan D. commentedYes, it is an issue with the CAPTCHA module itself, see #918856: CAPTCHA Session Reuse message on webforms .
Comment #16
Alan D. CreditAttribution: Alan D. commentedCommitted. Great work.
Some things that I found and fixed in testing.
1) Unsetting the iso2 element in _ajax_countries_continent_widget_callback() blocked all AJAX other submissions by the element. This is probably a bug in core, but I worked around by adding a hidden div wrapper. I updated the countries element to optionally hide if there are 0 options or 1 option of type #empty_value.
2) I got a PDO exception when saving a country value of type 'none'. I changed this to just ''. The JScript tests the continent filter value for the show / hide toggle.
You can see the diff here: http://drupalcode.org/project/countries.git/commitdiff/77dfd39?hp=f3f1f8...
Comment #17
pcambraAmazing, thanks for doing such a follow up on this :)
Comment #18
Alan D. CreditAttribution: Alan D. commentedMy pleasure, it is a very useful addition to the module :)
Comment #20
llorberb CreditAttribution: llorberb commentedthis patch is causing a break. is this just on my machine? any idea what could be causing the issue.
Comment #21
pcambraYou should not apply this patch to the latest dev, it's already there!
This was committed 20 days ago as Alan mentions in comment #16.
Comment #22
Alan D. CreditAttribution: Alan D. commented@pcambra
An issue was reported with this in #1620276: Widget "countries by continent" issues due to AJAX #limit_validation_errors and nested forms (Field Collections, Profile2), I'd love a second pair of eyes on the patch before committing this.
It is in relation to the widget simply breaking when used in Profile2 profiles. I managed to replicate this using Field Collections, and once replicated, easily fixed the error on my installation.
Comment #23
Belibaste CreditAttribution: Belibaste commentedHi, Thanks for this awesome piece of work.
Any hints on using it in FAPI style created form ?
Comment #23.0
Belibaste CreditAttribution: Belibaste commentedClear resolution message
Comment #24
vipul.jadvani CreditAttribution: vipul.jadvani commented13: 1459850-countries-add_continent_widget-13.patch queued for re-testing.
Comment #26
Alan D. CreditAttribution: Alan D. commented@vipul.jadvani
This is already in the dev version if not the latest tagged release ;)