If you create a form select element with an options array with a 0 and string indexes, if the value is a string or 0, multiple options will be marked selected.

The form element:

$options = array('a'=> 'A', 0 => 'zero', 'b => 'B');
$form['foo'] = array(
  '#type' => 'select',
  '#title' => 'options...',
  '#default_value' => 'a',
  '#options' => $options,
);

Renders as:

<select name="edit[foo]"  id="edit-foo" ><option value="a" selected="selected">A</option><option value="0" selected="selected">zero</option><option value="b">B</option></select>

PHP evaluates 'a' == 0 as true. 'a' is converted to a number, which will be zero, and they're considered equivalent. The solution is to convert the option key to a string before comparing it to the value.

The attached patch modifies the theme_select in form.inc to do this.

Comments

chx’s picture

Status: Needs review » Closed (duplicate)
chx’s picture

Status: Closed (duplicate) » Needs work

(sorry I misunderstood the problem, rereading makes me understand it)

quoting values is not a real solution to this. What about === ?

drewish’s picture

Aren't most POSTed values strings? So you'd be forced to make all your indexes strings when you're building the options array. That prevents you from doing things like $options = range(0, 5);...

Is using quotes to cast it to a string really a problem?

jvandyk’s picture

StatusFileSize
new1.19 KB

Here's a patch with the === solution implemented. Both options with mixed keys and nested options work. Naturally one must put in the correct type in #default_value if you want a match (if your key is 0, '0' in #default_value will not match but 0 will).

drewish’s picture

jvandyk, that doesn't work either.

Put that control (after you fix the missing ') into a node form. Open up the form, set the value to an option with a numeric index and preview it. It'll preview correctly but you'll loose the selection on the form.

The reason is that the values POSTed are strings. As I said before, if you don't cast it to a string, you'd have to make sure that all your option indexes are either all numeric or, if you mix strings and numbers, non-zero.

drewish’s picture

would casting using (string) be better?

chx’s picture

If, you would comment it that it's a string cast, then I would lean to accepting it.

drewish’s picture

StatusFileSize
new1.91 KB

based on the triple nesting of the ? : operator, i thought brevity was valued over readability :p

here's a patch using (string).

chx’s picture

Status: Needs work » Needs review

My friend, if you want to change it to more readable, rest assured it'll be welcomed warmly. Thanks for your hard work so far.

drewish’s picture

StatusFileSize
new2.12 KB

here's a more-readable patch

moshe weitzman’s picture

quite a bit more readable. i can't test this now though.

drewish’s picture

StatusFileSize
new2.11 KB

Here's a re-roll that's current.

drewish’s picture

StatusFileSize
new1.25 KB

re-roll for head

drewish’s picture

Status: Needs review » Fixed

it looks like someone else figured out this bug and added in a cast.

jamespvg’s picture

Status: Fixed » Active

Reopened as requested by drewish due to this related bug: http://drupal.org/node/45836.

drewish’s picture

Status: Active » Fixed

Humm, chx just pointed out bug #45365 to me... It looks, to me, like it should have fixed it. That seems like a better place to continue this discussion so I'll mark this as fixed again.

Anonymous’s picture

Status: Fixed » Closed (fixed)