Look at the more_actions.js file, specifically the updateFormId() function.
const formId = form.getAttribute('id');
[...]
document.querySelector(`[data-drupal-selector="${formId}"] [data-drupal-selector="${buttonId}"]`).click();
[...]
The code assumes, that formId and data-drupal-selector are identical. Which they initially are.
However, after an Ajax triggered reload, they diverge.
In our local example, form #id and data-drupal-selector initially are "node-document-edit-form"
After Ajax, they are "node-document-edit-form--4fZYYVW-UEc" and "node-document-edit-form-4fZYYVW-UEc" respectively. Note the "--" vs "-" before the random String.
Under the hood, this in FormBuilder.php and Html::getUniqueId($unprocessed_id); vs Html::getId($element['#id'])
The former creates a "--", the latter reduces it to "-".
So, the code needs to either query by ID instead of data-drupal-selector, or get the selector by ID first, and then use that next.
| Comment | File | Size | Author |
|---|---|---|---|
| #6 | Screenshot_2025-01-30_13-53-37.png | 15.26 KB | christianadamski |
Issue fork gin-3503304
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:
- 3503304-more-actions
changes, plain diff MR !572
- 3503304-sticky-actions-fail
changes, plain diff MR !571
Comments
Comment #2
saschaeggiAs you reported this as being an issue on rc15, can you reproduce this issue on either stable release 3.0 or 4.0.2?
I'm pretty confident that we've fixed this in rc16+
Comment #3
christianadamski commentedThis is current 4.0.x:
https://git.drupalcode.org/project/gin/-/blob/4.0.x/js/more_actions.js?r...
formId is still directly used as selector for data-drupal-selector.
Comment #4
christianadamski commentedWant me to write an MR? If yes, what approach would you prefer?
Comment #5
saschaeggiYes, feel free to spin up a MR with a fix and adding steps how we can reproduce it!
The
idis being used which generally would be correct as it gets updated by thecontextobject in an Ajax request running through Drupal behaviors. In my short testing with an simple Ajax form this seems to work as expected and theidgets replaced with each Ajax call. But maybe your user case does not run through this function somehow.I've also quickly did spin up an vanilla instance on tugboat here: https://master-oipts4sjqrrbzlm2ezjy0rvvw0jnjxkj.tugboatqa.com/admin/stru...
(admin/admin) and if you change the "Allowed number of values" it sends an Ajax request and the id gets changed, Save gets the updated form id and form selector id.
Cheers!
Comment #6
christianadamski commentedWell, perfect example actually. See attached Screenshot of the tugboat install.
form ID and data-drupal-selector diverge after AJAX call. So the more-actions.js code does not apply anymore.
It seems however, that it is simply not executed here?
Comment #7
saschaeggiThanks for the clarification! Yes, this seems to be wrong.
Why the use case I was testing still works as expected: For that button to function correctly, the important part is what gets set on the submit button themselves. The
formattribute is referring to theidof the form and thedata-gin-sticky-form-selectoris referring to the the action being triggered (also an id). This seems to be correctly set. As this button doesn't have to rely on the additionalclick()event from JS as it can directly (natively) trigger theidwhich is defined in theformattribute on the button (that's an native HTML feature). That's why this still works as expected.So in a nutshell, if that's not the case for a form action the JS never gets triggered in the first place because of the
idanddata-drupal-selectorselector mismatch.If you can spin up an MR which changes the part within the
if (buttonSelector) {}to use[id="${formId}"]instead of[data-drupal-selector="${formId}"]this should be fixed.We might want to additionally exit the function when the
formattribute exists (and is a valid attribute) on the action and is available in the dom, but this could be done in a follow-up.Comment #8
christianadamski commentedFor which version? 4.0.x? And then run webpack dev? Anyway, tomorrow...
Comment #11
christianadamski commentedComment #13
christianadamski commentedI tested locally with 3.0-rc15 and transferred the changes manually. So didn't technically test 4.x, but the code is identical, so should be the same.
Comment #14
saschaeggiHey @christianadamski thanks for creating an MR, I left one comment 👀
Comment #15
christianadamski commentedOk, good to go I guess.
Comment #17
volkerk commentedUse once to add eventlistener for button sync. Added mousedown event in case of ajax buttons, see #3499408: custom ajax button not working anymore
Comment #18
volkerk commentedComment #19
miha.wagner commentedI can confirm that the patch with the addition of Volker's change restores AJAX button functionality.
Comment #20
saschaeggi@christianadamski can you confirm that the latest added changes still work in your case? Thank you
Comment #21
jurgenhaasRTBC +1
Comment #23
saschaeggiThanks! 👏
Released & included in 4.0.3
https://www.drupal.org/project/gin/releases/4.0.3