I wanted to make a select field that listed the counties of the UK grouped in to regions. I used the 'Allowed values function' field within the select list settings to specify a custom function uk_county_list() to build the allowed values.

function uk_county_list() {
  return array(
    'North West' => array(
      'Cheshire' => 'Cheshire',
      'Cumbria' => 'Cumbria',
      'Greater Manchester' => 'Greater Manchester',
      'Isle of Man' => 'Isle of Man',
      'Lancashire' => 'Lancashire',
      'Merseyside' => 'Merseyside',
    ),
   ...

This produced the desired select field with optgroups:

<select class="form-select required" name="field_job_county[und]" id="edit-field-job-county-und">
  <optgroup label="North West">
    <option value="Cheshire">Cheshire</option>
    <option value="Cumbria">Cumbria</option>
    <option selected="selected" value="Greater Manchester">Greater Manchester</option>
    <option value="Isle of Man">Isle of Man</option>
    <option value="Lancashire">Lancashire</option>
    <option value="Merseyside">Merseyside</option>
  </optgroup>
  <optgroup label="North East">
    <option value="County Durham">County Durham</option>
    <option value="Northumberland">Northumberland</option>
    ...

However, when a user selects a county on the node edit/creation screen, they get an 'illegal value' error on that field every time, regardless of the value selected.

I believe the problem lies with the list_field_validate() module within list.module of the core field module. The list of allowed_values is returned as a two-dimensional array but this function seems to assume that the list is always flat and in the case of the a select list with optgroups, the validate always fails.

My hack was to flatten the $allowed_values array before validating but there may be a cleaner way of doing it:

function list_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
  $allowed_values = options_array_flatten(list_allowed_values($field)); // Flatten the array to accommodate optgroups
  foreach ($items as $delta => $item) {
    if (!empty($item['value'])) {
      if (!empty($allowed_values) && !isset($allowed_values[$item['value']])) {
        $errors[$field['field_name']][$langcode][$delta][] = array(
          'error' => 'list_illegal_value',
          'message' => t('%name: illegal value.', array('%name' => t($instance['label']))),
        );
      }
    }
  }
}
Files: 
CommentFileSizeAuthor
#33 1180992-33.patch3.88 KBravi.khetri
PASSED: [[SimpleTest]]: [PHP 5.4 MySQL] 92,285 pass(es). View
#29 1180992-optgroup-validation-29.patch3.89 KBjorgegc
PASSED: [[SimpleTest]]: [PHP 5.4 MySQL] 77,734 pass(es). View
#27 dropdown2.png109.53 KBprateek479
#25 1180992-optgroup-validation-24.patch3.89 KBsaki007ster
PASSED: [[SimpleTest]]: [MySQL] 63,145 pass(es). View
#24 1180992-optgroup-validation-24.patch643.74 KBsaki007ster
PASSED: [[SimpleTest]]: [MySQL] 63,136 pass(es). View
#19 1180992-optgroup-validation-19.patch2.78 KBcristiroma
FAILED: [[SimpleTest]]: [MySQL] 58,581 pass(es), 3 fail(s), and 0 exception(s). View
#19 interdiff-1180992-18-19.txt2.04 KBcristiroma
#18 1180992-optgroup-validation-18.patch1.35 KBcristiroma
FAILED: [[SimpleTest]]: [MySQL] 58,647 pass(es), 3 fail(s), and 0 exception(s). View
#15 1180992-optgroup-validation-15.patch1.45 KBToRum
PASSED: [[SimpleTest]]: [MySQL] 55,842 pass(es). View
#13 1180992-optgroup-validation-13.patch1.37 KBToRum
PASSED: [[SimpleTest]]: [MySQL] 55,922 pass(es). View
#10 1180992-optgroup-validation.patch844 bytesbleen
FAILED: [[SimpleTest]]: [MySQL] 55,639 pass(es), 37 fail(s), and 16 exception(s). View
#7 1180992-optgroup-validation-7.patch905 bytesToRum
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 1180992-optgroup-validation-7.patch. Unable to apply patch. See the log in the details link for more information. View
#1 1180992-optgroup-validation.patch838 bytesbleen
PASSED: [[SimpleTest]]: [MySQL] 33,808 pass(es). View

Comments

bleen’s picture

Version: 7.x-dev » 8.x-dev
Status: Active » Needs review
FileSize
838 bytes
PASSED: [[SimpleTest]]: [MySQL] 33,808 pass(es). View

I dont think there is anything hackey about your approach at all...

This bug should be fixed first (or concurrently) in d8. Here is a patch for d8 that uses your approach.

cweagans’s picture

Issue tags: +needs backport to D7
chimericdream’s picture

Assigned: Unassigned » chimericdream
chimericdream’s picture

Assigned: chimericdream » Unassigned

Sorry. Didn't mean to assign this to myself. Removing assignment.

Simon Georges’s picture

ToRum’s picture

Patch in #1 (https://drupal.org/files/1180992-optgroup-validation.patch) works fine for me (Drupal 7). Can it be added to a following release of Drupal 7?

ToRum’s picture

FileSize
905 bytes
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 1180992-optgroup-validation-7.patch. Unable to apply patch. See the log in the details link for more information. View

Update: patch #1 became obsolete as source code has changed in the meanwhile. The following updated patch works fine for me.

Status: Needs review » Needs work

The last submitted patch, 1180992-optgroup-validation-7.patch, failed testing.

ToRum’s picture

Update: patch in #7 is the backport for D7. That's why the test failed.

bleen’s picture

Status: Needs work » Needs review
FileSize
844 bytes
FAILED: [[SimpleTest]]: [MySQL] 55,639 pass(es), 37 fail(s), and 16 exception(s). View

ToRum, the D8 version needs to go in before the D7 version will be considered...

This is a re-roll for D8

bleen’s picture

...ToRum. The best thing you can do to keep the wheels moving so this can get into D7 would be to test out the patch in #10 on D8 and (assuming all is well) mark this issue as RTBC.

Status: Needs review » Needs work

The last submitted patch, 1180992-optgroup-validation.patch, failed testing.

ToRum’s picture

FileSize
1.37 KB
PASSED: [[SimpleTest]]: [MySQL] 55,922 pass(es). View

Patch #10 failed because options_array_flatten() does not exist and passed parameters of list_allowed_values() were wrong. New patch for D8 attached.

ToRum’s picture

Status: Needs work » Needs review
ToRum’s picture

FileSize
1.45 KB
PASSED: [[SimpleTest]]: [MySQL] 55,842 pass(es). View

Patch #13 contained a duplicate line (for $allowed_values = ...). It is removed in this new version.

bleen’s picture

Issue tags: +Needs tests

This probably needs a quick test

bleen’s picture

Status: Needs review » Needs work
cristiroma’s picture

FileSize
1.35 KB
FAILED: [[SimpleTest]]: [MySQL] 58,647 pass(es), 3 fail(s), and 0 exception(s). View

Re-roll the code work with the current HEAD. Still needs the tests implemented.

cristiroma’s picture

Status: Needs work » Needs review
FileSize
2.04 KB
2.78 KB
FAILED: [[SimpleTest]]: [MySQL] 58,581 pass(es), 3 fail(s), and 0 exception(s). View

Changes:
1. Added a test case that checks the function options_array_flatten
2. Fixed code phpdoc

Status: Needs review » Needs work

The last submitted patch, 1180992-optgroup-validation-19.patch, failed testing.

mikegoodwin’s picture

Assigned: Unassigned » mikegoodwin

re-rolling

YesCT’s picture

Assigned: mikegoodwin » Unassigned
Issue summary: View changes
Issue tags: +Needs reroll

feel free to jump in to do the reroll anytime. https://drupal.org/contributor-tasks/reroll

saki007ster’s picture

Assigned: Unassigned » saki007ster
saki007ster’s picture

Status: Needs work » Needs review
FileSize
643.74 KB
PASSED: [[SimpleTest]]: [MySQL] 63,136 pass(es). View

re-rolling this patch.

saki007ster’s picture

FileSize
3.89 KB
PASSED: [[SimpleTest]]: [MySQL] 63,145 pass(es). View

Sorry , earlier patch was my stupidity. Replaced it with new one.

saki007ster’s picture

Assigned: saki007ster » Unassigned
prateek479’s picture

FileSize
109.53 KB

Select list working fine

martin107’s picture

Issue tags: -Needs reroll

patch currently applies.

jorgegc’s picture

FileSize
3.89 KB
PASSED: [[SimpleTest]]: [PHP 5.4 MySQL] 77,734 pass(es). View

Re-rolling patch in #25

jorgegc’s picture

Just looked for the +Needs reroll tag and couldn't find it... I guess I've just rerolled a patch that applies LOL, my bad!

jhedstrom’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

Even though this patch still applies, it needs a reroll keeping this change in mind.

ravi.khetri’s picture

Status: Needs work » Needs review
FileSize
3.88 KB
PASSED: [[SimpleTest]]: [PHP 5.4 MySQL] 92,285 pass(es). View

Rerolled.

dcam’s picture

Issue tags: -Needs reroll

#33 applies to HEAD. Removing the "Needs reroll" tag.

jOksanen’s picture

Works for me.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.