As I was adding a field to a content type, I ended up with two Label field text inputs on the form (see screenshot). It took me a while to figure out the steps to reproduce it, but finally hit on them...

1) Select a field type from the Add a new field select list (I selected Taxonomy term)

2) Click to open the select list for "Re-use an existing field". (After I had selected to add a new field, I thought I should check to see if that field already existed.)

3) Scroll the list of options in the select list opened in step 2 above. My mouse pointer happened to be hovering over one of the options, but I didn't actually click on it - just had the list open and one of the options highlighted (because it was where my pointer was).

4) Switch to another program on your computer. I'm on a MacBookPro, and I used Ctrl-tab to switch to another browser.

5) Switch back to the browser with Drupal. You should see two Label fields.

Comments

ExTexan created an issue. See original summary.

20th’s picture

Version: 8.2.2 » 8.3.x-dev
Component: field system » javascript
Status: Active » Needs work
FileSize
16.36 KB

I was able to reproduce this bug in Firefox on Windows 7 and Linux, but not in Chrome or IE, so it seems like a browser-specific issue.

This bug is caused by how browser events are handled by Drupal form states in states.js. Similar behaviour can be achieved in any form that uses states to show/hide its fields. Here is an example of this bug in translations export form; the Export options fieldset must be invisible when a language is not selected.

[bug]

There is an easier way to trigger this bug:

  1. Go to the 'Add field' page as described in the issue summary.
  2. Select any value in the 'Add a new field' field. The 'Label' input will become visible.
  3. Click on the 'Re-use an existing field' select to open list of options.
  4. Move the mouse pointer over any item in the list and press Ctrl on your keyboard.
  5. You should now see two 'Label' inputs.
20th’s picture

The states.Trigger object defined in core/misc/states.js binds two browser events – keyup and change – to recalculate the state of form items.

The problem is that Firefox emits the keyup event on a <select> element when the dropdown list of options is opened and user presses the keyboard. This causes the events handler to somehow read the dirty value of the select element, even thought the change event has not been triggered yet. This, in turn, leads to recalculation of form items state and update of DOM.

Chrome and IE, on the other hand, block keyboard events until the dropdown is closed, so this bug is not consistent between browsers.

There are two possible solutions here:

1. Ignore any keyup events on select inputs.

This is a simple and straightforward solution. The events handler already has a special case for radio buttons, so adding another one will not make the code any more complicated. But this may possibly introduce some accessibility issues.

2. Make sure the handler always reads the real value of a <select> element, instead of a dirty value from the event object.

20th’s picture

Status: Needs work » Needs review
FileSize
579 bytes

For starters, here is a patch to ignore keyup events on selects.

It fixes the bug for me in Firefox, without adding any visible regressions Chrome or IE.

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

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now 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.