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.

<?php
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:

<?php
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
#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 bytesbleen18
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 bytesbleen18
PASSED: [[SimpleTest]]: [MySQL] 33,808 pass(es).
[ View ]

Comments

bleen18’s picture

Version:7.x-dev» 8.x-dev
Status:Active» Needs review
StatusFileSize
new838 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

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

StatusFileSize
new905 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.

bleen18’s picture

Status:Needs work» Needs review
StatusFileSize
new844 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

bleen18’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

StatusFileSize
new1.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

StatusFileSize
new1.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.

bleen18’s picture

Issue tags:+Needs tests

This probably needs a quick test

bleen18’s picture

Status:Needs review» Needs work
cristiroma’s picture

StatusFileSize
new1.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
StatusFileSize
new2.04 KB
new2.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
StatusFileSize
new643.74 KB
PASSED: [[SimpleTest]]: [MySQL] 63,136 pass(es).
[ View ]

re-rolling this patch.

saki007ster’s picture

StatusFileSize
new3.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

StatusFileSize
new109.53 KB

Select list working fine

martin107’s picture

Issue tags:-Needs reroll

patch currently applies.

jorgegc’s picture

StatusFileSize
new3.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.