开启showSearch后全选按钮仅作用于可见项,因隐藏项无DOM节点;需通过transfer.set({id:xxx,value:true})遍历原始数据手动设置选中状态。
transfer.render 中 showSearch 开启后,全选按钮失效的真相
默认开启 showsearch 后,layui 穿梭框的“全选”按钮(左栏顶部复选框)只对当前可见项生效——但搜索过滤后的隐藏项不会被纳入选中范围,用户点“全选”,实际只勾了没被过滤掉的那几条。这不是 bug,是设计逻辑:layui 的全选动作绑定在渲染后的 dom 节点上,而被 ishidden = true 的项根本没生成 checkbox 元素。
用 transfer.getData() + 手动设置 checked 状态绕过 DOM 限制
真正要实现“搜索后全选所有原始数据”,不能依赖界面按钮,得跳过 UI 层,直接操作数据源和组件状态:
-
transfer.getData()只返回右侧已选数据,不适用;要用transfer.config拿到初始化时传入的原始data数组 - 遍历原始数据,把每个
id显式调用transfer.set({id: xxx, value: true})(注意:value 是布尔值,不是字符串) - 必须在搜索触发后的回调里执行,比如监听
transfer.on('search')或在自定义搜索输入的keyup后延时处理
formSelects-v4 的 cumHandle 逻辑不能直接套用到 transfer
你看到的 cumHandle('product', formSelects) 是为 formSelects(第三方扩展)写的过滤修复,它重写了 filter 钩子并控制 isHidden 字段。但 transfer 组件没有公开的 filter 钩子,也没有 isHidden 的写入接口——它的过滤是纯 DOM 显示控制,无法通过 JS 数据标记干预。强行复制该逻辑会无效,甚至引发重复渲染异常。
最简可行方案:加一个自定义“全选原始数据”按钮
别改穿梭框原生全选行为,另起一个按钮更可控、更易维护:
layui.use(['transfer', 'jquery'], function(){
var transfer = layui.transfer, $ = layui.jquery;
var ins = transfer.render({
elem: '#test-transfer',
data: [{id:1,title:'A'},{id:2,title:'B'},...],
showSearch: true,
title: ['待选','已选']
});
// 自定义按钮点击事件
$('#btn-select-all-raw').on('click', function(){
var rawData = ins.config.data; // 拿到原始数据
$.each(rawData, function(i, item){
transfer.set({id: item.id, value: true});
});
});
});
这个方案不破坏原有交互,用户能明确区分“选当前显示”和“选全部原始项”,也避免了在搜索态下误操作导致数据错乱。
关键点在于:Layui 的 transfer 没有提供“搜索后全选原始集”的快捷 API,所有试图魔改内部过滤逻辑的尝试,都会撞上它不暴露数据过滤中间态的底层限制。


















