We needed the ability to move certain countries to the top of the country pulldown list, which is normally sorted alphabetically by country name. The attached patch to HEAD adds a new 'Top Countries' field to the admin settings page, which lets the user select one or more countries to be moved to the top of the countries pulldown. If set, the _addresses_country_get() function reorders the countries array accordingly.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

AlexisWilke’s picture

Status: Active » Needs review

This looks good to me. 8-)

I don't have the time to test now, but that's a good option. I had people complaining. We may also want to add a delimited between the top and other countries.

Did you try to not eliminate the top countries from the rest of the list? Does that result in duplication that the browser does not like?

Thank you.
Alexis

ISPTraderChris’s picture

I've tested this patch and it is working successfully on my system. I think it might be nice, if we're going to add this functionality, to allow the user to specify the sort order for the 'top' countries. As it stands, everything in the 'top' list is sorted alphabetically.

AlexisWilke’s picture

Status: Needs review » Fixed

Checked in. I made the top countries a "separate list" so the countries appear at the right place too.

Yes. It is in alphabetical order which is not the best but works for now, I think. Especially because you should not have 20 top countries and yes that means the US appears after Canada, which is a shame. 8-)

Thank you.
Alexis

rbl’s picture

The only problem is that when selected these countries do not show the province menu, I mean, selecting US in the "regular" list makes the states/provinces menu appear and selecting it in the top countries list doesn't.

Ricardo

AlexisWilke’s picture

Status: Fixed » Active

rbl,

Good point! I did not pay attention to that. The top countries have 'top_' prepended to them. I need to remove that when checking for the province.

Thank you.
Alexis

AlexisWilke’s picture

Status: Active » Fixed

Okay, this is fixed in -dev version (available in next 12h).

Thank you.
Alexis

rbl’s picture

Hi Alexis!
Thanks! It's working now but there's a new problem, state/provinces are not recognized, I keep getting this error:
"Could not find LI as a province from . Try to use the province abbreviation or number."

Again, just to make it clear:
- choosing a country from the regular list and then a state/province works fine;
- choosing a country from the top countries list and then a state/province outputs that error.

Ricardo

AlexisWilke’s picture

Category: feature » bug
Status: Fixed » Active

Okay, I added a few more fixes in there... The validation function cannot be used to fix the country name. It has to be fixed everywhere instead.

So I added a few more.

Let me know if you still experience problems.

Thank you.
Alexis

rbl’s picture

There's something definitely wrong... Every node I edit defaults to Tonga now.

Ricardo

AlexisWilke’s picture

Hi rbl,

I put a fix in, but I do not think it will make a difference. The new 6.x-1.x will be available within 12h. Note that, obviously, not using the top countries will fix the problem. 8-}

This is in the CCK which does not work for me at this time, so it's hard to debug/fix anything. ISPTraderChris has been working on adding dynamic labels, description, etc. and maybe he can help on this one... If my fix doesn't work, send him an email. 8-)

Thank you.
Alexis

mweixel’s picture

Ricardo, same thing was happening to me. _addresses_validate_top_countries in addresses.settings.inc seems to be using the wrong array subelements in $form_state to perform validation. As a result, validation doesn't run properly and the module just takes the first two characters of the country code. Because the "top" countries all have "top_" prepended to their country codes (i.e. "top_us"), the form winds up passing "to" for anything selected from the "top" countries. Guess what country has "to" as its code? You got it: Tonga.

Fortunately, $element is passed referenced in _addresses_validate_top_countries, so I hacked together the following:

  $add_field_nm = $element['#parents'][0];
  if ($form_state['values'][$add_field_nm]['0']['country'] == 'separator') {

    // the user selected the separator!
    $form_state['values'][$add_field_nm]['0']['country'] = '';
  }
  elseif (substr($form_state['values'][$add_field_nm]['0']['country'], 0, 4) == 'top_') {
    $form_state['values'][$add_field_nm]['0']['country'] = substr($form_state['values'][$add_field_nm]['0']['country'], 4);
  }
}

That seems to be doing the trick.

AlexisWilke’s picture

Okay, I checked the fix proposed by mweixel. Although you that function is used by the Users address book too so we want to check for 'addresses' if the $element['#parents'][0] value is not defined. At least, I think that's the case and I set $add_field_nm to 'addresses' in that case.

Let me know whether that solves the problem.

Thank you.
Alexis

AlexisWilke’s picture

Status: Active » Fixed

Okay, the CCK, validations, auto-complete should all be fixed. I put that in 6.x-1.10! Feel free to re-open if you still experience problems with Top Countries.

Thank you.
Alexis

Shawn DeArmond’s picture

Status: Fixed » Needs work

Still getting "Tonga" when selecting any of the "top countries" using 6.x-1.10

Shawn DeArmond’s picture

