Problem/Motivation
In Select2 Entity Reference field widgets, with autocomplete enabled, for multivalued fields, removing a selected option doesn't always work on the first click. When the issue occurs, it needs 3 clicks. See screen recording @ https://www.drupal.org/files/issues/2022-03-23/Screen%20Recording%202022... .
Steps to reproduce
- Install standard Drupal
- Install select2 module
- Configure the Select2 Entity Reference field widget for the Tags field on Article content type
- Make sure autocomplete is enabled for the Select2 Entity Reference field widget
- Create 10 tags or so
- Create an Article with those 10 tags
- Navigate to the edit form of the Article you just created
- Start clicking on the X-icons in the tags field 1 by 1. Eventually you'll come across a tag that needs 3 clicks before it get removed.
Proposed resolution
Unsure what the solution is, but I did track the root cause of the issue: the drag & drop functionality that is initiated here:
// Copied from https://github.com/woocommerce/woocommerce/blob/master/assets/js/admin/wc-enhanced-select.js#L118
if (Object.prototype.hasOwnProperty.call(config, 'ajax') && config.multiple) {
var $select = $(this);
var $list = $select.next('.select2-container').find('ul.select2-selection__rendered');
Sortable.create($list[0], {
draggable: 'li:not(.select2-search)',
forceFallback: true,
onEnd: function () {
$($list.find('.select2-selection__choice').get().reverse()).each(function () {
$select.prepend($select.find('option[value="' + $(this).data('optionValue') + '"]').first());
});
}
});
}
The usage of SortableJs was introduced in #3104877: Replace jquery.ui.sortable with SortableJs.
Comments
Comment #2
tuuuukka commentedThis seems to be a really random thing, hard to say where the problem actually lies. One way to reproduce this is to grab any selected tag, move it a little but not change the order, release it and then try to remove it -> requires 2 clicks on the X before it's actually removed. The first click adds
draggable="false"to the element.Comment #3
tuuuukka commentedNot an actual fix, but this helps anyway: https://github.com/SortableJS/Sortable#fallbacktolerance-option
I noticed that when you're clicking the X's, it sometimes fires the SortableJS stuff 'cause it counts the click as a drag if your mouse moves even a little bit. It's simple to try out when it happens:
I added fallbackTolerance: 10, and it does help with those unwanted drags when you're just trying to click. But this still doesn't completely solve the actual problem. I still think it's better than the default behavior though, so here's a simple patch.
Comment #4
tuuuukka commentedHad a sudden thought of this being caused by the order of the items not changing, but the code inside
onEndbeing run nevertheless. So I tried checking if the order has changed before running the piece code, and that seems to fix it -> if the order has changed, run the code, if the order is the same, do nothing.Patch included.
Comment #5
recrit commentedI ran into this same issue. The patch #4 did not fix this issue for me. The patch #3 did not fix this issue for me.
Field setup:
- autocomplete
- multiple values
Select2: 4.1.0-rc.0
Browsers:
Chrome, FireFox
To Reproduce:
I was able to reproduce this with only 1 or 2 tags. You just have to drag 1 item left or right but keep it in the same position.
Troubleshooting:
It works ok when I remove only the Sortable option
forceFallback: true.From https://github.com/SortableJS/Sortable#options:
"forceFallback: ignore the HTML5 DnD behaviour and force the fallback to kick in"
I do not see this option set in any Drupal core usage of the Sortable library.
Fix:
The attached patch removes the option "forceFallback".
Maintainers - any feedback on why the forceFallback option was used?
It was added in this commit Issue #3104877 by angela_G, chr.fritsch, volkerk: Replace jquery.ui.sortable with SortableJs, #3104877: Replace jquery.ui.sortable with SortableJs
Comment #6
tuuuukka commentedTested #4 again on a vanilla install of D9 and Select2 with no other modules installed, and the patch works (autocomplete, multivalue). Do you have any customization that might be interfering with it?
Removing forceFallback works, but it also requires you to first focus the element before you can drag anything in it. Plus it might cause some UI/UX issues on certain themes (although that's more of a theme related issue, but anyways).
Comment #7
recrit commented@Tuuuukka I do not have any customization to the Select2 element. The admin theme is Seven. With patch #4, I could still reproduce the bug as stated above.
Select2: 4.1.0-rc.0
For FireFox - it worked without having to focus the input. I was able to just dragged an item. I suspect its a timing issue with Select2 autofocus and Sortable draggable code.
For Chrome - I attempted to drag an item without focusing and it did not work. The focus was then auto set (i suspect Select2 is doing that). Then it works when attempting to drag again.
UPDATE:
I tested with the original code with
forceFallback: true,and had the same results in Chrome where you first have to focus (either directly or by clicking an item) before you can drag an item.So this suggests that forceFallback does not affect the focusing.
As stated in the docs https://github.com/SortableJS/Sortable#options:
"forceFallback: ignore the HTML5 DnD behaviour and force the fallback to kick in"
This affects DnD (Drag n Drop).
Comment #8
recrit commentedThe patch #4 makes sense to me to check if the index changed. The attached combines both patches - #4 and #5.
Comment #9
shivamitakari commentedI have tested the patch select2-check-indexes-3271205-8.patch and it works fine.
Comment #10
heatherwoz commentedAlso tested patch in #8 and it's working for us.
Comment #11
pawelgorski87 commentedselect2-check-indexes-3271205-8.patch
Working also on Drupal 10, thx
Comment #14
chr.fritschComment #16
himanshu rajI have tested the patch select2-check-indexes-3271205-8.patch on Drupal 9.5.2 with PHP 8.1 and the Select2 module.
Issue:
In multivalued entity reference fields with autocomplete, removing a selected option required multiple clicks.
After applying the patch:
Selected items are removed on the first click consistently.
Drag-and-drop sorting still works correctly.
No JavaScript or UX issues noticed in testing.
Marking as “Works for me.” Based on the results, this patch looks ready for RTBC (Reviewed and Tested by the Community).
Thanks to the contributors for resolving this frustrating usability bug.
Comment #17
avpaderno@himanshu This is a closed issue, and its merge request has been already merged.
There is no need to report the merge request works for you, since it has been already merged. What eventually could be done, in this case, is opening a new issue for any problem caused by this merge request.