unpoly
unpoly copied to clipboard
Watching fields requires multiple-values checkboxes to have a `[]` name suffix
Bug description
I have a list of checkboxes. The HTML is a bit messy (generated by Django) but there's some sort of dependence between the checkboxes which leads to Unpoly not always getting triggered.
Reproduction project
https://codepen.io/dsfsdfa/pen/gOyWYVv
Steps to reproduce the behavior:
- Go to reproduction project linked above
- Open console
- Click on "Won't do"
- Click on any of the checkboxes before "Won't do"
Once "Won't do" is checked, checking the other checkboxes doesn't trigger a submit event
If you uncheck "Won't do", the checkboxes before it work as expected.
Expected behavior
All checkboxes should trigger an autosubmit whenever they're checked/unchecked.
Browser version
- OS: [e.g. Mac OS]
- Browser [e.g. Chrome]
- Version [e.g. Unpoly 3.7.1 and 3.7.3]
Unpoly autosubmits the form when the form's params ("form data") changes.
The checkboxes have the same [name]
. The last checked checkbox with a given name is the one that goes into params. Hence checking other boxes before "Won't do" does not change the form's params.
You can use different names, or radio buttons.
Unpoly autosubmits the form when the form's params ("form data") changes.
The checkboxes have the same
[name]
. The last checked checkbox with a given name is the one that goes into params. Hence checking other boxes before "Won't do" does not change the form's params.You can use different names, or radio buttons.
It's a multiple-choice checkbox. I think that's the way those are typically rendered into HTML by both rails and django forms but I'll see if I can solve it some other way. Thanks for the help!
It's a multiple-choice checkbox.
The [name]
of a multiple choice checkbox usually ends with a []
to signify to the browser and server that there are multiple values attached.
ex.
<input type="checkbox" name="status[]">
The last checked checkbox with a given name is the one that goes into params.
I didn't say this correctly. This will work for keys with an []
suffix, as @adam12 mentioned. Here is a fork of @davisums' CodePen that changes the [name]
to "status[]"
: https://codepen.io/triskweline/pen/rNbwMLj
The []
suffix is a convention shared by many, but not all web frameworks. There is no web standard for it AFAIK.
It would technically be possible to detect multi-selects without that suffix. However doing this would somewhat complicate the callback signature of up.watch()
and [up-watch]
. In particular the oldValue
and newValue
arguments would always need to be arrays, for the rare case that we're dealing with a multi-select field.
I had wanted to test if it would work with brackets. Thanks for pointing that out.
My first solution was to use Alpine for autosubmit (since it's already a dependency on this project) but I ended going with this instead on Django:
post = request.POST.copy()
post.setlist("status", request.POST.getlist("status[]"))
form = FilterForm(post)
Since I don't want to use the form object to generate the HTML, this works fine in this case.
Would it be possible to add an 'up-multivalue-fields="status, xyz"' attribute to the form tag (or maybe on the inputs directly) to help unpoly out while keeping the signatures of up.watch()
etc? This would help frameworks where the []
suffix is not used.
Would it be possible to add an 'up-multivalue-fields="status, xyz"' attribute to the form tag (or maybe on the inputs directly) to help unpoly out while keeping the signatures of up.watch() etc? This would help frameworks where the [] suffix is not used.
Also thinking about a global setting that would declare all fields to be multi-value. E.g.
up.form.config.arrayFields = 'suffix' # or 'all'
Setting this to 'all'
would always pass an array value
for up.watch()
or [up-watch]
. Since it's a manual setting, this would not be a breaking change.
Medium-term we may need a breaking change for value
, as Unpoly manually parsing form fields is incompatible with modern ways to author custom form fields (formdata
event, form-associated custom elements with attachInternals()
).
That would probably be the least invasive patch for now :+1: