kdayun-compnent-develop/kdayun-compnent-pack/dist/libs/layui/lay/modules/transfer.js

484 lines
17 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
@Namelayui.transfer 穿梭框
@Author贤心
@LicenseMIT
*/
layui.define(['laytpl', 'form'], function (exports) {
"use strict";
var $ = layui.$
, laytpl = layui.laytpl
, form = layui.form
//模块名
, MOD_NAME = 'transfer'
//外部接口
, transfer = {
config: {}
, index: layui[MOD_NAME] ? (layui[MOD_NAME].index + 10000) : 0
//设置全局项
, set: function (options) {
var that = this;
that.config = $.extend({}, that.config, options);
return that;
}
//事件监听
, on: function (events, callback) {
return layui.onevent.call(this, MOD_NAME, events, callback);
}
}
//操作当前实例
, thisModule = function () {
var that = this
, options = that.config
, id = options.id || that.index;
thisModule.that[id] = that; //记录当前实例对象
thisModule.config[id] = options; //记录当前实例配置项
return {
config: options
//重置实例
, reload: function (options) {
that.reload.call(that, options);
}
//获取右侧数据
, getData: function () {
return that.getData.call(that);
}
}
}
//获取当前实例配置项
, getThisModuleConfig = function (id) {
var config = thisModule.config[id];
if (!config) hint.error('The ID option was not found in the ' + MOD_NAME + ' instance');
return config || null;
}
//字符常量
, ELEM = 'layui-transfer', HIDE = 'layui-hide', DISABLED = 'layui-btn-disabled', NONE = 'layui-none'
, ELEM_BOX = 'layui-transfer-box', ELEM_HEADER = 'layui-transfer-header', ELEM_SEARCH = 'layui-transfer-search', ELEM_ACTIVE = 'layui-transfer-active', ELEM_DATA = 'layui-transfer-data'
//穿梭框模板
, TPL_BOX = function (obj) {
obj = obj || {};
return ['<div class="layui-transfer-box" data-index="' + obj.index + '">'
, '<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) + '\' }}">'
, '</div>'
, '{{# if(d.data.showSearch){ }}'
, '<div class="layui-transfer-search">'
, '<i class="layui-icon layui-icon-search"></i>'
, '<input type="input" class="layui-input" placeholder="关键词搜索">'
, '</div>'
, '{{# } }}'
, '<ul class="layui-transfer-data"></ul>'
, '</div>'].join('');
}
//主模板
, TPL_MAIN = ['<div class="layui-transfer layui-form layui-border-box" lay-filter="LAY-transfer-{{ d.index }}">'
, TPL_BOX({
index: 0
, checkAllName: 'layTransferLeftCheckAll'
})
, '<div class="layui-transfer-active">'
, '<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>'
, '</button>'
, '<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>'
, '</button>'
, '</div>'
, TPL_BOX({
index: 1
, checkAllName: 'layTransferRightCheckAll'
})
, '</div>'].join('')
//构造器
, Class = function (options) {
var that = this;
that.index = ++transfer.index;
that.config = $.extend({}, that.config, transfer.config, options);
that.render();
};
//默认配置
Class.prototype.config = {
title: ['列表一', '列表二']
, width: 200
, height: 360
, data: [] //数据源
, value: [] //选中的数据
, showSearch: false //是否开启搜索
, id: '' //唯一索引,默认自增 index
, text: {
none: '无数据'
, searchNone: '无匹配数据'
}
};
//重载实例
Class.prototype.reload = function (options) {
var that = this;
layui.each(options, function (key, item) {
if (item.constructor === Array) delete that.config[key];
});
that.config = $.extend(true, {}, that.config, options);
that.render();
};
//渲染
Class.prototype.render = function () {
var that = this
, options = that.config;
//解析模板
var thisElem = that.elem = $(laytpl(TPL_MAIN).render({
data: options
, index: that.index //索引
}));
var othis = options.elem = $(options.elem);
if (!othis[0]) return;
//初始化属性
options.data = options.data || [];
options.value = options.value || [];
//索引
that.key = options.id || that.index;
//插入组件结构
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
});
that.layData.css({
height: function () {
return options.height - that.layHeader.outerHeight() - that.laySearch.outerHeight() - 2
}()
});
that.renderData(); //渲染数据
that.events(); //事件
};
//渲染数据
Class.prototype.renderData = function () {
var that = this
, options = that.config;
//左右穿梭框差异数据
var arr = [{
checkName: 'layTransferLeftCheck'
, views: []
}, {
checkName: 'layTransferRightCheck'
, views: []
}];
//解析格式
that.parseData(function (item) {
//标注为 selected 的为右边的数据
var _index = item.selected ? 1 : 0
, listElem = ['<li>'
, '<input type="checkbox" name="' + arr[_index].checkName + '" lay-skin="primary" lay-filter="layTransferCheckbox" title="' + item.title + '"' + (item.disabled ? ' disabled' : '') + (item.checked ? ' checked' : '') + ' value="' + item.value + '">'
, '</li>'].join('');
arr[_index].views.push(listElem);
delete item.selected;
});
// 扩展赋值的顺序跟勾选的顺序一致
var newArr = [];
layui.each(options.value, function (index, item1) {
layui.each(arr[1].views, function (index2, item2) {
var getValue = $(item2).find('input').attr('value');
if (item1 == getValue) {
newArr.push(item2);
}
});
});
// 扩展赋值的顺序跟勾选的顺序一致 end
that.layData.eq(0).html(arr[0].views.join(''));
that.layData.eq(1).html(newArr.join(''));
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;
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 nums = 0
, haveChecked = false;
listElemCheckbox.each(function () {
var isHide = $(this).data('hide');
if (this.checked || this.disabled || isHide) {
nums++;
}
if (this.checked && !isHide) {
haveChecked = true;
}
});
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);
}
});
that.renderForm('checkbox');
};
//无数据视图
Class.prototype.noneView = function (thisDataElem, text) {
var createNoneElem = $('<p class="layui-none">' + (text || '') + '</p>');
if (thisDataElem.find('.' + NONE)[0]) {
thisDataElem.find('.' + NONE).remove();
}
text.replace(/\s/g, '') && thisDataElem.append(createNoneElem);
};
//同步 value 属性值
Class.prototype.setValue = function () {
var that = this
, options = that.config
, arr = [];
that.layBox.eq(1).find('.' + ELEM_DATA + ' input[type="checkbox"]').each(function () {
var isHide = $(this).data('hide');
isHide || arr.push(this.value);
});
options.value = arr;
return that;
};
//解析数据
Class.prototype.parseData = function (callback) {
var that = this
, options = that.config
, newData = [];
layui.each(options.data, function (index, item) {
//解析格式
item = (typeof options.parseData === 'function'
? options.parseData(item)
: item) || item;
newData.push(item = $.extend({}, item))
layui.each(options.value, function (index2, item2) {
if (item2 == item.value) {
item.selected = true;
}
});
callback && callback(item);
});
options.data = newData;
return that;
};
//获得右侧面板数据
Class.prototype.getData = function (value) {
var that = this
, options = that.config
, selectedData = [];
that.setValue();
layui.each(value || options.value, function (index, item) {
layui.each(options.data, function (index2, item2) {
delete item2.selected;
if (item == item2.value) {
selectedData.push(item2);
};
});
});
return selectedData;
};
//事件
Class.prototype.events = function () {
var that = this
, 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);
if (thisElemCheckbox[0].disabled) return;
//判断是否全选
if (thisElemCheckbox.attr('lay-type') === 'all') {
if (options.limit == undefined || options.limit == 0) {
thisDataElem.find('input[type="checkbox"]').each(function () {
if (this.disabled) return;
this.checked = checked;
});
} else if (thisElemCheckbox.parent().parent().data('index') != 0) {
thisDataElem.find('input[type="checkbox"]').each(function () {
if (this.disabled) return;
this.checked = checked;
});
}
}
if (options.limit != undefined && options.limit > 0 && checked) {
var selectCount = 0;
thisDataElem.find('input[type="checkbox"]').each(function () {
if (this.checked) {
selectCount++;
}
});
var selectedCount = 0;
if (thisElemCheckbox.parent().parent().parent().data('index') == 0) {
selectedCount = thisElemCheckbox.parent().parent().parent().next('div').next('div').find('ul li').length;
}
selectCount += selectedCount;
if (options.limit < selectCount) {
thisElemCheckbox[0].checked = false;
layer.msg('最多选' + options.limit + "个", { icon: 0, time: 1500, shade: 0.3 });
}
//获取右侧数据
if (selectedCount == options.limit) {
thisElemCheckbox[0].checked = false;
layer.msg('最多选' + options.limit + "个", { icon: 0, time: 1500, shade: 0.3 });
}
}
that.renderCheckBtn({ stopNone: true });
});
//按钮事件
that.layBtn.on('click', function () {
var othis = $(this)
, _index = othis.data('index')
, thisBoxElem = that.layBox.eq(_index)
, arr = [];
if (othis.hasClass(DISABLED)) return;
that.layBox.eq(_index).each(function (_index) {
var othis = $(this)
, thisDataElem = othis.find('.' + ELEM_DATA);
thisDataElem.children('li').each(function () {
var thisList = $(this)
, thisElemCheckbox = thisList.find('input[type="checkbox"]')
, 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);
}
that.setValue();
});
});
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);
});
//搜索
that.laySearch.find('input').on('keyup', function () {
var value = this.value
, thisDataElem = $(this).parents('.' + ELEM_SEARCH).eq(0).siblings('.' + ELEM_DATA)
, thisListElem = thisDataElem.children('li');
thisListElem.each(function () {
var thisList = $(this)
, thisElemCheckbox = thisList.find('input[type="checkbox"]')
, isMatch = thisElemCheckbox[0].title.indexOf(value) !== -1;
thisList[isMatch ? 'removeClass' : 'addClass'](HIDE);
thisElemCheckbox.data('hide', isMatch ? false : true);
});
that.renderCheckBtn();
//无匹配数据视图
var isNone = thisListElem.length === thisDataElem.children('li.' + HIDE).length;
that.noneView(thisDataElem, isNone ? options.text.searchNone : '');
});
};
//记录所有实例
thisModule.that = {}; //记录所有实例对象
thisModule.config = {}; //记录所有实例配置项
//重载实例
transfer.reload = function (id, options) {
var that = thisModule.that[id];
that.reload(options);
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);
};
exports(MOD_NAME, transfer);
});