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

实现多Part中多选分类选项的互斥禁用功能

解决方案

核心实现逻辑

  • 用对象跟踪已选中的分类,记录每个分类被哪个Part选中
  • 监听多选框的变化事件,实时更新选中状态
  • 遍历所有Part的分类选项,根据选中状态同步设置禁用/启用,并刷新插件使状态生效

修改后的完整代码

<body>
<div class="modal-body flex flex-col">
   <div>
      <label for="part_input">How many part do you want?</label>
      <input class="rounded-md mx-3" type="number" name="input" id="input" min="1"
                max="10" style="height: 30px;width: 100px" placeholder="e.g. 1" required>
      <button type="submit" id="generateFields" class="bg-blue-500 rounded"
                style="width: 80px; height: 30px;">Enter</button>
   </div>
   <form method="POST" action="">
      <div id="partContainer"></div>
         <div class="float-right mt-4" id="buttons" style="display: none">
            <button type="button" class="bg-blue-400 rounded hover:bg-blue-300"
                        style="width: 100px">Create</button>
            <button data-dismiss="modal" class="border bg-white rounded hover:bg-gray-100"
                        style="width: 100px; margin-left:10px">Cancel</button>
         </div>
   </form>
</div>
</body>

<script>
document.addEventListener("DOMContentLoaded", function() {
    const generateButton = document.getElementById("generateFields");
    const partContainer = document.getElementById("partContainer");
    const buttonsDiv = document.getElementById('buttons');
    // 存储已选中的分类:key为分类文本,value为选中它的Part编号
    const selectedCategories = {};

    // 更新所有Part的选项禁用状态
    function updateCategoryDisabledStates() {
        document.querySelectorAll('.categorySelect').forEach(select => {
            const partNumber = select.id.replace('category_id', '');
            select.querySelectorAll('option').forEach(option => {
                const categoryText = option.textContent.trim();
                // 若该分类被其他Part选中,禁用当前选项
                if (selectedCategories[categoryText] && selectedCategories[categoryText] !== partNumber) {
                    option.disabled = true;
                } else {
                    option.disabled = false;
                }
            });
            // 刷新插件,让禁用状态生效
            $(select).filterMultiSelect('refresh');
        });
    }

    generateButton.addEventListener("click", function() {
        const numberOfParts = parseInt(document.getElementById('input').value);

        if (numberOfParts >= 1 && numberOfParts <= 10) {
            partContainer.innerHTML = "";
            // 清空上一轮的选中记录
            Object.keys(selectedCategories).forEach(key => delete selectedCategories[key]);
 
            for (let i = 1; i <= numberOfParts; i++) {
                const partDiv = document.createElement("div");
                partDiv.innerHTML = `
                    <h4 style="font-size:20px; margin-top:25px"><b>Part ${i}</b></h4>
                    <div class="flex items-center">
                        <label for="partName${i}" class="w-32 pr-2 mt-4">Name</label>
                        <input class="rounded-md" type="text" name="part_name${i}" id="part_name${i}" placeholder="Name"
                            style="height: 30px; margin:15px 0px 0px 20px;width:175px;" required>
                    </div>
                    <div class="flex items-center">
                        <label for="partAmount${i}" class="w-32 pr-2 mt-4">Amount</label>
                        <input class="rounded-md" type="number" step="0.01" name="allocation_amount${i}" id="allocation_amount${i}" placeholder="0.00"
                            style="height: 30px; margin:15px 0px 0px 20px;text-align:right;width:175px;" required>
                    </div>
                    <div class="flex">
                        <label for="partCategory${i}" class="w-32 pr-2 mt-4">Category</label>
                        <select class="rounded-md categorySelect"  name="category_id${i}" id="category_id${i}" multiple
                            required>
                            <option name="category_id${i}[]" value="1" data-part="${i}">
                                    Food & drink
                                </option>
                                <option name="category_id${i}[]" value="2" data-part="${i}">
                                    Shopping
                                </option>
                                <option name="category_id${i}[]" value="3" data-part="${i}">
                                    Income
                                </option>
                                <option name="category_id${i}[]" value="4" data-part="${i}">
                                    Travel
                                </option>
                                <option name="category_id${i}[]" value="5" data-part="${i}">
                                    Housing
                                </option>
                        </select>
                    </div>
                `;

                partContainer.appendChild(partDiv);

                // 初始化filterMultiSelect插件
                const $select = $('#category_id' + i).filterMultiSelect({
                    placeholderText: "Please select",
                });

                // 监听选项变化事件
                $select.on('change', function() {
                    const partNumber = $(this).attr('id').replace('category_id', '');
                    // 获取当前选中的所有分类文本
                    const selectedTexts = $(this).find('option:selected').map(function() {
                        return $(this).text().trim();
                    }).get();

                    // 移除当前Part之前的选中记录
                    Object.keys(selectedCategories).forEach(key => {
                        if (selectedCategories[key] === partNumber) {
                            delete selectedCategories[key];
                        }
                    });
                    // 添加当前选中的分类记录
                    selectedTexts.forEach(text => {
                        selectedCategories[text] = partNumber;
                    });

                    // 更新所有Part的选项状态
                    updateCategoryDisabledStates();
                });
            }
            buttonsDiv.style.display = "block";
        }
    });
});
</script>

关键修改说明

  1. 选中状态管理:新增selectedCategories对象,确保同一分类只能被一个Part占用。
  2. 状态同步函数:updateCategoryDisabledStates遍历所有选项,根据选中记录设置禁用状态,并调用插件的refresh方法更新UI。
  3. 事件监听:为每个多选框添加change事件,实时更新选中记录并触发状态同步。
  4. 选项值修正:将原代码中重复的选项值改为唯一标识(实际场景中替换为真实分类ID即可)。

内容的提问来源于stack exchange,提问作者user16045271

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 10:54:56