feat(transfer): 新增 `dblclick` 选项 (#1491)

* feat(transfer): 新增 `dblclick` 选项

* style(transfer): 优化代码书写风格

---------

Co-authored-by: 贤心 <3277200+sentsim@users.noreply.github.com>
pull/1510/head^2
morning-star 11 months ago committed by GitHub
parent ed3bab52e5
commit e5aa6c3a87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -163,6 +163,30 @@ onchange: function(data, index){
`false` `false`
</td>
</tr>
<tr>
<td>dblclick <sup>2.9.3+</sup></td>
<td>
双击时的回调函数。返回的参数如下:
```
dblclick: function(obj){
console.log(obj.elem); // 点击的元素
console.log(obj.data); // 得到点击项的数据
console.log(obj.index); // 如果数据来自左边index 为 0否则为 1
return false // 返回 false 会阻止穿梭
}
```
</td>
<td>function</td>
<td>
`null`
</td> </td>
</tr> </tr>
<tr> <tr>

@ -73,39 +73,39 @@ layui.define(['laytpl', 'form'], function(exports){
// 穿梭框模板 // 穿梭框模板
var TPL_BOX = function(obj){ var TPL_BOX = function(obj){
obj = obj || {}; obj = obj || {};
return ['<div class="layui-transfer-box" data-index="'+ obj.index +'">' return ['<div class="layui-transfer-box" data-index="'+ obj.index +'">',
,'<div class="layui-transfer-header">' '<div class="layui-transfer-header">',
,'<input type="checkbox" name="'+ obj.checkAllName +'" lay-filter="layTransferCheckbox" lay-type="all" lay-skin="primary" title="{{= d.data.title['+ obj.index +'] || \'list'+ (obj.index + 1) +'\' }}">' '<input type="checkbox" name="'+ obj.checkAllName +'" lay-filter="layTransferCheckbox" lay-type="all" lay-skin="primary" title="{{= d.data.title['+ obj.index +'] || \'list'+ (obj.index + 1) +'\' }}">',
,'</div>' '</div>',
,'{{# if(d.data.showSearch){ }}' '{{# if(d.data.showSearch){ }}',
,'<div class="layui-transfer-search">' '<div class="layui-transfer-search">',
,'<i class="layui-icon layui-icon-search"></i>' '<i class="layui-icon layui-icon-search"></i>',
,'<input type="text" class="layui-input" placeholder="关键词搜索">' '<input type="text" class="layui-input" placeholder="关键词搜索">',
,'</div>' '</div>',
,'{{# } }}' '{{# } }}',
,'<ul class="layui-transfer-data"></ul>' '<ul class="layui-transfer-data"></ul>',
,'</div>'].join(''); '</div>'].join('');
}; };
// 主模板 // 主模板
var TPL_MAIN = ['<div class="layui-transfer layui-form layui-border-box" lay-filter="LAY-transfer-{{= d.index }}">' var TPL_MAIN = ['<div class="layui-transfer layui-form layui-border-box" lay-filter="LAY-transfer-{{= d.index }}">',
,TPL_BOX({ TPL_BOX({
index: 0 index: 0,
,checkAllName: 'layTransferLeftCheckAll' checkAllName: 'layTransferLeftCheckAll'
}) }),
,'<div class="layui-transfer-active">' '<div class="layui-transfer-active">',
,'<button type="button" class="layui-btn layui-btn-sm layui-btn-primary layui-btn-disabled" data-index="0">' '<button type="button" class="layui-btn layui-btn-sm layui-btn-primary layui-btn-disabled" data-index="0">',
,'<i class="layui-icon layui-icon-next"></i>' '<i class="layui-icon layui-icon-next"></i>',
,'</button>' '</button>',
,'<button type="button" class="layui-btn layui-btn-sm layui-btn-primary layui-btn-disabled" data-index="1">' '<button type="button" class="layui-btn layui-btn-sm layui-btn-primary layui-btn-disabled" data-index="1">',
,'<i class="layui-icon layui-icon-prev"></i>' '<i class="layui-icon layui-icon-prev"></i>',
,'</button>' '</button>',
,'</div>' '</div>',
,TPL_BOX({ TPL_BOX({
index: 1 index: 1,
,checkAllName: 'layTransferRightCheckAll' checkAllName: 'layTransferRightCheckAll'
}) }),
,'</div>'].join(''); '</div>'].join('');
// 构造器 // 构造器
var Class = function(options){ var Class = function(options){
@ -115,7 +115,7 @@ layui.define(['laytpl', 'form'], function(exports){
that.render(); that.render();
}; };
//默认配置 // 默认配置
Class.prototype.config = { Class.prototype.config = {
title: ['列表一', '列表二'], title: ['列表一', '列表二'],
width: 200, width: 200,
@ -130,31 +130,31 @@ layui.define(['laytpl', 'form'], function(exports){
} }
}; };
//重载实例 // 重载实例
Class.prototype.reload = function(options){ Class.prototype.reload = function(options){
var that = this; var that = this;
that.config = $.extend({}, that.config, options); that.config = $.extend({}, that.config, options);
that.render(); that.render();
}; };
//渲染 // 渲染
Class.prototype.render = function(){ Class.prototype.render = function(){
var that = this; var that = this;
var options = that.config; var options = that.config;
//解析模板 // 解析模板
var thisElem = that.elem = $(laytpl(TPL_MAIN, { var thisElem = that.elem = $(laytpl(TPL_MAIN, {
open: '{{', // 标签符前缀 open: '{{', // 标签符前缀
close: '}}' // 标签符后缀 close: '}}' // 标签符后缀
}).render({ }).render({
data: options data: options,
,index: that.index //索引 index: that.index // 索引
})); }));
var othis = options.elem = $(options.elem); var othis = options.elem = $(options.elem);
if(!othis[0]) return; if(!othis[0]) return;
//初始化属性 // 初始化属性
options.data = options.data || []; options.data = options.data || [];
options.value = options.value || []; options.value = options.value || [];
@ -164,20 +164,20 @@ layui.define(['laytpl', 'form'], function(exports){
); );
that.key = options.id; that.key = options.id;
//插入组件结构 // 插入组件结构
othis.html(that.elem); othis.html(that.elem);
//各级容器 // 各级容器
that.layBox = that.elem.find('.'+ ELEM_BOX) that.layBox = that.elem.find('.'+ ELEM_BOX)
that.layHeader = that.elem.find('.'+ ELEM_HEADER) that.layHeader = that.elem.find('.'+ ELEM_HEADER)
that.laySearch = that.elem.find('.'+ ELEM_SEARCH) that.laySearch = that.elem.find('.'+ ELEM_SEARCH)
that.layData = thisElem.find('.'+ ELEM_DATA); that.layData = thisElem.find('.'+ ELEM_DATA);
that.layBtn = thisElem.find('.'+ ELEM_ACTIVE + ' .layui-btn'); that.layBtn = thisElem.find('.'+ ELEM_ACTIVE + ' .layui-btn');
//初始化尺寸 // 初始化尺寸
that.layBox.css({ that.layBox.css({
width: options.width width: options.width,
,height: options.height height: options.height
}); });
that.layData.css({ that.layData.css({
height: function(){ height: function(){
@ -189,8 +189,8 @@ layui.define(['laytpl', 'form'], function(exports){
}() }()
}); });
that.renderData(); //渲染数据 that.renderData(); // 渲染数据
that.events(); //事件 that.events(); // 事件
}; };
// 渲染数据 // 渲染数据
@ -233,27 +233,28 @@ layui.define(['laytpl', 'form'], function(exports){
that.renderCheckBtn(); that.renderCheckBtn();
}; };
//渲染表单 // 渲染表单
Class.prototype.renderForm = function(type){ Class.prototype.renderForm = function(type){
form.render(type, 'LAY-transfer-'+ this.index); form.render(type, 'LAY-transfer-'+ this.index);
}; };
//同步复选框和按钮状态 // 同步复选框和按钮状态
Class.prototype.renderCheckBtn = function(obj){ Class.prototype.renderCheckBtn = function(obj){
var that = this var that = this;
,options = that.config; var options = that.config;
obj = obj || {}; obj = obj || {};
that.layBox.each(function(_index){ that.layBox.each(function(_index){
var othis = $(this) var othis = $(this);
,thisDataElem = othis.find('.'+ ELEM_DATA) var thisDataElem = othis.find('.'+ ELEM_DATA);
,allElemCheckbox = othis.find('.'+ ELEM_HEADER).find('input[type="checkbox"]') var allElemCheckbox = othis.find('.'+ ELEM_HEADER).find('input[type="checkbox"]');
,listElemCheckbox = thisDataElem.find('input[type="checkbox"]'); var listElemCheckbox = thisDataElem.find('input[type="checkbox"]');
//同步复选框和按钮状态 // 同步复选框和按钮状态
var nums = 0 var nums = 0;
,haveChecked = false; var haveChecked = false;
listElemCheckbox.each(function(){ listElemCheckbox.each(function(){
var isHide = $(this).data('hide'); var isHide = $(this).data('hide');
if(this.checked || this.disabled || isHide){ if(this.checked || this.disabled || isHide){
@ -264,10 +265,10 @@ layui.define(['laytpl', 'form'], function(exports){
} }
}); });
allElemCheckbox.prop('checked', haveChecked && nums === listElemCheckbox.length); //全选复选框状态 allElemCheckbox.prop('checked', haveChecked && nums === listElemCheckbox.length); // 全选复选框状态
that.layBtn.eq(_index)[haveChecked ? 'removeClass' : 'addClass'](DISABLED); //对应的按钮状态 that.layBtn.eq(_index)[haveChecked ? 'removeClass' : 'addClass'](DISABLED); // 对应的按钮状态
//无数据视图 // 无数据视图
if(!obj.stopNone){ if(!obj.stopNone){
var isNone = thisDataElem.children('li:not(.'+ HIDE +')').length var isNone = thisDataElem.children('li:not(.'+ HIDE +')').length
that.noneView(thisDataElem, isNone ? '' : options.text.none); that.noneView(thisDataElem, isNone ? '' : options.text.none);
@ -277,7 +278,7 @@ layui.define(['laytpl', 'form'], function(exports){
that.renderForm('checkbox'); that.renderForm('checkbox');
}; };
//无数据视图 // 无数据视图
Class.prototype.noneView = function(thisDataElem, text){ Class.prototype.noneView = function(thisDataElem, text){
var createNoneElem = $('<p class="layui-none">'+ (text || '') +'</p>'); var createNoneElem = $('<p class="layui-none">'+ (text || '') +'</p>');
if(thisDataElem.find('.'+ NONE)[0]){ if(thisDataElem.find('.'+ NONE)[0]){
@ -286,11 +287,12 @@ layui.define(['laytpl', 'form'], function(exports){
text.replace(/\s/g, '') && thisDataElem.append(createNoneElem); text.replace(/\s/g, '') && thisDataElem.append(createNoneElem);
}; };
//同步 value 属性值 // 同步 value 属性值
Class.prototype.setValue = function(){ Class.prototype.setValue = function(){
var that = this var that = this;
,options = that.config var options = that.config;
,arr = []; var arr = [];
that.layBox.eq(1).find('.'+ ELEM_DATA +' input[type="checkbox"]').each(function(){ that.layBox.eq(1).find('.'+ ELEM_DATA +' input[type="checkbox"]').each(function(){
var isHide = $(this).data('hide'); var isHide = $(this).data('hide');
isHide || arr.push(this.value); isHide || arr.push(this.value);
@ -300,14 +302,14 @@ layui.define(['laytpl', 'form'], function(exports){
return that; return that;
}; };
//解析数据 // 解析数据
Class.prototype.parseData = function(callback){ Class.prototype.parseData = function(callback){
var that = this var that = this;
,options = that.config var options = that.config;
,newData = []; var newData = [];
layui.each(options.data, function(index, item){ layui.each(options.data, function(index, item){
//解析格式 // 解析格式
item = (typeof options.parseData === 'function' item = (typeof options.parseData === 'function'
? options.parseData(item) ? options.parseData(item)
: item) || item; : item) || item;
@ -326,11 +328,11 @@ layui.define(['laytpl', 'form'], function(exports){
return that; return that;
}; };
//获得右侧面板数据 // 获得右侧面板数据
Class.prototype.getData = function(value){ Class.prototype.getData = function(value){
var that = this var that = this;
,options = that.config var options = that.config;
,selectedData = []; var selectedData = [];
that.setValue(); that.setValue();
@ -345,30 +347,30 @@ layui.define(['laytpl', 'form'], function(exports){
return selectedData; return selectedData;
}; };
//执行穿梭 // 执行穿梭
Class.prototype.transfer = function (_index, elem) { Class.prototype.transfer = function (_index, elem) {
var that = this var that = this;
,options = that.config var options = that.config;
,thisBoxElem = that.layBox.eq(_index) var thisBoxElem = that.layBox.eq(_index);
,arr = [] var arr = [];
if (!elem) { if (!elem) {
//通过按钮触发找到选中的进行移动 // 通过按钮触发找到选中的进行移动
thisBoxElem.each(function(_index){ thisBoxElem.each(function(_index){
var othis = $(this) var othis = $(this);
,thisDataElem = othis.find('.'+ ELEM_DATA); var thisDataElem = othis.find('.'+ ELEM_DATA);
thisDataElem.children('li').each(function(){ thisDataElem.children('li').each(function(){
var thisList = $(this) var thisList = $(this);
,thisElemCheckbox = thisList.find('input[type="checkbox"]') var thisElemCheckbox = thisList.find('input[type="checkbox"]');
,isHide = thisElemCheckbox.data('hide'); var isHide = thisElemCheckbox.data('hide');
if(thisElemCheckbox[0].checked && !isHide){ if(thisElemCheckbox[0].checked && !isHide){
thisElemCheckbox[0].checked = false; thisElemCheckbox[0].checked = false;
thisBoxElem.siblings('.'+ ELEM_BOX).find('.'+ ELEM_DATA).append(thisList.clone()); thisBoxElem.siblings('.'+ ELEM_BOX).find('.'+ ELEM_DATA).append(thisList.clone());
thisList.remove(); thisList.remove();
//记录当前穿梭的数据 // 记录当前穿梭的数据
arr.push(thisElemCheckbox[0].value); arr.push(thisElemCheckbox[0].value);
} }
@ -376,15 +378,15 @@ layui.define(['laytpl', 'form'], function(exports){
}); });
}); });
} else { } else {
//双击单条记录移动 // 双击单条记录移动
var thisList = elem var thisList = elem;
,thisElemCheckbox = thisList.find('input[type="checkbox"]') var thisElemCheckbox = thisList.find('input[type="checkbox"]');
thisElemCheckbox[0].checked = false; thisElemCheckbox[0].checked = false;
thisBoxElem.siblings('.'+ ELEM_BOX).find('.'+ ELEM_DATA).append(thisList.clone()); thisBoxElem.siblings('.'+ ELEM_BOX).find('.'+ ELEM_DATA).append(thisList.clone());
thisList.remove(); thisList.remove();
//记录当前穿梭的数据 // 记录当前穿梭的数据
arr.push(thisElemCheckbox[0].value); arr.push(thisElemCheckbox[0].value);
that.setValue(); that.setValue();
@ -392,28 +394,28 @@ layui.define(['laytpl', 'form'], function(exports){
that.renderCheckBtn(); that.renderCheckBtn();
//穿梭时,如果另外一个框正在搜索,则触发匹配 // 穿梭时,如果另外一个框正在搜索,则触发匹配
var siblingInput = thisBoxElem.siblings('.'+ ELEM_BOX).find('.'+ ELEM_SEARCH +' input') var siblingInput = thisBoxElem.siblings('.'+ ELEM_BOX).find('.'+ ELEM_SEARCH +' input')
siblingInput.val() === '' || siblingInput.trigger('keyup'); siblingInput.val() === '' || siblingInput.trigger('keyup');
//穿梭时的回调 // 穿梭时的回调
options.onchange && options.onchange(that.getData(arr), _index); options.onchange && options.onchange(that.getData(arr), _index);
} }
//事件 // 事件
Class.prototype.events = function(){ Class.prototype.events = function(){
var that = this var that = this;
,options = that.config; var options = that.config;
//左右复选框 // 左右复选框
that.elem.on('click', 'input[lay-filter="layTransferCheckbox"]+', function(){ that.elem.on('click', 'input[lay-filter="layTransferCheckbox"]+', function(){
var thisElemCheckbox = $(this).prev() var thisElemCheckbox = $(this).prev();
,checked = thisElemCheckbox[0].checked var checked = thisElemCheckbox[0].checked;
,thisDataElem = thisElemCheckbox.parents('.'+ ELEM_BOX).eq(0).find('.'+ ELEM_DATA); var thisDataElem = thisElemCheckbox.parents('.'+ ELEM_BOX).eq(0).find('.'+ ELEM_DATA);
if(thisElemCheckbox[0].disabled) return; if(thisElemCheckbox[0].disabled) return;
//判断是否全选 // 判断是否全选
if(thisElemCheckbox.attr('lay-type') === 'all'){ if(thisElemCheckbox.attr('lay-type') === 'all'){
thisDataElem.find('input[type="checkbox"]').each(function(){ thisDataElem.find('input[type="checkbox"]').each(function(){
if(this.disabled) return; if(this.disabled) return;
@ -428,26 +430,36 @@ layui.define(['laytpl', 'form'], function(exports){
// 双击穿梭 // 双击穿梭
that.elem.on('dblclick', '.' + ELEM_DATA + '>li', function(event){ that.elem.on('dblclick', '.' + ELEM_DATA + '>li', function(event){
var elemThis = $(this) var elemThis = $(this);
,thisElemCheckbox = elemThis.children('input[type="checkbox"]') var thisElemCheckbox = elemThis.children('input[type="checkbox"]');
,thisDataElem = elemThis.parent() var thisDataElem = elemThis.parent();
,thisBoxElem = thisDataElem.parent() var thisBoxElem = thisDataElem.parent();
var index = thisBoxElem.data('index');
if(thisElemCheckbox[0].disabled) return; 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(){ that.layBtn.on('click', function(){
var othis = $(this) var othis = $(this);
,_index = othis.data('index') var _index = othis.data('index');
if(othis.hasClass(DISABLED)) return;
if(othis.hasClass(DISABLED)) return;
that.transfer(_index); that.transfer(_index);
}); });
//搜索 // 搜索
that.laySearch.find('input').on('keyup', function(){ that.laySearch.find('input').on('keyup', function(){
var value = this.value; var value = this.value;
var thisDataElem = $(this).parents('.'+ ELEM_SEARCH).eq(0).siblings('.'+ ELEM_DATA); var thisDataElem = $(this).parents('.'+ ELEM_SEARCH).eq(0).siblings('.'+ ELEM_DATA);
@ -472,17 +484,17 @@ layui.define(['laytpl', 'form'], function(exports){
that.renderCheckBtn(); that.renderCheckBtn();
//无匹配数据视图 // 无匹配数据视图
var isNone = thisListElem.length === thisDataElem.children('li.'+ HIDE).length; var isNone = thisListElem.length === thisDataElem.children('li.'+ HIDE).length;
that.noneView(thisDataElem, isNone ? options.text.searchNone : ''); that.noneView(thisDataElem, isNone ? options.text.searchNone : '');
}); });
}; };
//记录所有实例 // 记录所有实例
thisModule.that = {}; //记录所有实例对象 thisModule.that = {}; // 记录所有实例对象
thisModule.config = {}; //记录所有实例配置项 thisModule.config = {}; // 记录所有实例配置项
//重载实例 // 重载实例
transfer.reload = function(id, options){ transfer.reload = function(id, options){
var that = thisModule.that[id]; var that = thisModule.that[id];
that.reload(options); that.reload(options);
@ -490,13 +502,13 @@ layui.define(['laytpl', 'form'], function(exports){
return thisModule.call(that); return thisModule.call(that);
}; };
//获得选中的数据(右侧面板) // 获得选中的数据(右侧面板)
transfer.getData = function(id){ transfer.getData = function(id){
var that = thisModule.that[id]; var that = thisModule.that[id];
return that.getData(); return that.getData();
}; };
//核心入口 // 核心入口
transfer.render = function(options){ transfer.render = function(options){
var inst = new Class(options); var inst = new Class(options);
return thisModule.call(inst); return thisModule.call(inst);

Loading…
Cancel
Save