Problem/Motivation
Pretty much like before 8.0.x in #2139921: Contextual links can't handle multiple occurrences of the same contextual links, contextual module does not support multiple contextual blocks with the same parameters, although it manifests a bit differently.
When the same content appears more than once on the same page, that content naturally has the same contextual links (specifically, exactly the same contextual links placeholder, e.g. <div data-contextual-id="foo:"></div>). Each contextual link should work correctly and act independently, of course.
However, that is not what happens. In the current codebase, when clicking one contextual link (by clicking on the pencil icon), it does not open. As observed in the chrome devtools, both links receive the event (flashes in the inspector), but none displays.
Steps to reproduce
- Create a render array in a controller
- Add a
#contextual_linkselement, pointing to some section with appropriate parameters - Add a child element within the top-level render array
- Within that element, add a similar
#contextual_linkselement, with the same parameters
Go to the page for that controller. The same contextual link now appears twice: once in the main content area, once in the other element further down. Click either contextual link. No contextual link menus will be opened.
Workaround
Add an unused extra route_parameter, with a different value in each element like ['instance' => 1] in the first one, ['instance' => 2] in the second one. The blocks will now work normally, and the links will only carry the extra unused parameter in the query.
This is pretty much how multiple pagers work.
Proposed resolution
Either:
- Fix this.
- Or document the workaround
| Comment | File | Size | Author |
|---|---|---|---|
| #37 | 2891603-8.9.x-37.patch | 12.42 KB | alexpott |
| #37 | 30-37-interdiff.txt | 1.18 KB | alexpott |
| #36 | 2891603-36.patch | 12.36 KB | alexpott |
| #30 | interdiff2730.txt | 4.28 KB | eiriksm |
| #30 | 2891603.patch | 12.72 KB | eiriksm |
Comments
Comment #2
fgmComment #3
fgmAdded reference to original issue.
Comment #5
Anonymous (not verified) commented@fgm, thanks for this issue and nice IS. Your workaround also works for me.
We can add key with random (or pseudorandom) value to
'route_parameters'in_contextual_id_to_links(). This will give us the guarantee of the uniqueness of any link. But many tests rely on the ability to predict link value.So here is another solution. This prevents binding of several javascript object with one html tag. Because the links cease to work due to the fact that when you click on them, several models immediately consider themselves the owners of the pencil icon :)
It seems this reason is also very suitable for #2834346: Contextual links double trigger.
Comment #7
Anonymous (not verified) commentedAnother related issue with a good description of the problem of binding objects.
Comment #8
drclaw commentedCould do it server-side as a counter which is a little more predictable for testing? Something like the attached patch? (testing disabled since we know it will break current tests)
Comment #9
Anonymous (not verified) commented@drclaw, thanks for the suggestion. But it seems to me that different id for the same contextual links is a good idea for the contrib module. When for some reason we need to implement different behavior to equal links. But for the core this logic is unnecessary complication.
We just need to eliminate the bug with multiple processing of links (js building links from web-cache, where the problem arises).
Comment #10
Anonymous (not verified) commentedHere is the detailed description:
Those, we need just set 1 to 1 relationship between model of contextual links and placeholders (like #5). Or just prevent duplication link ids in Session Storage.
Comment #13
Nik W commentedAny updates on this?
Still running into this issue...
Comment #14
grayle commentedReroll for 8.6.1
Comment #15
SriHarshaRavi commentedI was having the same issue and The patch in #5 fixed the issue for me.
Comment #16
grayle commentedReroll for 8.6.2
Comment #17
charlietoleary commentedHey guys,
I've patched this against 8.7.x tree.
I also changed the checks in the JS to use the eq() jQuery method: as this is better for modern browsers, as per jQuery docs (https://api.jquery.com/eq-selector/):
"Because :eq() is a jQuery extension and not part of the CSS specification, queries using :eq() cannot take advantage of the performance boost provided by the native DOM querySelectorAll() method. For better performance in modern browsers, use $("your-pure-css-selector").eq(index) instead."
Comment #19
charlietoleary commentedMy bad, missed a line in the tests.
Another Patch.
Comment #20
charlietoleary commentedElevating to major for visibility and also the original issue #2139921 was also marked major.
Comment #22
anonym-developer commentedAny updates here?
Comment #24
kerasai commentedNot sure I fully-grok the what/how/why of this approach. I've updated front-end approach in #2834346: Contextual links double trigger and it seems to be working.
If someone has a good explanation of the backend approach on this issue or has strong opinions about one over the other, I'd love to hear.
Comment #25
eiriksmTested the patch in #19, works great. Since we have a test-only patch that fails, and several has tested this solution to be OK, this should probably be marked as RTBC. But it has some coding standard errors in the test class, so here is an updated patch.
Comment #27
eiriksmLast patch had some leftover diff from another issue so ignore that.
It did however show a new test failure, so here is a new patch adressing that.
Comment #30
eiriksmOK, new try. Let's move the new test to a new class, so we dont mess up the existing tests :)
Comment #33
ocastle commentedPatch #30 tested on two sites and solves the issue for me on both. Great Stuff!
Comment #34
eiriksmIf you tested and reviewed the patch you might also consider changing the status of the issue to "reviewed and tested by the community"? :)
Comment #35
ocastle commentedRTBC
Comment #36
alexpottThe patch needed to be rerolled for JS tooling changes in 9.x - I applied #30 without patching core/modules/contextual/js/contextual.js. I then ran:
As this doesn't change any functionality, and in a better world we wouldn't commit core/modules/contextual/js/contextual.js anyway, leaving at rtbc
Comment #37
alexpottOh the 8.9.x patch fails the linting rules too...
So let's fix that too. Same yarn commands run on 8.9.x...
Comment #38
alexpottCommitted and pushed 0c74be7ae2 to 9.1.x and a1239b97e4 to 9.0.x. Thanks!
Committed 796e8dc and pushed to 8.9.x. Thanks!
Comment #42
nod_