Problem/Motivation
The widget stores the selection settings in the key value store and builds the route inside formElement, so custom code that alters a widget, for example in hook_field_widget_single_element_form_alter, cannot change the selection settings without repeating all of that, and other modules embedding the element carry the same boilerplate.
Steps to reproduce
- Alter the selection settings of a widget from a form alter.
- The stored settings and the route no longer match what was altered.
Proposed resolution
Move the key value storage and the route building into a #process callback of the element, so they run after alters and every user of the element gets them for free. The README examples for custom forms would then shrink to setting the selection settings.
Remaining tasks
- ✅ File an issue
- ❌ Addition/Change/Update/Fix
- ➖ Testing to ensure no regression
- ➖ Automated unit testing coverage
- ➖ Automated functional testing coverage
- ➖ UX/UI designer responsibilities
- ➖ Readability
- ➖ Accessibility
- ➖ Performance
- ➖ Security
- ➖ Developer Documentation
- ➖ User Guide Documentation
- ➖ Reviewed by human
- ➖ Code review by maintainers
- ➖ Full testing and approval
- ➖ Credit contributors
- ➖ Review with the product owner
- ➖ Release notes snippet
- ❌ Release
User interface changes
- N/A
API changes
- N/A
Data model changes
- N/A
Release notes snippet
- N/A
Issue fork autocomplete_deluxe-3532791
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
Comment #2
rajab natshahThank you, cyberwolf for laying it out.
Agreed on the direction: the element should own the storage and the route in a #process callback, so alters run first and the custom form wiring in the README, which today repeats exactly this code, collapses to setting the selection settings. It also relates to #3268207: Pass entity through AJAX request, where the entity is added beside those settings.
Leaving it active as the agreed direction, open for a merge request.
Comment #4
rajab natshahDone as suggested. Merge request against 2.1.x, pipeline green.
The element now puts the selection settings into the key value store and builds the path to the autocomplete route itself, in its process callback. The widget no longer does any of that.
Two things come out of it. Nothing placing the element has to know how the key is hashed or which route to name any more, and the two README examples each lost about fifteen lines of boilerplate. More to the point of this issue, an alter now actually takes effect, because a process callback runs after
hook_field_widget_single_element_form_alter().I wanted to be sure of that second claim rather than assume it, so I wrote a throwaway module that sets the match operator to
STARTS_WITHin that hook. With it enabled the settings key changes and typing "storm" returns nothing, which is correct since no term starts with those letters. With it disabled the key goes back and the same query returns the two terms that contain "storm". Before this change the widget had already hashed and stored the settings by the time the hook ran, so the alter did nothing whatsoever.Setting
#autocomplete_deluxe_pathyourself still works and still wins, so anything written against the older element carries on unaffected. The key value service also stays on the widget, unused, so code constructing it with the same arguments does not break.One detail worth your eye in review. The element's
#selection_settingscarries the entity being edited, which was added for #3268207, but the hash must not include it or the store would grow a key for every entity anyone edits. The new helper takes the entity out before hashing and storing, and the entity still reaches the controller through the query parameters. I checked that the key is identical on the add form and on the edit forms of two different nodes, and that the store held steady at two keys throughout.The one thing I have not done is add automated coverage. This is the widest reaching change of the batch and I have only verified it by hand, so it would be worth deciding together what shape a test for it should take before this goes in.
Prepared with AI assistance (Claude), reviewed and driven by the maintainer.
Comment #5
rajab natshahI said above that I had not added automated coverage for this one. That is done now, and the pipeline is still green.
There is a kernel test with four cases: the path names the route and the settings land in the store under the key it carries, the same settings give the same key so the store does not grow, the entity being edited changes neither the key nor what is stored, and altered settings give a different key, which is the point of this issue.
The third case is the one I care most about. If the entity is put back into the hash, that test fails, so the store cannot quietly start growing a key for every entity anyone opens without someone noticing.
Prepared with AI assistance (Claude), reviewed and driven by the maintainer.
Comment #7
rajab natshah