Problem/Motivation

The Options module uses _none to indicate the empty option. However, for browsers this means the select element has a value. As a result, common client side logic no longer applies. For example:

MDN example of an option suggests using an empty string for the value attribute, see https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/select

Proposed resolution

  1. Map the _none option label to the Select #empty_option in a process callback
  2. Set #empty_value = '' in a process callback, so the select renders as <option value="">#empty_option</option> (BC break)
  3. Deprecate the _none option in #2448545: Modernize form select option helpers

Remaining tasks

  1. Write a merge request
  2. Review
  3. Commit

User interface changes

None

API changes

A select element now uses an empty string for the empty option:

Before:

<option value="_none">- Select -</option>

After:

<option value="">- Select -</option>

Original report by attiks

This was originally introduced in #735426: Fields with select widget: first option is selected by default even if no 'default value' set for the field

A user of clientside_validation reported this bug (#1585554: Validating lists (select-fields) not working correctly), it is caused by the fact that the options.module uses the following: $options = array('_none' => $label).

First problem is that the outputted HTML contains <option value="_none"> and this means the select element has a value.
Second (unrelated) problem is that we allow people to enter "_none|oops" as an allowed value, but it will never be outputted unless a default value is selected.

I found #735426: Fields with select widget: first option is selected by default even if no 'default value' set for the field where this was introduced, so I would like to change the use of '_none' to NULL

Issue fork drupal-1585930

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

attiks’s picture

Status: Active » Needs review
StatusFileSize
new7.03 KB

Patch attached

geerlingguy’s picture

Can't see why FAPI options uses '_none' when NULL seems a more logical (and less painful) method of adding an empty option. +1 here.

swentel’s picture

Assigned: Unassigned » yched
StatusFileSize
new7.71 KB

I can't think of any good reason why '_none' is used either. Rerolled the patch as it didn't apply anymore.
Assigning to yched however because maybe he has some more historical background, I'll let him push this RTBC or not.

Status: Needs review » Needs work

The last submitted patch, 1585930-3.patch, failed testing.

yched’s picture

Status: Needs work » Needs review

Ouch - bad memories around this, i'm not too thrilled to poke in there :-).
This probably had to do with what FAPI select / radios / checkboxes allowed back in D6 / D7. Maybe those elements are fine with a NULL / empty string value now, but that would need to be thoroughly tested.

Also
- patch uses NULL as value in the FAPI code but empty strings in submitted forms values in tests ? Not ideal, but I guess that's how it works...
- could we settle on '' (single quotes) rather than "" (double quotes) for empty string ?

haydeniv’s picture

We're dealing with this over at Select or Other #1830090: Align with Drupal core select list, NULL (-None-) value. as well, so we're anxious to see where this one goes.

brad.bulger’s picture

an array key should be an empty string, since PHP will cast NULL to one anyway.

i'd like to see this change too. another problem with how it is now is that you can create your own explicit empty-string key|label pair - eg "|None" - in the list of values for the field, but users end up seeing both the Drupal-generated "_none|N/A" and your "|None", both of which produce the same end result.

this already was an empty string up through 6.x, so presumably somebody changed that to '_none' for some reason. it would probably be good to know why that was done.

i'd like to also suggest allowing users to more easily customize the option_none value's label by declaring their own explicitly in the field's value list, as with "|None". that would work if we just swap the way the Drupal-generated value is added to the option list in _options_get_options():

$options = $options + array('' => $label);

instead of

$options = array('' => $label) + $options;
rwohleb’s picture

In D7, I find it odd that the options module doesn't just pass #empty_value and #empty_option to the underlying select, but instead does its own thing with theme_options_none(). Wouldn't it make more sense to set these standard FAPI options from the field settings instead? At least this way it would be done in a way people would expect, plus #empty_value defaults to an empty string (can't be NULL according to docs), so the question of "" or "_none" seems handled.

In D8 this also seems to apply, but I'm not up-to-date with D8 development.

haydeniv’s picture

In 8 you implement a isEmtpy() method I believe. https://drupal.org/node/1985716

I'm going to take a crack at converting this module to 8.x pretty soon. Unless someone beats me to it of course.

brad.bulger’s picture

what is this issue waiting on? does it have to be fixed in 8.x and then backported to 7.x?

swentel’s picture

Issue summary: View changes
StatusFileSize
new8.29 KB

reroll

Status: Needs review » Needs work

The last submitted patch, 11: 1585930-11.patch, failed testing.

damienmckenna’s picture

Issue tags: +affects drupal.org, +Needs backport to 7.x

This affects the drupal.org "gender" profile field on d.o, so I'm marking it as such. As a result, I'm also closing a duplicate: #2412393: "Prefer not to share" gender option option does not display correct in profile form.

damienmckenna’s picture

Assigned: yched » Unassigned

Taking it off yched's plate as it hasn't been touched in a year.

yesct’s picture

This could use an updated issue summary to make it easier for someone to help with this. See instructions: https://drupal.org/contributor-tasks/write-issue-summary

tstoeckler’s picture

Yes, #8 is spot on. Let's use #empty_option and #empty_value please!

xjm’s picture

Issue tags: -Needs backport to 7.x +Needs backport to D7

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.

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

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

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

kenorb’s picture

In Drupal 7 pretty weird is happening.

I've got field like:

  '#entity_type' => string 'entityform' (length=10)
  '#field_name' => string 'field_declaration_checkbox_2' (length=28)
  '#required' => boolean true
  '#delta' => int 0
  '#type' => string 'checkbox' (length=8)
  '#default_value' => int 0
  '#on_value' => int 1
  '#off_value' => int 0
  '#value_key' => string 'value' (length=5)
  '#element_validate' => 
    array (size=2)
      0 => string 'options_field_widget_validate' (length=29)
  '#value' => int 0
  '#checked' => boolean false

where before I start the form, the value is string, when submitting, it's integer. When it's integer, this code doesn't make any sense:

function options_field_widget_validate($element, &$form_state) {
  if ($element['#required'] && $element['#value'] == '_none') {

When you comparing integer with string, string becomes integer (zero in this case). So in this case #value equals to '_none', but it's not really none. I don't know if it's my custom code causing it, but probably not.

imot3k’s picture

StatusFileSize
new9.4 KB
new9.4 KB

Re-rolled against 8.2.x.

imot3k’s picture

imot3k’s picture

StatusFileSize
new9.76 KB

Re-roll.

imot3k’s picture

StatusFileSize
new9.76 KB

The last patch threw an error when trying to submit a form with a select list that is not required.

geerlingguy’s picture

Status: Needs work » Needs review

The last submitted patch, 21: 1585930-21.patch, failed testing.

The last submitted patch, 23: 1585930-23.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 24: 1585930-24.patch, failed testing.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

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

rgpublic’s picture

One question on #24: Are there any inherent problems still associated with the patch? Or are the tests only failing because the tests themselves have to be adapted? TIA!

mpp’s picture

Version: 8.3.x-dev » 8.4.x-dev

The HTML
required Attribute only triggers client-side validation if the value isn't set so we should implement this issue and remove '_none'. See https://www.w3schools.com/tags/att_select_required.asp

The patch in #24 no longer applies to 8.3.5

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

rgpublic’s picture

StatusFileSize
new2.04 KB

I agree, mpp. Client-side validation doesnt work if there's a "_none" value. Furthermore, you'll get W3C validation errors if there's not a decent empty value. TBH, I think it was an extremely bad idea to introduce this magic _none value. It ought to be removed ASAP. Hopefully, this patch is included in future Drupal versions.

The patch, BTW, doesnt apply, because the test files dont seem to exist anymore and - as usual - the Array syntax has changed to just brackets. I've added a patch for 8.3.x. Perhaps it will also apply for later versions.

anas_maw’s picture

Status: Needs work » Needs review
StatusFileSize
new51.69 KB

Patch #33 solved the issue for me Drupal core 8.4.4, this should be committed to core

anas_maw’s picture

Status: Needs review » Reviewed & tested by the community

This should be set to RTCB

wim leers’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs reroll

The patch does not apply.

arunkumark’s picture

Status: Needs work » Needs review
StatusFileSize
new2.04 KB

I have re-rolled the patch for supporting the latest version of Drupal 8.5.x.

Status: Needs review » Needs work

The last submitted patch, 37: special-value-1585930-37.patch, failed testing. View results

jofitz’s picture

Issue tags: -Needs reroll

Removed Needs Reroll tag.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

nikunjkotecha’s picture

Status: Needs work » Needs review
StatusFileSize
new9.96 KB

Updated tests to check for empty string instead of _none.

Status: Needs review » Needs work

The last submitted patch, 41: 1585930-41.patch, failed testing. View results

nikunjkotecha’s picture

Status: Needs work » Needs review
StatusFileSize
new10.23 KB

This should make the unit tests happy.

chiranjeeb2410’s picture

Status: Needs review » Reviewed & tested by the community

Patch applies cleanly. Usage of empty strings seems alright instead of _none.
RTBC good to go!

larowlan’s picture

Status: Reviewed & tested by the community » Needs review
  1. +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/OptionsWidgetBase.php
    @@ -67,7 +67,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
    -    if ($element['#required'] && $element['#value'] == '_none') {
    +    if ($element['#required'] && $element['#value'] == '') {
    

    I'm not sure this is the same thing.

    $element[#value] of FALSE or possibly 0 would match here.

    I think we need === not ==

  2. +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/OptionsWidgetBase.php
    @@ -85,7 +85,7 @@ public static function validateElement(array $element, FormStateInterface $form_
    -    $index = array_search('_none', $values, TRUE);
    +    $index = array_search('', $values, TRUE);
    

    we're being strict about type here, so that makes me more sure ^ should be strict too

  3. +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/OptionsWidgetBase.php
    @@ -117,7 +117,7 @@ protected function getOptions(FieldableEntityInterface $entity) {
    +        $options = ['' => $empty_label] + $options;
    
    +++ b/core/modules/options/options.api.php
    @@ -32,7 +32,7 @@ function hook_options_list_alter(array &$options, array $context) {
    +    $options[''] = t('== Empty ==');
    
    +++ b/core/modules/options/tests/src/Functional/OptionsSelectDynamicValuesTest.php
    @@ -25,7 +25,7 @@ public function testSelectListDynamic() {
    +      if ($value != '') {
    
    +++ b/core/modules/options/tests/src/Functional/OptionsWidgetsTest.php
    @@ -125,7 +125,7 @@ public function testRadioButtons() {
    +    $edit = ['card_1' => ''];
    

    I think we should use a constant here instead of ''.

    OptionsWidgetBase::EMPTY_VALUE or something.

    That way, if we change it in the future, we do it once

    Would bring it in line with #2448545: Modernize form select option helpers too

  4. +++ b/core/modules/options/tests/src/Functional/OptionsSelectDynamicValuesTest.php
    @@ -25,7 +25,7 @@ public function testSelectListDynamic() {
    -      if ($value != '_none') {
    +      if ($value != '') {
    

    same comment about strictness applies here

nikunjkotecha’s picture

StatusFileSize
new10.23 KB
new1.49 KB

Thanks @larowlan for quick feedback.

Fixed the issues related to strict checking.

About replacing '_none' or '' with class constant - I would request to keep it in #2448545: Convert '_none' option to a constant and deprecate form_select_options() only as it will be out of scope for current ticket + changes required for #2448545 are even outside the Options core module. There are many references to '_none' outside the module so it makes more sense to create the constant in core itself (outside the module). Approach and solution in #2448545 look good to me (and for sure it is going through it's own review cycle), only issue I see is bit of rework required in one of the patches after the other patch is merged, which should be fine IMO.

amateescu’s picture

Status: Needs review » Needs work

We should change OptionsSelectWidget to use the #empty_option and #empty_value properties of the select FAPI element (\Drupal\Core\Render\Element\Select), like already mentioned in #8 and #16 :)

amateescu’s picture

Issue tags: +Needs change record

Also, this is kind of a BC break for modules which implement hook_options_list_alter() so we need a CR at least.

idebr’s picture

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

colan’s picture

Adding the other issue as related.

(Although, personally, I don't see the point of continuing to maintain this module in core, when Taxonomy always seems to be the better choice. But maybe I'm missing something?)

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Hammad Ghani’s picture

StatusFileSize
new2.05 KB

Patch applied successfully for 8.8.4.

joseph.olstad’s picture

Status: Needs work » Needs review
StatusFileSize
new10.63 KB

rerolled patch 46

Status: Needs review » Needs work

The last submitted patch, 56: 1585930-56.patch, failed testing. View results

ridhimaabrol24’s picture

StatusFileSize
new10.09 KB

Rerolled patch for latest head for 9.1.x

anushrikumari’s picture

Status: Needs work » Needs review
ridhimaabrol24’s picture

Status: Needs review » Needs work

@anushrikumari The test cases are failing. hence the correct status is "Needs Work".

ridhimaabrol24’s picture

StatusFileSize
new11.46 KB
new2.03 KB

Fixing tests!

ridhimaabrol24’s picture

Status: Needs work » Needs review
StatusFileSize
new11.53 KB
new952 bytes

Fixing failed test.

andrewmacpherson’s picture

Re: #51. Emphasis mine...

(Although, personally, I don't see the point of continuing to maintain this module in core, when Taxonomy always seems to be the better choice. But maybe I'm missing something?)

That's a fairly opinionated choice; I'd tend to disagree here. Which one you choose really depends on your needs.

Taxonomy is a good choice if you need:

  • The ability for content managers to add new options later on.
  • Listing pages for content with a particular term. (Taxonomy module comes with some pre-made views, although you could easily create ones based on options fields too.)
  • "Big-T" taxonomy features - such as hierarchical vocabularies, preferred terms, synonym collapsing, glossary of term and definition, controlled vocabularies with authority codes, etc.

On the other hand, Taxonomy module brings in a lot of extra baggage, if all you want is a simple enumerated property on a node.

  • An "options" field implemented using taxonomy terms will have dependencies on content entities (the terms), not just field config entities. So deployment of new features is complicated by the need to create the term entities in advance (using an update hook, say), and the need for a term ID to be the same on development/production environments.
  • Using terms for a simple options field carries a risk of breakage if a term is deleted. So you need to take steps to prevent this, with permissions.
  • Terms have a taxonomy/term/% route of their own. Unless your "options" need a page of their own, then you'll need to take steps to hide this from site visitors.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

villette’s picture

StatusFileSize
new11.49 KB

Reroll patch #62 against head of 9.2.x
Also applies to 9.1.0

longwave’s picture

I'm confused between this and #2448545: Modernize form select option helpers as they both seem to be going in the same direction but the patches are quite different.

I don't believe we can just change this constant as there could be JavaScript or custom code depending on the existing special value. However, I also don't know how we would be able to deprecate it.

geek-merlin’s picture

> I don't believe we can just change this constant as there could be JavaScript or custom code depending on the existing special value.

Yes good point.

> However, I also don't know how we would be able to deprecate it.

We can use the "Only new installs get it" pattern.

A imho thorough solution would make this a parameter of the render array (like '#empty_key'), which defaults to '_none' for old installs, and '' for new ones. (Which also means i'd suggest to close the other issue as dup.)

joseph.olstad’s picture

StatusFileSize
new9.12 KB

patch 64 needed a reroll

Status: Needs review » Needs work

The last submitted patch, 68: 1585930-68.patch, failed testing. View results

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

nikitagupta’s picture

Status: Needs work » Needs review
StatusFileSize
new9.23 KB

Rerolled patch #68.

nikitagupta’s picture

StatusFileSize
new10.96 KB
new2.67 KB

fixed the failed test case.

The last submitted patch, 71: 1585930-71.patch, failed testing. View results

joachim’s picture

Status: Needs review » Needs work

Needs work based on #67. This is going to break any custom code that uses form options, such as submit and validation handlers.

The BC policy says that the form and render API are public, though individual pages and forms aren't. That means that the value you get from a form element is part of our public API.

clayfreeman’s picture

Re: #67

The problem with "new installs get it" is that you effectively prevent people with centralized custom modules from doing new installs without a major refactor, or manipulating state somewhere.

I'd tend to lean toward a new element being the safest option, as no BC concerns present themselves.

joachim’s picture

> A imho thorough solution would make this a parameter of the render array (like '#empty_key'), which defaults to '_none' for old installs, and '' for new ones. (Which also means i'd suggest to close the other issue as dup.)

That would make it different for each form, which is probably needed in case a site has a mixture of contrib modules that have updated to the new empty key and modules that haven't.

> The problem with "new installs get it" is that you effectively prevent people with centralized custom modules from doing new installs without a major refactor, or manipulating state somewhere.

But could we also set a global setting in an update hook, so existing sites don't need to do anything? A container parameter would do it, but I don't think there's a way that could be set permanently by an update hook?

johnpitcairn’s picture

FWIW, the patch at #72 also applies against 9.2.x and works as expected with clientside validation. Having html5 validation for list elements is a huge win.

johnpitcairn’s picture

Patch at #72 no longer applies to 9.2.7. I'll possibly attempt a backport sometime soon, unless anyone else cares to do so.

ankithashetty’s picture

StatusFileSize
new11.01 KB
new3.31 KB

Rerolled the patch in #72 as requested in #78. Retaining status as "Needs work" for the reviews mentioned in #74 to #77.

Thanks!

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

richardhobbs made their first commit to this issue’s fork.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

mistrae’s picture

StatusFileSize
new11.04 KB

Rerolled against latest version

dhinakaran’s picture

StatusFileSize
new2.09 KB

Rerolled against the patch 158590_55 for version 9.x

johnpitcairn’s picture

arunkumark’s picture

Status: Needs work » Needs review
StatusFileSize
new10.62 KB

The patch has been rerolled for Drupal 10.1.x

Status: Needs review » Needs work

The last submitted patch, 87: 1585930-87.patch, failed testing. View results

joseph.olstad’s picture

Patch 84 still applies cleanly to the HEAD of 9.5.x, 10.0.x and 10.1.x, I just checked vs the latest in each branch.

Patch 84 passes.

Patch 85 and 87 were not needed and were incorrectly rolled and fail testing.

https://www.drupal.org/docs/develop/git/using-git-to-contribute-to-drupa...

longwave’s picture

We still need to address the backward compatibility concerns from #66 onwards: we need a way to allow keep '_none' for existing sites that depend on it, while allowing '' for sites that want to use that instead.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

joseph.olstad’s picture

patch 84 no longer applies to 10.0.x, will need a new patch for 10.0.10

joseph.olstad’s picture

StatusFileSize
new11.03 KB
sumithra ramalingam’s picture

Thank you @joseph.olstad
Patch #93 working clearly with D10.1.4 version.

luenemann’s picture

Issue summary: View changes

Fixed link to project page.

darktek’s picture

StatusFileSize
new10.79 KB

New 11.2.3 version was released today and patch #93 is not working anymore.

I'm sharing this new patch

eduardo morales alberti’s picture

@darktek some changes do not match the 93 patch:

Why do you replaced "$element['#value'] === ''" by "$element['#value'] == ''" or "if ($value !== '') {" by "if ($value != '') {"?

interdiff 1585930-93.patch 1585930-96.patch

diff -u b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/OptionsWidgetBase.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/OptionsWidgetBase.php
--- b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/OptionsWidgetBase.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/OptionsWidgetBase.php
@@ -90,7 +90,7 @@
    *   The form state.
    */
   public static function validateElement(array $element, FormStateInterface $form_state) {
-    if ($element['#required'] && $element['#value'] === '') {
+    if ($element['#required'] && $element['#value'] == '') {
       if (isset($element['#required_error'])) {
         $form_state->setError($element, $element['#required_error']);
       }
@@ -144,7 +144,7 @@
 
       // Add an empty option if the widget needs one.
       if ($empty_label = $this->getEmptyLabel()) {
-        $options = ['' => $empty_label] + $options;
+        $options = ['_none' => $empty_label] + $options;
       }
 
       $module_handler = \Drupal::moduleHandler();
diff -u b/core/modules/options/tests/src/Functional/OptionsSelectDynamicValuesTest.php b/core/modules/options/tests/src/Functional/OptionsSelectDynamicValuesTest.php
--- b/core/modules/options/tests/src/Functional/OptionsSelectDynamicValuesTest.php
+++ b/core/modules/options/tests/src/Functional/OptionsSelectDynamicValuesTest.php
@@ -36,7 +36,7 @@
     $this->assertCount(count($this->test) + 1, $options);
     foreach ($options as $option) {
       $value = $option->getValue();
-      if ($value !== '') {
+      if ($value != '') {
         $this->assertContains($value, $this->test);
       }
     }
diff -u b/core/modules/options/tests/src/Functional/OptionsWidgetsTest.php b/core/modules/options/tests/src/Functional/OptionsWidgetsTest.php
--- b/core/modules/options/tests/src/Functional/OptionsWidgetsTest.php
+++ b/core/modules/options/tests/src/Functional/OptionsWidgetsTest.php
@@ -613,7 +613,7 @@
 
     // Display form: check that empty '' option is present and has label.
     $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
-    $this->assertNotEmpty($this->xpath('//div[@id=:id]//input[@value=:value]', [':id' => 'edit-card-1', ':value' => '']), 'A test radio button has a "None" choice.');
+       $this->assertNotEmpty($this->xpath('//div[@id=:id]//input[@value=:value]', [':id' => 'edit-card-1', ':value' => '']), 'A test radio button has a "None" choice.');
 
     // Change it to the select widget.
     $display_repository->getFormDisplay('entity_test', 'entity_test')
diff -u b/core/modules/workspaces/tests/src/Functional/WorkspaceTestUtilities.php b/core/modules/workspaces/tests/src/Functional/WorkspaceTestUtilities.php
--- b/core/modules/workspaces/tests/src/Functional/WorkspaceTestUtilities.php
+++ b/core/modules/workspaces/tests/src/Functional/WorkspaceTestUtilities.php
@@ -52,12 +52,12 @@
    * @param string $id
    *   The ID of the workspace to create.
    * @param string $parent
-   *   (optional) The ID of the parent workspace. Defaults to ''.
+   *   (optional) The ID of the parent workspace. Defaults to '_none'.
    *
    * @return \Drupal\workspaces\WorkspaceInterface
    *   The workspace that was just created.
    */
-  protected function createWorkspaceThroughUi($label, $id, $parent = '') {
+  protected function createWorkspaceThroughUi($label, $id, $parent = '_none') {
     $this->drupalGet('/admin/config/workflow/workspaces/add');
     $this->submitForm([
       'id' => $id,
@@ -94,12 +94,12 @@
    * @param string|null $id
    *   The ID of the workspace to create.
    * @param string $parent
-   *   (optional) The ID of the parent workspace. Defaults to '_none'.
+   *   (optional) The ID of the parent workspace. Defaults to ''.
    *
    * @return \Drupal\workspaces\WorkspaceInterface
    *   The workspace that was just created.
    */
-  protected function createWorkspaceThroughUi(?string $label = NULL, ?string $id = NULL, string $parent = '_none') {
+  protected function createWorkspaceThroughUi(?string $label = NULL, ?string $id = NULL, string $parent = '') {
     $id ??= $this->randomMachineName();
     $label ??= $this->randomString();
eduardo morales alberti’s picture

We will open a MR to track the changes properly

eduardo morales alberti’s picture

Status: Needs work » Needs review
eduardo morales alberti’s picture

Failed PHPUnit:

    Options Widgets (Drupal\Tests\options\Functional\OptionsWidgets)
     ✔ Radio buttons
     ✔ Check boxes
     ✔ Select list single
     ✘ Select list required error attribute
       ┐
       ├ Behat\Mink\Exception\ElementNotFoundException: Option with id|name|label|value "_none" not found.
       │
       │ /builds/issue/drupal-1585930/core/tests/Drupal/Tests/WebAssert.php:241
       │ /builds/issue/drupal-1585930/core/modules/options/tests/src/Functional/OptionsWidgetsTest.php:406
       ┴
     ✔ Select list multiple
     ✔ Select list float
     ✔ Empty value
     ✘ Options list alter
       ┐
       ├ Behat\Mink\Exception\ElementNotFoundException: Element matching xpath "//select[@id="edit-card-1"]//option[@value="_none" and text()="- None -"]" not found.
       │
       │ /builds/issue/drupal-1585930/vendor/behat/mink/src/WebAssert.php:465
       │ /builds/issue/drupal-1585930/core/modules/options/tests/src/Functional/OptionsWidgetsTest.php:689

Functional with Javascript:

    Entity Reference Widget (Drupal\Tests\media_library\FunctionalJavascript\EntityReferenceWidget)
     ✔ Focus not applied without selection change
     ✔ Widget
     ✔ Required media field
     ✔ Remove after reordering
     ✔ Add after reordering
     ✘ Widget preview
       ┐
       ├ "Removing media." not found                  
       ├ Failed asserting that a boolean is not empty.
       │
       │ /builds/issue/drupal-1585930/core/modules/media_library/tests/src/FunctionalJavascript/MediaLibraryTestBase.php:69
       │ /builds/issue/drupal-1585930/core/modules/media_library/tests/src/FunctionalJavascript/EntityReferenceWidgetTest.php:656
eduardo morales alberti’s picture

Status: Needs review » Needs work
eduardo morales alberti’s picture

Failing:

    Options Widgets (Drupal\Tests\options\Functional\OptionsWidgets)
     ✔ Radio buttons
     ✔ Check boxes
     ✔ Select list single
     ✔ Select list required error attribute
     ✔ Select list multiple
     ✔ Select list float
     ✔ Empty value
     ✘ Options list alter
       ┐
       ├ Behat\Mink\Exception\ElementNotFoundException: Element matching xpath "//select[@id="edit-card-4"]//option[@value="" and text()="- Select something -"]" not found.
       │
       │ /builds/issue/drupal-1585930/vendor/behat/mink/src/WebAssert.php:465
       │ /builds/issue/drupal-1585930/core/modules/options/tests/src/Functional/OptionsWidgetsTest.php:691
idebr’s picture

Issue summary: View changes
Issue tags: -Needs issue summary update

To minimize the BC break, I suggest we map the _none option to the Select #empty_option and set #empty_value to an empty string in a process callback.

This implementation allows existing options to remain unchanged; only client side logic is impacted (eg. JavaScript)

idebr changed the visibility of the branch 1585930-options-module-uses to hidden.

idebr’s picture

Title: Options module uses '_none' as a special value » Render the _none option as an empty value for single select to allow client side validation
Category: Bug report » Task
Status: Needs work » Needs review

Based on the issue summary, comments and related issues the immediate problem is limited to single select elements and client side validation. If I missed something, let me know and I can update the issue accordingly

Refactoring the _none value itself is being worked on in #2448545: Modernize form select option helpers

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new2.17 KB

The Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

idebr’s picture

Status: Needs work » Needs review
smustgrave’s picture

Status: Needs review » Needs work
Issue tags: -affects drupal.org, -Needs backport to D7

Still appears this will need a CR. Do have some backwards compatibility concerns but not sure how to address them

joseph.olstad’s picture

StatusFileSize
new9.94 KB

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.