修复部分bug以及新增一些功能

1、layui 添加unuse方法用于注销已存在的模块
2、table 添加reloadData方法用于重载数据
3、table 修复table.exportFile报错
4、table 添加editTrigger配置,可以设定触发单元格编辑的方式为click(默认)或dblclick
5、form 添加doVerify方法支持主动调用表单验证,支持特定范围内表单输入验证
6、form form.render方法新增对特定节点的渲染支持,除了以前设置类型和表单范围还可以直接对需要渲染的节点对象进行渲染
7、form 修复表单验证在移动端检验到不满足要求的表单元素没有红框显示的问题
This commit is contained in:
岁月小偷 2022-06-19 02:10:15 +08:00
parent af4ab7f93a
commit ba5f7891d1
3 changed files with 151 additions and 48 deletions

View File

@ -232,6 +232,21 @@
return that;
};
Layui.prototype.unuse = function (apps) {
var that = this;
apps = that.isArray(apps) ? apps : [apps];
that.each(apps, function (index, item) {
if (!config.status[item]) {
return error('module ' + item + ' is not exist');
}
delete that[item];
delete modules[item];
delete that.modules[item];
delete config.status[item];
delete config.modules[item];
})
}
//获取节点的 style 属性值
Layui.prototype.getStyle = function(node, name){
var style = node.currentStyle ? node.currentStyle : win.getComputedStyle(node, null);

View File

@ -145,19 +145,19 @@ layui.define('layer', function(exports){
}())
,items = {
//输入框
input: function(){
var inputs = elemForm.find('input,textarea');
input: function(elem){
var inputs = elem || elemForm.find('input,textarea');
//初始化全局的 autocomplete
options.autocomplete && inputs.attr('autocomplete', options.autocomplete);
}
//下拉选择框
,select: function(){
,select: function(elem){
var TIPS = '请选择', CLASS = 'layui-form-select', TITLE = 'layui-select-title'
,NONE = 'layui-select-none', initValue = '', thatInput
,selects = elemForm.find('select')
,selects = elem || elemForm.find('select')
//隐藏 select
,hide = function(e, clear){
if(!$(e.target).parent().hasClass(TITLE) || clear){
@ -480,13 +480,13 @@ layui.define('layer', function(exports){
}
//复选框/开关
,checkbox: function(){
,checkbox: function(elem){
var CLASS = {
checkbox: ['layui-form-checkbox', 'layui-form-checked', 'checkbox']
,_switch: ['layui-form-switch', 'layui-form-onswitch', 'switch']
}
,checks = elemForm.find('input[type=checkbox]')
,checks = elem || elemForm.find('input[type=checkbox]')
,events = function(reElem, RE_CLASS){
var check = $(this);
@ -552,10 +552,10 @@ layui.define('layer', function(exports){
}
//单选框
,radio: function(){
,radio: function(elem){
var CLASS = 'layui-form-radio', ICON = ['', '']
,radios = elemForm.find('input[type=radio]')
,radios = elem || elemForm.find('input[type=radio]')
,events = function(reElem){
var radio = $(this), ANIM = 'layui-anim-scaleSpring';
@ -611,34 +611,58 @@ layui.define('layer', function(exports){
});
}
};
type ? (
items[type] ? items[type]() : hint.error('不支持的 "'+ type + '" 表单渲染')
) : layui.each(items, function(index, item){
item();
});
if (layui._typeof(type) === 'object') {
// jquery对象
type.each(function (index, item) {
var elem = $(item);
if (!elem.closest(ELEM).length) {
// 如果不是存在layui-form中的直接跳过
return;
}
if (item.tagName === 'SELECT') {
items['select'](elem);
} else if (item.tagName === 'INPUT') {
var itemType = item.type;
if (itemType === 'checkbox' || itemType === 'radio') {
items[itemType](elem);
} else {
items['input'](elem);
}
}
});
} else {
type ? (
items[type] ? items[type]() : hint.error('不支持的 "'+ type + '" 表单渲染')
) : layui.each(items, function(index, item){
item();
});
}
return that;
};
//表单提交校验
var submit = function(){
// verifyElem: 要验证的节点或者范围 返回验证通过返回true否则返回false
Form.prototype.doVerify = function(verifyElem){
var stop = null //验证不通过状态
,verify = form.config.verify //验证规则
,DANGER = 'layui-form-danger' //警示样式
,field = {} //字段集合
,button = $(this) //当前触发的按钮
,elem = button.parents(ELEM).eq(0) //当前所在表单域
,verifyElem = elem.find('*[lay-verify]') //获取需要校验的元素
,formElem = button.parents('form')[0] //获取当前所在的 form 元素,如果存在的话
,filter = button.attr('lay-filter'); //获取过滤器
,verify = form.config.verify //验证规则
,DANGER = 'layui-form-danger' //警示样式
if (layui.type(verifyElem) !== 'object') { // 不符合要求的格式直接判通过
hint.error('doVerify: 参数错误');
return true;
}
if (!verifyElem.attr('lay-verify')) {
// 验证某个容器内的节点
verifyElem = verifyElem.find('*[lay-verify]');
}
//开始校验
layui.each(verifyElem, function(_, item){
var othis = $(this)
,vers = othis.attr('lay-verify').split('|')
,verType = othis.attr('lay-verType') //提示方式
,value = othis.val();
,verifyStr = othis.attr('lay-verify') || ''
,vers = verifyStr.split('|')
,verType = othis.attr('lay-verType') //提示方式
,value = othis.val();
othis.removeClass(DANGER); //移除警示样式
//遍历元素绑定的验证规则
@ -687,7 +711,7 @@ layui.define('layer', function(exports){
} else { //移动设备定位
$dom.scrollTop(function(){
try {
return (isForm2Elem ? othis.next() : othis).offset().top - 15
return (isForm2Elem ? othis.next() : othis).focus().offset().top - 15
} catch(e){
return 0;
}
@ -701,9 +725,22 @@ layui.define('layer', function(exports){
});
if(stop) return stop;
});
if(stop) return false;
return !stop;
}
//表单提交校验
var submit = function(){
var field = {} //字段集合
,button = $(this) //当前触发的按钮
,elem = button.parents(ELEM).eq(0) //当前所在表单域
,verifyElem = elem.find('*[lay-verify]') //获取需要校验的元素
,formElem = button.parents('form')[0] //获取当前所在的 form 元素,如果存在的话
,filter = button.attr('lay-filter'); //获取过滤器
//开始校验
if(!form.doVerify(verifyElem)) return false;
//获取当前表单值
field = form.getValue(null, elem);

View File

@ -53,6 +53,9 @@ layui.define(['laytpl', 'laypage', 'layer', 'form', 'util'], function(exports){
,reload: function(options, deep){
that.reload.call(that, options, deep);
}
,reloadData: function(options, deep){
table.reloadData(id, options, deep);
}
,setColsWidth: function(){
that.setColsWidth.call(that);
}
@ -251,6 +254,7 @@ layui.define(['laytpl', 'laypage', 'layer', 'form', 'util'], function(exports){
,loading: true //请求数据时,是否显示 loading
,escape: true // 是否开启 HTML 编码功能,即转义 html 原文
,cellMinWidth: 60 //所有单元格默认最小宽度
,editTrigger: 'click' //单元格编辑的触发方式
,defaultToolbar: ['filter', 'exports', 'print'] //工具栏右侧图标
,autoSort: true //是否前端自动排序。如果否,则需自主排序(通常为服务端处理好排序)
,text: {
@ -694,7 +698,11 @@ layui.define(['laytpl', 'laypage', 'layer', 'form', 'util'], function(exports){
that.layMain.find('tbody').html('');
that.layMain.append(that.layNone = layNone);
// 异常情况下对page和total的内容处理
that.layPage && that.layPage.addClass(HIDE).find('>div').html('');
that.layTotal && that.layTotal.addClass(HIDE).find('tbody').html('');
table.cache[that.key] = []; //格式化缓存数据
};
@ -941,6 +949,7 @@ layui.define(['laytpl', 'laypage', 'layer', 'form', 'util'], function(exports){
//正常初始化数据渲染
render(); //渲染数据
that.renderTotal(data, totalRowData); //数据合计
that.layTotal && that.layTotal.removeClass(HIDE);
//同步分页状态
if(options.page){
@ -1697,7 +1706,7 @@ layui.define(['laytpl', 'laypage', 'layer', 'form', 'util'], function(exports){
});
//单元格单击事件
that.layBody.on('click', 'td', function(e){
that.layBody.on(options.editTrigger, 'td', function(e){
var othis = $(this)
,field = othis.data('field')
,editType = othis.data('edit')
@ -1982,8 +1991,6 @@ layui.define(['laytpl', 'laypage', 'layer', 'form', 'util'], function(exports){
//表格导出
table.exportFile = function(id, data, type){
var that = this;
data = data || table.clearCacheKey(table.cache[id]);
type = type || 'csv';
@ -2023,8 +2030,8 @@ layui.define(['laytpl', 'laypage', 'layer', 'form', 'util'], function(exports){
}
var content = item1[item3.field]
,td = that.layBody.find('tr[data-index="'+ i1 +'"]>td');
,td = thatTable.layBody.find('tr[data-index="'+ i1 +'"]>td');
if(content === undefined || content === null) content = '';
i1 == 0 && dataTitle.push(item3.title || '');
@ -2046,14 +2053,14 @@ layui.define(['laytpl', 'laypage', 'layer', 'form', 'util'], function(exports){
});
//表合计
layui.each(that.dataTotal, function(key, value){
thatTable && layui.each(thatTable.dataTotal, function(key, value){
fieldsIsHide[key] || dataTotal.push(value);
});
return dataTitle.join(',') + '\r\n' + dataMain.join('\r\n') + '\r\n' + dataTotal.join(',');
}());
alink.download = (config.title || 'table_'+ (config.index || '')) + '.' + type;
alink.download = (config.title || 'table_'+ (config.index || new Date().getTime())) + '.' + type;
document.body.appendChild(alink);
alink.click();
document.body.removeChild(alink);
@ -2085,7 +2092,51 @@ layui.define(['laytpl', 'laypage', 'layer', 'form', 'util'], function(exports){
return thisTable.call(that);
};
//需要重新render的参数名单
var dataParams = ['data', 'url', 'where', 'page', 'request', 'response'];
//重载数据 options只允许跟数据请求相关的配置信息
table.reloadData = function(id, options, deep){
var config = getThisTableConfig(id); //获取当前实例配置项
if (!config) return;
var that = thisTable.that[id];
options = options || {};
if (options.page !== undefined && !!options.page !== !!config.page) {
// 如果是否分页发生了改变
hint.error('reloadData不允许对是否分页进行切换从不分页到分页的切换反之亦然,如果需要请使用reload重载');
delete options.page;
}
//过滤options只留下跟数据请求相关的参数
layui.each(options, function (_key, _value) {
if (dataParams.indexOf(_key) === -1) {
delete options[_key];
}
});
if (options.page !== undefined) { // 针对page组件的特殊处理
if (typeof options.page === 'object') {
options.page.curr && (that.page = options.page.curr);
delete options.elem;
delete options.jump;
} else if (options.page) {
options.page = {};
}
$.extend(true, that.config, {page: options.page});
delete options.page;
}
if (options.data && options.data.constructor === Array) delete that.config.data;
deep ? $.extend(true, that.config, options) : $.extend(that.config, options);
if (!that.config.page) {
that.page = 1;
}
that.loading();
that.pullData(that.page);
return thisTable.call(that);
}
//核心入口
table.render = function(options){
var inst = new Class(options);