实现两个select list box间item的移动和过滤

本文介绍了一个使用jQuery实现的列表筛选功能,并通过双击或按钮操作完成列表项的拖拽转移。该功能包括输入框实时过滤选项、取消按钮清空筛选条件等特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<head>
    <title>
    </title>    
    <!--Standard jQuery -->
    <script type="text/javascript" src="https://code.jquery.com/jquery-git2.js" charset="utf-8"></script>
    <script type="text/javascript">
        $(document).ready(function()
        {
            $('#boxClear').click(function(){
                $('#firstFilterSearch').val('');
            });

            $('#firstFilterSearch').keyup(function()
            {
                var searchArea = $('#firstList');
                searchFirstList($(this).val(), searchArea);
            });

            $('#firstList').dblclick(function() {
                assignList();
            });

            $('#secondList').dblclick(function() {
                unassignList();
            });

            $('#to2').click(function()
            {
                assignList();
            });

            $('#to1').click(function()
            {
                unassignList();
            });
        });
            
        // Function for Filtering
        function searchFirstList(inputVal, searchArea)
        {
            var allCells = $(searchArea).find('option');
            if(allCells.length > 0)
            {
                var found = false;
                allCells.each(function(index, option)
                {
                    var regExp = new RegExp(inputVal, 'i');
                    if(regExp.test($(option).text()))
                    {
                        $(option).show();
                    }
                    else
                    {
                        $(option).hide();
                    }
                });
            }
        }

        // function: UnAssignment
        function assignList()
        {
            $('#firstList :selected').each(function(i, selected){
                // append to second list box
                $('#secondList').append('<option value="'+selected.value+'">'+ selected.text+'</option>');
                // remove from first list box
                $("#firstList option[value='"+ selected.value +"']").remove();
            });
        }
        // function: UnAssignment
        function unassignList()
        {
            $('#secondList :selected').each(function(i, selected){
                // append to first list box
                $('#firstList').append('<option value="'+selected.value+'">'+ selected.text+'</option>');
                // remove from second list box
                $("#secondList option[value='"+ selected.value +"']").remove();
            });
        }
    </script>
</head>
<body>
<table border="0" cellpadding="0" cellspacing="0" width="100%">    
    <tr>        
        <td width="100%">
            <form id="frm_format" method="" action="">
            <table cellpadding="0" id="tbl_format"cellspacing="0" border="0" width="100%" class="standard_table_v4">    
                <thead>
                </thead>
                <tbody>
                    <tr>
                        <td>
                        <td align="center">
                            Filter: <input id="firstFilterSearch" type="text">
                                    <input type="button" id="boxClear" name="boxClear" value="Cancel"><br>
                            <select id="firstList" multiple="multiple" style="height:420px;width: 250px;" >    
                                <option value="1">PHP</option>
                                <option value="2">.Net</option>
                                <option value="3">Copy</option>
                                <option value="4">Paste</option>
                                <option value="5">Pea</option>
                                <option value="6">Pamp</option>
                                <option value="7">ladaku</option>
                                <option value="8">Zebra</option>
                            </select>
                        </td>
                        <td align="center">
                            <input id="to2" type="button" name="to2"  title='assign' value=">" /><br/><br/>
                            <input id="to1" type="button" name="to1" title='unassign' value="<">
                        </td>
                        <td>
                            <select id="secondList" multiple="multiple" style="height:420px;width: 250px;" >
                            </select>
                        </td>
                    </tr>
                </tbody>
            </table>
            </form>
            
        </td>
    </tr>
</table>
</body>
</html>

 

转载于:https://www.cnblogs.com/dereklovecc/p/3998698.html

