如何在Odoo 17中使用Owl JavaScript实现多选选项功能
解决方案:Owl框架下实现带删除功能的多选选择器
一、替换HTML结构
把原生单选<select>改成支持多选标签的结构,同时保留表单提交所需的隐藏字段:
<div class="col-6"> <div class="col-auto"> <label class="col-form-label">状态</label> </div> <div class="col-auto"> <!-- 已选标签展示区 --> <div class="selected-tags d-flex flex-wrap gap-2 mb-2"> <!-- 标签由Owl动态渲染 --> </div> <!-- 选择下拉框 --> <select class="form-select" id="status-select"> <option value="">-- 选择状态 --</option> <option value="draft">草稿</option> <option value="to_approve">待审批</option> <option value="approved">已审批</option> <option value="cancel">取消</option> </select> <!-- 用于表单提交的隐藏字段,存储选中值的逗号分隔字符串 --> <input type="hidden" name="status" id="status-hidden"> </div> </div>
二、编写Owl组件逻辑
基于Owl的状态管理和事件处理,实现选择、添加、删除标签的功能:
import { Component, useState } from '@odoo/owl'; export class MultiStatusSelector extends Component { static template = ` <div class="col-6"> <div class="col-auto"> <label class="col-form-label">状态</label> </div> <div class="col-auto"> <div class="selected-tags d-flex flex-wrap gap-2 mb-2"> <span t-foreach="state.selected" t-as="item" t-key="item.value" class="badge bg-primary d-flex align-items-center gap-1 px-2 py-1"> <span t-esc="item.label"></span> <button type="button" class="btn-close btn-close-sm" t-on-click="() => removeTag(item.value)"></button> </span> </div> <select class="form-select" t-on-change="handleSelect"> <option value="">-- 选择状态 --</option> <option value="draft">草稿</option> <option value="to_approve">待审批</option> <option value="approved">已审批</option> <option value="cancel">取消</option> </select> <input type="hidden" name="status" t-value="state.selected.map(i => i.value).join(',')"> </div> </div> `; setup() { // 初始化状态:已选列表和选项列表 this.state = useState({ selected: [], options: [ { value: 'draft', label: '草稿' }, { value: 'to_approve', label: '待审批' }, { value: 'approved', label: '已审批' }, { value: 'cancel', label: '取消' }, ] }); } // 处理下拉选择事件 handleSelect(e) { const val = e.target.value; if (!val) return; // 避免重复添加 if (this.state.selected.some(item => item.value === val)) { e.target.value = ''; return; } // 找到对应选项并添加到已选列表 const option = this.state.options.find(opt => opt.value === val); if (option) { this.state.selected.push(option); e.target.value = ''; // 重置下拉框 } } // 删除已选标签 removeTag(value) { this.state.selected = this.state.selected.filter(item => item.value !== value); } }
三、挂载组件到页面
在你的页面入口脚本中,挂载这个Owl组件:
import { mount } from '@odoo/owl'; import { MultiStatusSelector } from './your-component-file.js'; // 替换成你要挂载的容器ID mount(MultiStatusSelector, document.getElementById('search-container'));
关键说明
- 用Owl的
useState管理已选状态,状态变化会自动触发视图更新 - 已选标签用Bootstrap的
badge样式,点击关闭按钮即可删除对应项 - 隐藏字段会自动将选中值拼接成逗号分隔的字符串,表单提交时后端可以直接解析
- 做了重复选择的校验,避免同一状态被多次添加
内容的提问来源于stack exchange,提问作者Cris Tuan
相关产品推荐
相关产品推荐

