From e5aa6c3a877713ca65007b85191d01c864001d04 Mon Sep 17 00:00:00 2001 From: morning-star <1453017105@qq.com> Date: Tue, 26 Dec 2023 22:32:10 +0800 Subject: [PATCH] =?UTF-8?q?feat(transfer):=20=E6=96=B0=E5=A2=9E=20`dblclic?= =?UTF-8?q?k`=20=E9=80=89=E9=A1=B9=20(#1491)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(transfer): 新增 `dblclick` 选项 * style(transfer): 优化代码书写风格 --------- Co-authored-by: 贤心 <3277200+sentsim@users.noreply.github.com> --- docs/transfer/detail/options.md | 24 ++++ src/modules/transfer.js | 240 +++++++++++++++++--------------- 2 files changed, 150 insertions(+), 114 deletions(-) diff --git a/docs/transfer/detail/options.md b/docs/transfer/detail/options.md index c35fd62e..71ee758f 100644 --- a/docs/transfer/detail/options.md +++ b/docs/transfer/detail/options.md @@ -163,6 +163,30 @@ onchange: function(data, index){ `false` + + + +dblclick 2.9.3+ + + +双击时的回调函数。返回的参数如下: + +``` +dblclick: function(obj){ + console.log(obj.elem); // 点击的元素 + console.log(obj.data); // 得到点击项的数据 + console.log(obj.index); // 如果数据来自左边,index 为 0,否则为 1 + + return false // 返回 false 会阻止穿梭 +} +``` + + +function + + + `null` + diff --git a/src/modules/transfer.js b/src/modules/transfer.js index 844e4332..200eb283 100644 --- a/src/modules/transfer.js +++ b/src/modules/transfer.js @@ -73,39 +73,39 @@ layui.define(['laytpl', 'form'], function(exports){ // 穿梭框模板 var TPL_BOX = function(obj){ obj = obj || {}; - return ['
' - ,'
' - ,'' - ,'
' - ,'{{# if(d.data.showSearch){ }}' - ,'' - ,'{{# } }}' - ,'' - ,'
'].join(''); + return ['
', + '
', + '', + '
', + '{{# if(d.data.showSearch){ }}', + '', + '{{# } }}', + '', + '
'].join(''); }; // 主模板 - var TPL_MAIN = ['
' - ,TPL_BOX({ - index: 0 - ,checkAllName: 'layTransferLeftCheckAll' - }) - ,'
' - ,'' - ,'' - ,'
' - ,TPL_BOX({ - index: 1 - ,checkAllName: 'layTransferRightCheckAll' - }) - ,'
'].join(''); + var TPL_MAIN = ['
', + TPL_BOX({ + index: 0, + checkAllName: 'layTransferLeftCheckAll' + }), + '
', + '', + '', + '
', + TPL_BOX({ + index: 1, + checkAllName: 'layTransferRightCheckAll' + }), + '
'].join(''); // 构造器 var Class = function(options){ @@ -115,7 +115,7 @@ layui.define(['laytpl', 'form'], function(exports){ that.render(); }; - //默认配置 + // 默认配置 Class.prototype.config = { title: ['列表一', '列表二'], width: 200, @@ -130,31 +130,31 @@ layui.define(['laytpl', 'form'], function(exports){ } }; - //重载实例 + // 重载实例 Class.prototype.reload = function(options){ var that = this; that.config = $.extend({}, that.config, options); that.render(); }; - //渲染 + // 渲染 Class.prototype.render = function(){ var that = this; var options = that.config; - //解析模板 + // 解析模板 var thisElem = that.elem = $(laytpl(TPL_MAIN, { open: '{{', // 标签符前缀 close: '}}' // 标签符后缀 }).render({ - data: options - ,index: that.index //索引 + data: options, + index: that.index // 索引 })); var othis = options.elem = $(options.elem); if(!othis[0]) return; - //初始化属性 + // 初始化属性 options.data = options.data || []; options.value = options.value || []; @@ -164,20 +164,20 @@ layui.define(['laytpl', 'form'], function(exports){ ); that.key = options.id; - //插入组件结构 + // 插入组件结构 othis.html(that.elem); - //各级容器 + // 各级容器 that.layBox = that.elem.find('.'+ ELEM_BOX) that.layHeader = that.elem.find('.'+ ELEM_HEADER) that.laySearch = that.elem.find('.'+ ELEM_SEARCH) that.layData = thisElem.find('.'+ ELEM_DATA); that.layBtn = thisElem.find('.'+ ELEM_ACTIVE + ' .layui-btn'); - //初始化尺寸 + // 初始化尺寸 that.layBox.css({ - width: options.width - ,height: options.height + width: options.width, + height: options.height }); that.layData.css({ height: function(){ @@ -189,8 +189,8 @@ layui.define(['laytpl', 'form'], function(exports){ }() }); - that.renderData(); //渲染数据 - that.events(); //事件 + that.renderData(); // 渲染数据 + that.events(); // 事件 }; // 渲染数据 @@ -233,27 +233,28 @@ layui.define(['laytpl', 'form'], function(exports){ that.renderCheckBtn(); }; - //渲染表单 + // 渲染表单 Class.prototype.renderForm = function(type){ form.render(type, 'LAY-transfer-'+ this.index); }; - //同步复选框和按钮状态 + // 同步复选框和按钮状态 Class.prototype.renderCheckBtn = function(obj){ - var that = this - ,options = that.config; + var that = this; + var options = that.config; obj = obj || {}; that.layBox.each(function(_index){ - var othis = $(this) - ,thisDataElem = othis.find('.'+ ELEM_DATA) - ,allElemCheckbox = othis.find('.'+ ELEM_HEADER).find('input[type="checkbox"]') - ,listElemCheckbox = thisDataElem.find('input[type="checkbox"]'); + var othis = $(this); + var thisDataElem = othis.find('.'+ ELEM_DATA); + var allElemCheckbox = othis.find('.'+ ELEM_HEADER).find('input[type="checkbox"]'); + var listElemCheckbox = thisDataElem.find('input[type="checkbox"]'); - //同步复选框和按钮状态 - var nums = 0 - ,haveChecked = false; + // 同步复选框和按钮状态 + var nums = 0; + var haveChecked = false; + listElemCheckbox.each(function(){ var isHide = $(this).data('hide'); if(this.checked || this.disabled || isHide){ @@ -264,10 +265,10 @@ layui.define(['laytpl', 'form'], function(exports){ } }); - allElemCheckbox.prop('checked', haveChecked && nums === listElemCheckbox.length); //全选复选框状态 - that.layBtn.eq(_index)[haveChecked ? 'removeClass' : 'addClass'](DISABLED); //对应的按钮状态 + allElemCheckbox.prop('checked', haveChecked && nums === listElemCheckbox.length); // 全选复选框状态 + that.layBtn.eq(_index)[haveChecked ? 'removeClass' : 'addClass'](DISABLED); // 对应的按钮状态 - //无数据视图 + // 无数据视图 if(!obj.stopNone){ var isNone = thisDataElem.children('li:not(.'+ HIDE +')').length that.noneView(thisDataElem, isNone ? '' : options.text.none); @@ -277,7 +278,7 @@ layui.define(['laytpl', 'form'], function(exports){ that.renderForm('checkbox'); }; - //无数据视图 + // 无数据视图 Class.prototype.noneView = function(thisDataElem, text){ var createNoneElem = $('

'+ (text || '') +'

'); if(thisDataElem.find('.'+ NONE)[0]){ @@ -286,11 +287,12 @@ layui.define(['laytpl', 'form'], function(exports){ text.replace(/\s/g, '') && thisDataElem.append(createNoneElem); }; - //同步 value 属性值 + // 同步 value 属性值 Class.prototype.setValue = function(){ - var that = this - ,options = that.config - ,arr = []; + var that = this; + var options = that.config; + var arr = []; + that.layBox.eq(1).find('.'+ ELEM_DATA +' input[type="checkbox"]').each(function(){ var isHide = $(this).data('hide'); isHide || arr.push(this.value); @@ -300,14 +302,14 @@ layui.define(['laytpl', 'form'], function(exports){ return that; }; - //解析数据 + // 解析数据 Class.prototype.parseData = function(callback){ - var that = this - ,options = that.config - ,newData = []; + var that = this; + var options = that.config; + var newData = []; layui.each(options.data, function(index, item){ - //解析格式 + // 解析格式 item = (typeof options.parseData === 'function' ? options.parseData(item) : item) || item; @@ -326,11 +328,11 @@ layui.define(['laytpl', 'form'], function(exports){ return that; }; - //获得右侧面板数据 + // 获得右侧面板数据 Class.prototype.getData = function(value){ - var that = this - ,options = that.config - ,selectedData = []; + var that = this; + var options = that.config; + var selectedData = []; that.setValue(); @@ -345,30 +347,30 @@ layui.define(['laytpl', 'form'], function(exports){ return selectedData; }; - //执行穿梭 + // 执行穿梭 Class.prototype.transfer = function (_index, elem) { - var that = this - ,options = that.config - ,thisBoxElem = that.layBox.eq(_index) - ,arr = [] + var that = this; + var options = that.config; + var thisBoxElem = that.layBox.eq(_index); + var arr = []; if (!elem) { - //通过按钮触发找到选中的进行移动 + // 通过按钮触发找到选中的进行移动 thisBoxElem.each(function(_index){ - var othis = $(this) - ,thisDataElem = othis.find('.'+ ELEM_DATA); + var othis = $(this); + var thisDataElem = othis.find('.'+ ELEM_DATA); thisDataElem.children('li').each(function(){ - var thisList = $(this) - ,thisElemCheckbox = thisList.find('input[type="checkbox"]') - ,isHide = thisElemCheckbox.data('hide'); + var thisList = $(this); + var thisElemCheckbox = thisList.find('input[type="checkbox"]'); + var isHide = thisElemCheckbox.data('hide'); if(thisElemCheckbox[0].checked && !isHide){ thisElemCheckbox[0].checked = false; thisBoxElem.siblings('.'+ ELEM_BOX).find('.'+ ELEM_DATA).append(thisList.clone()); thisList.remove(); - //记录当前穿梭的数据 + // 记录当前穿梭的数据 arr.push(thisElemCheckbox[0].value); } @@ -376,15 +378,15 @@ layui.define(['laytpl', 'form'], function(exports){ }); }); } else { - //双击单条记录移动 - var thisList = elem - ,thisElemCheckbox = thisList.find('input[type="checkbox"]') + // 双击单条记录移动 + var thisList = elem; + var thisElemCheckbox = thisList.find('input[type="checkbox"]'); thisElemCheckbox[0].checked = false; thisBoxElem.siblings('.'+ ELEM_BOX).find('.'+ ELEM_DATA).append(thisList.clone()); thisList.remove(); - //记录当前穿梭的数据 + // 记录当前穿梭的数据 arr.push(thisElemCheckbox[0].value); that.setValue(); @@ -392,28 +394,28 @@ layui.define(['laytpl', 'form'], function(exports){ that.renderCheckBtn(); - //穿梭时,如果另外一个框正在搜索,则触发匹配 + // 穿梭时,如果另外一个框正在搜索,则触发匹配 var siblingInput = thisBoxElem.siblings('.'+ ELEM_BOX).find('.'+ ELEM_SEARCH +' input') siblingInput.val() === '' || siblingInput.trigger('keyup'); - //穿梭时的回调 + // 穿梭时的回调 options.onchange && options.onchange(that.getData(arr), _index); } - //事件 + // 事件 Class.prototype.events = function(){ - var that = this - ,options = that.config; + var that = this; + var options = that.config; - //左右复选框 + // 左右复选框 that.elem.on('click', 'input[lay-filter="layTransferCheckbox"]+', function(){ - var thisElemCheckbox = $(this).prev() - ,checked = thisElemCheckbox[0].checked - ,thisDataElem = thisElemCheckbox.parents('.'+ ELEM_BOX).eq(0).find('.'+ ELEM_DATA); + var thisElemCheckbox = $(this).prev(); + var checked = thisElemCheckbox[0].checked; + var thisDataElem = thisElemCheckbox.parents('.'+ ELEM_BOX).eq(0).find('.'+ ELEM_DATA); if(thisElemCheckbox[0].disabled) return; - //判断是否全选 + // 判断是否全选 if(thisElemCheckbox.attr('lay-type') === 'all'){ thisDataElem.find('input[type="checkbox"]').each(function(){ if(this.disabled) return; @@ -428,26 +430,36 @@ layui.define(['laytpl', 'form'], function(exports){ // 双击穿梭 that.elem.on('dblclick', '.' + ELEM_DATA + '>li', function(event){ - var elemThis = $(this) - ,thisElemCheckbox = elemThis.children('input[type="checkbox"]') - ,thisDataElem = elemThis.parent() - ,thisBoxElem = thisDataElem.parent() + var elemThis = $(this); + var thisElemCheckbox = elemThis.children('input[type="checkbox"]'); + var thisDataElem = elemThis.parent(); + var thisBoxElem = thisDataElem.parent(); + var index = thisBoxElem.data('index'); if(thisElemCheckbox[0].disabled) return; - that.transfer(thisBoxElem.data('index'), elemThis); + // 根据 dblclick 回调函数返回值决定是否执行穿梭 --- 2.9.3+ + var ret = typeof options.dblclick === 'function' ? options.dblclick({ + elem: elemThis, + data: that.getData([thisElemCheckbox[0].value])[0], + index: index + }) : null; + + if(ret === false) return; + + that.transfer(index, elemThis); }) // 穿梭按钮事件 that.layBtn.on('click', function(){ - var othis = $(this) - ,_index = othis.data('index') - if(othis.hasClass(DISABLED)) return; + var othis = $(this); + var _index = othis.data('index'); + if(othis.hasClass(DISABLED)) return; that.transfer(_index); }); - //搜索 + // 搜索 that.laySearch.find('input').on('keyup', function(){ var value = this.value; var thisDataElem = $(this).parents('.'+ ELEM_SEARCH).eq(0).siblings('.'+ ELEM_DATA); @@ -472,17 +484,17 @@ layui.define(['laytpl', 'form'], function(exports){ that.renderCheckBtn(); - //无匹配数据视图 + // 无匹配数据视图 var isNone = thisListElem.length === thisDataElem.children('li.'+ HIDE).length; that.noneView(thisDataElem, isNone ? options.text.searchNone : ''); }); }; - //记录所有实例 - thisModule.that = {}; //记录所有实例对象 - thisModule.config = {}; //记录所有实例配置项 + // 记录所有实例 + thisModule.that = {}; // 记录所有实例对象 + thisModule.config = {}; // 记录所有实例配置项 - //重载实例 + // 重载实例 transfer.reload = function(id, options){ var that = thisModule.that[id]; that.reload(options); @@ -490,13 +502,13 @@ layui.define(['laytpl', 'form'], function(exports){ return thisModule.call(that); }; - //获得选中的数据(右侧面板) + // 获得选中的数据(右侧面板) transfer.getData = function(id){ var that = thisModule.that[id]; return that.getData(); }; - //核心入口 + // 核心入口 transfer.render = function(options){ var inst = new Class(options); return thisModule.call(inst);