如何在HTML <td>标签中用jQuery实现动态下拉列表及select替代方案
现有datalist实现的问题与修正
当前代码存在两处会直接导致功能失效的问题:
- HTML结构不合法:按照标准规范,
datalist是与input同级的独立附属元素,不能嵌套在input标签内部。这种嵌套写法会让浏览器解析时直接丢弃datalist节点,最终下拉列表完全无法触发。 - 模板绑定无效:Odoo模板的
t-att-*属性仅会在最终渲染为真实DOM的标签上生效,写在循环用的t节点上的t-att-value不会传递到最终生成的option元素上,属于无效绑定。
修正后的可运行datalist代码如下:
<td> <input list="parameters" name="health_parameter" class="form-control textclass" t-att-value="vi.parameter_id.parameter_name" readonly="true" > <datalist id="parameters"> <t t-foreach="health_parameter" t-as="parameter"> <option t-att-value="parameter.parameter_name" t-att-data-parameter-id="parameter.id" > <t t-esc="parameter.parameter_name"/> </option> </t> </datalist> </td>
使用datalist方案需要注意:原生datalist的选中值为option的value属性,因此需要将option的value设置为与input显示值匹配的参数名称,将对应的参数ID存在自定义属性中。后续提交数据时,通过监听input的change事件,匹配选中名称对应的参数ID,即可完成数据更新逻辑。
原生select控件的直接实现方案
完全可以直接使用select控件实现稳定的下拉选择能力,这类枚举值选择场景本身就是select的标准适用场景,相比datalist不需要额外做值映射处理:
- 相比datalist方案的优势
- 表单提交时直接携带选中项的参数ID,无需额外JS做值转换
- 不存在不同浏览器对datalist的渲染差异,下拉交互行为完全统一
- 选中状态与数据源的匹配逻辑更直接,能减少状态不同步的bug
- 可直接复用的实现代码:
<td> <select name="health_parameter" class="form-control textclass" t-att-value="vi.parameter_id.id" > <option value="">-- 请选择健康指标 --</option> <t t-foreach="health_parameter" t-as="parameter"> <option t-att-value="parameter.id" t-att-selected="vi.parameter_id.id == parameter.id ? 'selected' : false" > <t t-esc="parameter.parameter_name"/> </option> </t> </select> </td>
实现时的注意事项:
- 不需要给select加readonly属性,如果需要对齐原有readonly input的禁止随意编辑的效果,可以通过
disabled属性做状态控制 - 所有
t-att-*类的属性绑定,都要写在最终生成真实DOM的option标签上,不要写在循环用的t节点上,否则属性不会被正常渲染 - 如果后续需要给下拉增加搜索过滤能力,可以基于原生select叠加轻量前端组件,不需要替换底层表单结构,能够和现有数据更新逻辑完全打通。
内容的提问来源于stack exchange,提问作者Raihan
相关产品推荐
相关产品推荐

