如何使用htmx从非input元素获取值并随请求发送?
如何在htmx请求中包含按钮文本或非input元素的内容?
问题背景
htmx官方有这样的示例,能把input字段的值包含到发送到/register的请求里:
<div> <button hx-post="/register" name='button_name' hx-include="[name='email']"> Register! </button> Enter email: <input name="email" type="email"/> </div>
我想把按钮里的文本“Register!”也一起发过去,试了hx-include="[name='button_name']"但没用,发现hx-include只对input这类表单元素生效。现在连<p>这类普通元素的文本都不知道怎么随请求发送,求解决办法。
解决思路
试试这几个实用方法:
1. 用隐藏input同步内容
在按钮旁边加个hidden类型的input,把按钮文本同步到这个input里,这样hx-include就能正常捕获它的值了:
<div> <button hx-post="/register" name='button_name' hx-include="[name='email'],[name='button_text']" hx-on:click="this.nextElementSibling.value = this.textContent.trim()"> Register! </button> <input type="hidden" name="button_text" value="Register!"> Enter email: <input name="email" type="email"/> </div>
这里用htmx的hx-on:click事件同步文本,也可以用原生onclick,效果一样。
2. 拦截请求直接添加参数
用htmx的htmx:beforeRequest事件,直接往请求参数里塞自定义数据,不用额外加DOM元素:
<div> <button hx-post="/register" name='button_name' hx-include="[name='email']" hx-on::beforeRequest="event.detail.parameters.button_text = this.textContent.trim()"> Register! </button> Enter email: <input name="email" type="email"/> </div>
这个方法最简洁,直接在请求发送前修改参数,适合单次使用的场景。
3. 自定义扩展(全局复用)
如果多个地方都需要这种需求,可以写个简单的htmx扩展,自动收集指定元素的文本:
htmx.defineExtension('include-text', { onEvent: function(name, evt) { if (name === "htmx:beforeRequest") { const elem = evt.detail.elt; const targets = elem.getAttribute('hx-include-text'); if (targets) { document.querySelectorAll(targets).forEach(el => { const paramName = el.getAttribute('data-param-name'); evt.detail.parameters[paramName] = el.textContent.trim(); }); } } } });
使用的时候只需要给元素加对应的属性:
<div> <button hx-post="/register" hx-include="[name='email']" hx-ext="include-text" hx-include-text="[data-param-name='button_text']" data-param-name="button_text"> Register! </button> Enter email: <input name="email" type="email"/> </div>
这个扩展还能用来收集<p>、<div>等其他元素的文本,只要给目标元素加data-param-name指定参数名就行。
内容的提问来源于stack exchange,提问作者vushne
相关产品推荐
相关产品推荐