import React, { useState } from 'react'; import './DualListBox.less'; // 引入 LESS 样式 const DualListBox = ({ initialLeft = [], initialRight = [] }) => { // 状态管理 const [leftItems, setLeftItems] = useState(initialLeft); const [rightItems, setRightItems] = useState(initialRight); const [selectedLeft, setSelectedLeft] = useState([]); const [selectedRight, setSelectedRight] = useState([]); // 通用选择逻辑 const handleSelect = (selected, setSelected, item) => { const newSelected = selected.includes(item) ? selected.filter(i => i !== item) : [...selected, item]; setSelected(newSelected); }; // 移动项逻辑 const moveItems = (source, setSource, target, setTarget, selected) => { setSource(source.filter(item => !selected.includes(item))); setTarget([...target, ...selected]); }; return ( <div className="container"> {/* 左侧列表 */} <div className="list-container"> <select multiple className="list-box" onMouseDown={(e) => e.preventDefault()} // 防止默认选中行为 > {leftItems.map((item) => ( <option key={item} className={selectedLeft.includes(item) ? 'selected' : ''} onClick={() => handleSelect(selectedLeft, setSelectedLeft, item)} > {item} </option> ))} </select> </div> {/* 操作按钮组 */} <div className="button-group"> <button onClick={() => moveItems( leftItems, setLeftItems, rightItems, setRightItems, selectedLeft )} > > </button> <button onClick={() => moveItems( rightItems, setRightItems, leftItems, setLeftItems, selectedRight )} > < </button> </div> {/* 右侧列表 */} <div className="list-container"> <select multiple className="list-box" onMouseDown={(e) => e.preventDefault()} > {rightItems.map((item) => ( <option key={item} className={selectedRight.includes(item) ? 'selected' : ''} onClick={() => handleSelect(selectedRight, setSelectedRight, item)} > {item} </option> ))} </select> </div> </div> ); }; export default DualListBox;
03-31
<template> <div class="transfer-container"> <!-- 左侧表格 --> <div class="table-container"> <div class="header-box"> <span>设备列表</span> <span class="checkAll" @click="checkAll">全选</span> </div> <div class="select-box"> <div class="select-item"> <span>{{ $t('主机型号:') }}</span> <a-select v-model="hostModel" @change="changeSelect" :placeholder="$t('请选择主机型号')" allowClear> <a-select-option v-for="item in periodList" :key="item.id" :value="item.itemDesc" :title="item.itemName"> {{ item.itemName }} </a-select-option> </a-select> </div> <div class="select-item"> <span>{{ $t('组织名称:') }}</span> <org-tree-select @treeSelect="orgTreeSelect"></org-tree-select> </div> </div> <!-- 左侧列表 --> <div class="list-container"> <div v-for="item in leftData" :key="item.personId" class="list-item"> <a-checkbox v-model="item.checked" :disabled="item.deviceOnOffLine == 0 || item.configStatus == 1" class="checkbox" ></a-checkbox> <div class="device-box"> <div class="top-info"> <span>{{ item.deviceName }}</span> <span v-show="item.configStatus == 1" @click="openTask(item)"> <hd-icon type="files" /> {{ $t('已配任务') }} </span> </div> <div class="bottom-info"> <span>{{ $t('探测器信息:') }}</span> <span>{{ item.detectorName }} </span> | <span>{{ item.productModel }} </span> | <span>{{ item.detectorUniqueCode }} </span> </div> </div> </div> <a-empty v-show="leftData.length === 0" /> </div> <div v-if="leftData.length" class="pagination"> <a-pagination simple :defaultCurrent="pagination.currentPage" :total="pagination.totalRows" @change="changePage" /> </div> </div> <!-- 中操作按钮 --> <div class="transfer-actions"> <a-button type="primary" icon="right" :disabled="selectedLeft.length === 0" @click="moveToRight"> </a-button> </div> <!-- 右侧表格 --> <div class="table-container right-content"> <div class="header-box"> <span>{{ $t('已选择列表') + '(' + rightData.length + ')' }}</span> <a-button type="primary" :disabled="rightData.length === 0" @click="clearAll"> 清除 </a-button> </div> <div class="list-container"> <div v-for="item in rightData" :key="item.personId" class="list-item right-list"> <div class="device-box"> <div class="top-info"> <span>{{ item.deviceName }}</span> <div>{{ item.detectorOwnerName }}</div> <span v-show="item.configStatus == 1" @click="openTask(item)"> <hd-icon type="files" /> {{ $t('已配任务') }} </span> </div> <div class="bottom-info"> <span>{{ $t('探测器信息:') }}</span> <span>{{ item.detectorName }} </span> | <span>{{ item.productModel }} </span> | <span>{{ item.detectorUniqueCode }} </span> </div> </div> <img src="@/assets/img/icon-remove.png" @click="moveToLeft(item)" alt="" /> </div> <a-empty v-show="rightData.length === 0" /> </div> </div> <!-- 定时任务已存在 --> <myModal :params="{ title: $t('已配置任务列表'), showFooter: false }" :visible="visible" @cancel="visible = false" destroyOnClose > <template v-slot:header><span></span></template> <template v-slot:body> <div class="table_title"> {{ $t('探测名称') }} </div> <a-table :columns="detailColumns" :scroll="{ x: '100%', y: 400 }" :dataSource="detailData" row-key="id" :pagination="false" > </a-table> </template> </myModal> </div> </template> <script> import factory from '../factory' import myModal from '@/components/scfComponents/modalComponents/modal.vue' import orgTreeSelect from '@/components/orgTreeSelect/orgTreeSelect' export default { components: { myModal, orgTreeSelect }, data() { return { visible: false, // 弹窗 periodList: [], // 主机型号列表 orgData: {}, // 组织树数据 leftData: [], // 左侧表格数据 rightData: [], // 右侧表格数据 pagination: { pageSize: 10, currentPage: 1, totalRows: 0, }, // 分页 // 已配任务列表表头 detailColumns: [ { title: this.$t('日期'), dataIndex: 'date', ellipsis: true, }, { title: this.$t('时'), dataIndex: 'executeTime', ellipsis: true, }, { title: this.$t('空开操作'), dataIndex: 'operation', ellipsis: true, }, ], // 已配任务列表数据 detailData: [], } }, computed: { // 选中左侧列表 selectedLeft() { return this.leftData.filter(item => item.checked) }, }, mounted() { this.getDic() // 初始化数据 this.leftData = [] this.rightData = [] }, methods: { // 主机型号列表 getDic() { factory.getDic(1080).then(res => { this.periodList = res }) }, // 获取左侧表格数据 getLeftTableData() { let params = { page: this.pagination.currentPage, orgCodes: [this.orgData.orgCode], productModel: this.hostModel, } factory.getBatchDetector(params).then(res => { if (res.success) { this.leftData = res.data.map(item => ({ ...item, checked: false })) || [] // 如果右侧存在数据需要把数据过滤一下 if (this.rightData.length > 0) { let ids = this.rightData.map(item => item.id) this.leftData = this.leftData.filter(item => !ids.includes(item.id)) } } }) }, // 查询已存在空开定时任务 getDetectorJob(record) { factory.getDetectorJob(record.jobId).then(res => { if (res.success) { this.detailData = res.data.map(item => { item.detectorName = record.detectorName || '' item.weekList = this.getActiveWeeks(item.rept) return item }) || [] } }) }, // 主机型号 changeSelect(value) { if (value && Object.keys(this.orgData).length > 0) { this.getLeftTableData() } else { this.leftData = [] } }, getActiveWeeks(rept) { const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'] const pattern = rept.split('') return pattern .map((char, index) => (char == '1' ? weekDays[index] : null)) .filter(Boolean) .join('、') }, // 组织树节点选择 orgTreeSelect(node) { this.orgData = node if (this.hostModel && Object.keys(this.orgData).length > 0) { this.getLeftTableData() } else { this.leftData = [] } }, // 全选 checkAll() { if (this.leftData.length === 0) return this.leftData.forEach(item => { if (item.deviceOnOffLine == 1 && item.configStatus == 0) { item.checked = true } }) }, // 清除 clearAll() { const newLeft = [...this.leftData] this.rightData.forEach(rightItem => { if (!newLeft.some(leftItem => leftItem.id == rightItem.id)) { newLeft.push({ ...rightItem, checked: false }) } }) this.leftData = newLeft this.rightData = [] }, // 向右移动选中项 moveToRight() { this.rightData = [...this.rightData, ...this.selectedLeft] this.leftData = this.leftData.filter(item => !this.selectedLeft.some(i => i.id === item.id)) }, // 向左移动单个项 moveToLeft(item) { this.rightData = this.rightData.filter(i => i.id !== item.id) this.leftData = [...this.leftData, { ...item, checked: false }] }, // 打开已配置任务列表 openTask(record) { this.visible = true this.getDetectorJob(record) }, }, } </script> <style lang="less" scoped> .transfer-container { width: 100%; display: flex; justify-content: space-around; box-sizing: border-box; } .table-container { width: 48%; height: 100%; position: relative; font-family: '微软雅黑'; font-weight: 400; border: 1px solid #ebedef; .header-box { height: 46px; width: 100%; display: flex; align-items: center; padding: 0 16px; border-bottom: 1px solid rgb(229, 231, 234); background: rgb(242, 243, 244); justify-content: space-between; color: rgb(21, 23, 26); font-size: 14px; font-weight: 700; .checkAll { cursor: pointer; color: rgb(41, 141, 255); } } .select-box { display: flex; height: 64px; padding: 0 20px; align-items: center; .select-item { margin-right: 24px; color: rgb(157, 166, 177); > span:first-child { margin-right: 5px; } } } .list-container { padding: 0 20px; height: 392px; overflow-y: scroll; .list-item { height: 74px; display: flex; align-items: center; .device-box { margin-left: 16px; .top-info { display: flex; align-items: center; span { cursor: pointer; color: #298dff; font-size: 14px; } div { height: 24px; border-radius: 2px; font-size: 12px; display: flex; cursor: default; margin-right: 24px; align-items: center; padding: 0 8px; color: rgb(66, 75, 86); background: rgb(236, 238, 240); } span:first-child { color: rgb(21, 23, 26); font-size: 16px; cursor: default; margin-right: 24px; } } .bottom-info { color: rgb(105, 118, 136); font-size: 14px; > span { margin: 0 5px; } } } } } .pagination { display: flex; height: 58px; align-items: center; justify-content: flex-end; } } .right-content { .device-box { margin: 0; } .list-container { height: 514px; .list-item { justify-content: space-between; .device-box { margin: 0; } img { width: 20px; height: 20px; display: inline-block; } } } } .transfer-actions { margin-top: 56px; display: flex; flex-direction: column; justify-content: center; } </style> 代码评审
最新发布
08-02
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值