Include (data) attributes. E. g. in hx-include
For my understanding I need to generate hidden input tags to include 'fixed' or generated data (hyperscript, etc.) to a hx request.
What about including data attributes in the request? Maybe controllable with the hx-include attribute?
Try hx-vals which I think already does exactly what you are asking for. Hidden inputs are still a better option sometimes.
I fiddle around a lot and still think something like data-hx-key="value" would generate a request with { 'key': 'value' } would be a great option.
Especially when using rendering engines, generating JSON in an attribute is not that trivial (e. g. in GO).
For hx-get's if it is a static key value pair you can cheat and just use
<div hx-get="/load?key=value">content</div>
Which is very easy to template in the backend
agree on this, much cleaner than other workaroudns and hx-vals which feels super hacky
The potential gotcha with data attributes is the automatic camelcase conversion,
so data-hx-my-key="value" becomes myKey=value, which you may or may not be expecting.
To implement this yourself, you would do:
<script>
function hxDataAttrs(element) {
return Object.fromEntries(
Object.entries(element.dataset)
.filter( ([k,v]) => k.startsWith("hx") )
.map( ([k,v]) => [k[2].toLowerCase() + k.slice(3), v] )
)
}
</script>
<div hx-get="/blah" data-hx-my-key="value" hx-vals='js:{...hxDataAttrs(event.target)}'></div>
I was also looking for a solution for this. Did some googling and found this gist. Works well !
https://gist.github.com/sombriks/84ea02723623188c72b56060fdceeeb2
One problem with the idea of this is that all htmx attributes are allowed to be written as data attributes, so the following will work as a valid bit of htmx syntax (and you probably don't want to submit its value):
<a data-hx-post="/click">Click Me!</a>
If you want really wanted to do this, you could do it without using an extension:
document.addEventListener('htmx:configRequest', function(evt) {
Object.entries(evt.detail.elt.dataset)
// .filter( ([k,v]) => k.startsWith("hx") ) // optionally only add a subset of data attributes
// .map( ([k,v]) => [k[2].toLowerCase() + k.slice(3), v] ) // optionally make any case adjustments
.forEach( ([k,v]) => {
evt.detail.parameters[k] = v
})
});