You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 03:28:17