Status: Needs work » Needs review
FileSize
1.19 KB

Here's a patch against HEAD that fixes it.

AlexisWilke’s picture

Hi Shawn,

Is it really '0' and not 0?

Also, will it always be 0 or could it be 1, 2, 3... as well? (in case of multiple CCK fields in the same node type.)

Thank you.
Alexis

Shawn DeArmond’s picture

You're right, [0] would probably work. I was just copy/pasting from #11.

opi’s picture

Hi,

Just discover all of my new user lives in Tonga !!

#15 works fine for me

opi

AlexisWilke’s picture

sdsheridan’s picture

There is an issue with function _addresses_validate_top_countries when address fields are embedded in things like flexifields or multigroups, where the zeroth element of the #parents array does not in fact have a [0]['country'] array element, but in fact that element is a few layers down. The code below fixes that problem. $field becomes a reference to the correct location within $form_state that needs to be altered, appropriately traversing the variable depth to where $element's data is actually held.

function _addresses_validate_top_countries($element, &$form_state) {

  if (isset($element['#parents'][0])) {
    
    $field =& $form_state['values'];
    foreach ( $element['#parents'] as $value ) {
      $field =& $field[$value];
    }
    
//    $field_name = $element['#parents'][0];
  }
  else {
//    $field_name = 'addresses';
    $field =& $form_state['values']['addresses'][0]['country'];
  }

  if ($field == 'separator') {
    // the user selected the separator!
    $field = '';
  }
  elseif (substr($field, 0, 4) == 'top_') {
    $field = substr($field, 4);
  }
}
adamus_maximus’s picture

Prepending the country keys with "top_" caused issues for geocode_widget.
See the following:

http://drupal.org/node/961408

butler360’s picture

Patch in #15 works for me. No more Tongans.

AlexisWilke’s picture

Status: Needs review » Needs work

There is a first fix checked in using #15 but without losing the old behavior which is necessary in the user forms and address book.

So what we'll need next is to support #20 properly. However, the way it is currently written, #20 does not take the user forms and address book, only the CCK fields.

Thank you.
Alexis Wilke

Lendude’s picture

I have the 'Tonga' problem too, but only when using multiple address. The first address was fine, but the second one (when selecting a top country), would always be set to Tonga.
The problem is what was referenced in #16, the 0 is not always 0 but should be the delta of the current address being validated. Since $element does not seem to contain this delta, there needs to be another way to find this. The only thing I could find was $element['#parents'][1]. So the _addresses_validate_top_countries function would be something like this:

function _addresses_validate_top_countries($element, &$form_state) {
  $delta = 0;	//account for multiple addresses
  if (isset($element['#parents'][0])) {
    $field_name = $element['#parents'][0];
    if (isset($element['#parents'][1]) && is_numeric($element['#parents'][1])) $delta = $element['#parents'][1];  //set $delta to the current address being validated
  }
  else {
    $field_name = 'addresses';
  }
  if (isset($form_state['values'][$field_name][$delta]['country']) && $form_state['values'][$field_name][$delta]['country'] == 'separator') {
    // the user selected the separator!
    $form_state['values'][$field_name]['0']['country'] = '';
  }
  elseif ($form_state['values'][$field_name]['country'] == 'separator') {
    // the user selected the separator!
    $form_state['values'][$field_name]['country'] = '';
  }
  elseif (isset($form_state['values'][$field_name][$delta]['country']) && substr($form_state['values'][$field_name][$delta]['country'], 0, 4) == 'top_') {
    $form_state['values'][$field_name][$delta]['country'] = substr($form_state['values'][$field_name][$delta]['country'], 4);
  }
  elseif (substr($form_state['values'][$field_name]['country'], 0, 4) == 'top_') {
    $form_state['values'][$field_name]['country'] = substr($form_state['values'][$field_name]['country'], 4);
  }
  $counter++;
}

This fixed the problem for me, but I have no idea if this is a universal solution (In other CCK setups $element['#parents'][1] might or might not reference the correct delta).

Len

AlexisWilke’s picture

Status: Needs work » Active

Lendude,

This looks good! I put your patch in 6.x-1.x-dev.

Note that in your code sample you missed one $delta:

  $form_state['values'][$field_name]['0']['country'] = '';

I suppose that was just an oversight.

Thank you for posting your solution here!
Alexis Wilke

Lendude’s picture

Oh yeah, I missed that one, thanks.

Just to be extra clear, I haven't tested this with any other setup then my own, Address field with unlimited number, 1 deep in a fieldgroup. I have no idea how this holds up in a different situation. My knowledge of CCK just isn't good enough to oversee this.

Len

AlexisWilke’s picture

It's already better than what I came up with. And it doesn't change the behavior when the parent doesn't define an index so I think we're good. 8-)

Thank you.
Alexis