mirror of https://github.com/layui/layui
feat(layer): 新增 btnAsync 选项 (#2002)
* feat(layer): 新增 btnAsync 选项 * docs(layer): 添加 btnAsync 文档 * docs(layer): 添加 btnAsync 示例 * refactor: 删除按钮回调中的 loading 参数 * feat(layer): beforeEnd 回调新增第三个参数 * docs(layer): 更新文档 * docs: 优化 btnAsync 选项文档细节 * chore: 优化细节及增加注释 --------- Co-authored-by: 贤心 <3277200+sentsim@users.noreply.github.com>pull/2014/head
parent
28605f8125
commit
3fea273de6
|
@ -88,6 +88,12 @@
|
||||||
</textarea>
|
</textarea>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
<pre class="layui-code" lay-options="{preview: true, text: {preview: '异步按钮'}, codeStyle: 'height: 535px;', layout: ['preview', 'code'], tools: ['full']}">
|
||||||
|
<textarea>
|
||||||
|
{{- d.include("/layer/examples/btnasync.md") }}
|
||||||
|
</textarea>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
<h3 id="demo-skin" lay-toc="{level: 2, hot: true}">主题风格</h3>
|
<h3 id="demo-skin" lay-toc="{level: 2, hot: true}">主题风格</h3>
|
||||||
|
|
||||||
|
|
|
@ -397,6 +397,53 @@ layer.open({
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
|
[btnAsync](#options.btnAsync) <sup>2.9.12+</sup>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
<div id="options.btnAsync" lay-pid="options" class="ws-anchor">
|
||||||
|
|
||||||
|
异步按钮。开启之后,除 `layer.prompt` 的按钮外,按钮回调的返回值将支持 `boolean | Promise<boolean> | JQueryDeferred<boolean>` 类型,返回 `false` 或 `Promise.reject` 时阻止关闭。
|
||||||
|
|
||||||
|
注意,此时 `yes` 和 `btn1`(两者等效) 回调的默认行为发生了变化,即由触发时不关闭弹层变为关闭弹层。
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
```
|
||||||
|
var sleep = function (time) {
|
||||||
|
return $.Deferred(function (defer) {
|
||||||
|
setTimeout(function () {
|
||||||
|
defer.resolve();
|
||||||
|
}, time)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 下面以 confirm 层为例
|
||||||
|
layer.confirm('一个询问框的示例?', {
|
||||||
|
btnAsync: true,
|
||||||
|
btn: ['确定', '关闭'] // 按钮
|
||||||
|
},
|
||||||
|
function (index, layero, that) {
|
||||||
|
var defer = $.Deferred();
|
||||||
|
// 注: that.loading() 仅 btnAsync 开启后支持,参数为 boolean 类型,表示打开或关闭按钮的加载效果。
|
||||||
|
that.loading(true);
|
||||||
|
sleep(1000).then(defer.resolve);
|
||||||
|
return defer.promise();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>boolean</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
`false`
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
[skin](#options.skin)
|
[skin](#options.skin)
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
@ -746,7 +793,7 @@ layer.open({
|
||||||
layer.open({
|
layer.open({
|
||||||
content: '<div style="padding: 32px;"><input id="id"/></div>',
|
content: '<div style="padding: 32px;"><input id="id"/></div>',
|
||||||
/** @type {(layero: JQuery, index: number) => boolean | JQueryDeferred<boolean> | Promise<boolean>} */
|
/** @type {(layero: JQuery, index: number) => boolean | JQueryDeferred<boolean> | Promise<boolean>} */
|
||||||
beforeEnd: function(layero, index){
|
beforeEnd: function(layero, index, that){
|
||||||
return $.Deferred(function(defer){
|
return $.Deferred(function(defer){
|
||||||
var el = layero.find('#id');
|
var el = layero.find('#id');
|
||||||
var val = el.val().trim();
|
var val = el.val().trim();
|
||||||
|
@ -914,4 +961,4 @@ layer.open({
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
<button type="button" class="layui-btn layui-btn-primary" lay-on="bs_alert">alert</button>
|
||||||
|
<button type="button" class="layui-btn layui-btn-primary" lay-on="bs_confirm">confirm</button>
|
||||||
|
<button type="button" class="layui-btn layui-btn-primary" lay-on="bs_msg">msg</button>
|
||||||
|
<button type="button" class="layui-btn layui-btn-primary" lay-on="bs_open">open</button>
|
||||||
|
<button type="button" class="layui-btn layui-btn-primary" lay-on="bs_prompt">prompt(不支持)</button>
|
||||||
|
|
||||||
|
<!-- import layui -->
|
||||||
|
<script>
|
||||||
|
layui.use(function () {
|
||||||
|
var $ = layui.$
|
||||||
|
var util = layui.util;
|
||||||
|
var sleep = function (time) {
|
||||||
|
return $.Deferred(function (defer) {
|
||||||
|
setTimeout(function () {
|
||||||
|
defer.resolve();
|
||||||
|
}, time)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
var enableBtnAsync = true;
|
||||||
|
|
||||||
|
util.on({
|
||||||
|
bs_alert: function () {
|
||||||
|
layer.alert('对话框内容', {
|
||||||
|
btnAsync: enableBtnAsync,
|
||||||
|
}, function (index, layero, that) {
|
||||||
|
var defer = $.Deferred();
|
||||||
|
that.loading(true);
|
||||||
|
sleep(1000).then(defer.resolve);
|
||||||
|
return defer.promise();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
bs_confirm: function () {
|
||||||
|
layer.confirm('一个询问框的示例?', {
|
||||||
|
btnAsync: enableBtnAsync,
|
||||||
|
btn: ['确定', '关闭'] //按钮
|
||||||
|
}, function (index, layero, that) {
|
||||||
|
var defer = $.Deferred();
|
||||||
|
that.loading(true);
|
||||||
|
sleep(1000).then(defer.resolve);
|
||||||
|
return defer.promise();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
bs_msg: function () {
|
||||||
|
layer.msg('第二个回调', {
|
||||||
|
btnAsync: enableBtnAsync,
|
||||||
|
time: 20000, // 20s 后自动关闭
|
||||||
|
btn: ['明白了', '知道了'],
|
||||||
|
btn1: function (index, layero, that) {
|
||||||
|
var defer = $.Deferred();
|
||||||
|
that.loading(true);
|
||||||
|
sleep(1000).then(defer.resolve);
|
||||||
|
return defer.promise();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
bs_open: function () {
|
||||||
|
layer.open({
|
||||||
|
btnAsync: enableBtnAsync,
|
||||||
|
type: 1,
|
||||||
|
area: ['500px', '300px'],
|
||||||
|
btn: ['确定', '关闭'],
|
||||||
|
btn1: function (index, layero, that) {
|
||||||
|
var defer = $.Deferred();
|
||||||
|
that.loading(true);
|
||||||
|
sleep(1000).then(defer.resolve);
|
||||||
|
return defer.promise();
|
||||||
|
},
|
||||||
|
btn2: function (index, layero, that) {
|
||||||
|
var defer = $.Deferred();
|
||||||
|
that.loading(true);
|
||||||
|
sleep(1000).then(defer.resolve);
|
||||||
|
return defer.promise();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 不支持 btnAsync
|
||||||
|
bs_prompt: function () {
|
||||||
|
layer.prompt({
|
||||||
|
formType: 2,
|
||||||
|
value: '初始值',
|
||||||
|
title: '请输入值',
|
||||||
|
area: ['500px', '300px'] // 自定义文本域宽高
|
||||||
|
}, function (value, index, elem) {
|
||||||
|
alert(value);
|
||||||
|
layer.close(index);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -144,6 +144,8 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;}
|
||||||
.layui-layer-btn .layui-layer-btn0{border-color: transparent; background-color: #1E9FFF; color:#fff;}
|
.layui-layer-btn .layui-layer-btn0{border-color: transparent; background-color: #1E9FFF; color:#fff;}
|
||||||
.layui-layer-btn-l{text-align: left;}
|
.layui-layer-btn-l{text-align: left;}
|
||||||
.layui-layer-btn-c{text-align: center;}
|
.layui-layer-btn-c{text-align: center;}
|
||||||
|
.layui-layer-btn-is-loading{opacity:0.5 !important; cursor:not-allowed !important; cursor:wait !important; overflow:hidden; white-space:nowrap; -webkit-user-select: none; -ms-user-select: none;user-select: none;}
|
||||||
|
.layui-layer-btn-is-loading .layui-layer-btn-loading-icon{margin-right: 8px; font-size: 14px;}
|
||||||
|
|
||||||
/* 定制化 */
|
/* 定制化 */
|
||||||
.layui-layer-dialog{min-width: 240px;}
|
.layui-layer-dialog{min-width: 240px;}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* layer
|
* layer
|
||||||
* 通用 Web 弹出层组件
|
* 通用 Web 弹出层组件
|
||||||
*/
|
*/
|
||||||
|
//@ts-ignore
|
||||||
;!function(window, undefined){
|
;!function(window, undefined){
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
@ -859,6 +859,16 @@ Class.pt.move = function(){
|
||||||
return that;
|
return that;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Class.pt.btnLoading = function(btnElem, isLoading){
|
||||||
|
if(isLoading){
|
||||||
|
var loadingTpl = '<i class="layui-layer-btn-loading-icon layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop"></i>';
|
||||||
|
if(btnElem.find('.layui-layer-btn-loading-icon')[0]) return;
|
||||||
|
btnElem.addClass('layui-layer-btn-is-loading').attr({disabled: ''}).prepend(loadingTpl);
|
||||||
|
}else{
|
||||||
|
btnElem.removeClass('layui-layer-btn-is-loading').removeAttr('disabled').find('.layui-layer-btn-loading-icon').remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Class.pt.callback = function(){
|
Class.pt.callback = function(){
|
||||||
var that = this, layero = that.layero, config = that.config;
|
var that = this, layero = that.layero, config = that.config;
|
||||||
that.openLayer();
|
that.openLayer();
|
||||||
|
@ -875,18 +885,42 @@ Class.pt.callback = function(){
|
||||||
|
|
||||||
// 按钮
|
// 按钮
|
||||||
layero.find('.'+ doms[6]).children('a').on('click', function(){
|
layero.find('.'+ doms[6]).children('a').on('click', function(){
|
||||||
var index = $(this).index();
|
var btnElem = $(this);
|
||||||
if(index === 0){
|
var index = btnElem.index();
|
||||||
if(config.yes){
|
if(btnElem.attr('disabled')) return;
|
||||||
config.yes(that.index, layero, that);
|
|
||||||
} else if(config['btn1']){
|
// 若为异步按钮
|
||||||
config['btn1'](that.index, layero, that);
|
if(config.btnAsync){
|
||||||
} else {
|
var btnCallback = index === 0 ? (config.yes || config['btn1']) : config['btn'+(index+1)];
|
||||||
|
that.loading = function(isLoading){
|
||||||
|
that.btnLoading(btnElem, isLoading);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(btnCallback){
|
||||||
|
ready.promiseLikeResolve(btnCallback.call(config, that.index, layero, that))
|
||||||
|
.then(function(result){
|
||||||
|
if(result !== false){
|
||||||
|
layer.close(that.index)
|
||||||
|
}
|
||||||
|
}, function(reason){
|
||||||
|
reason !== undefined && window.console && window.console.error('layer error hint: ' + reason);
|
||||||
|
});
|
||||||
|
}else{
|
||||||
layer.close(that.index);
|
layer.close(that.index);
|
||||||
}
|
}
|
||||||
} else {
|
} else { // 普通按钮
|
||||||
var close = config['btn'+(index+1)] && config['btn'+(index+1)](that.index, layero, that);
|
if(index === 0){
|
||||||
close === false || layer.close(that.index);
|
if(config.yes){
|
||||||
|
config.yes(that.index, layero, that);
|
||||||
|
} else if(config['btn1']){
|
||||||
|
config['btn1'](that.index, layero, that);
|
||||||
|
} else {
|
||||||
|
layer.close(that.index);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var close = config['btn'+(index+1)] && config['btn'+(index+1)](that.index, layero, that);
|
||||||
|
close === false || layer.close(that.index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -926,7 +960,7 @@ Class.pt.callback = function(){
|
||||||
});
|
});
|
||||||
|
|
||||||
config.end && (ready.end[that.index] = config.end);
|
config.end && (ready.end[that.index] = config.end);
|
||||||
config.beforeEnd && (ready.beforeEnd[that.index] = config.beforeEnd);
|
config.beforeEnd && (ready.beforeEnd[that.index] = $.proxy(config.beforeEnd, config, layero, that.index, that));
|
||||||
};
|
};
|
||||||
|
|
||||||
// for ie6 恢复 select
|
// for ie6 恢复 select
|
||||||
|
@ -1000,6 +1034,18 @@ ready.restScrollbar = function(index){
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 类似 Promise.resolve
|
||||||
|
ready.promiseLikeResolve = function(value){
|
||||||
|
var deferred = $.Deferred();
|
||||||
|
|
||||||
|
if(value && typeof value.then === 'function'){
|
||||||
|
value.then(deferred.resolve, deferred.reject);
|
||||||
|
}else{
|
||||||
|
deferred.resolve(value);
|
||||||
|
}
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
/** 内置成员 */
|
/** 内置成员 */
|
||||||
|
|
||||||
window.layer = layer;
|
window.layer = layer;
|
||||||
|
@ -1307,19 +1353,7 @@ layer.close = function(index, callback){
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!hideOnClose && typeof ready.beforeEnd[index] === 'function'){
|
if(!hideOnClose && typeof ready.beforeEnd[index] === 'function'){
|
||||||
// 类似 Promise.resolve
|
ready.promiseLikeResolve(ready.beforeEnd[index]())
|
||||||
var promiseLikeResolve = function(value){
|
|
||||||
var deferred = $.Deferred();
|
|
||||||
|
|
||||||
if(value && typeof value.then === 'function'){
|
|
||||||
value.then(deferred.resolve, deferred.reject);
|
|
||||||
}else{
|
|
||||||
deferred.resolve(value);
|
|
||||||
}
|
|
||||||
return deferred.promise();
|
|
||||||
}
|
|
||||||
|
|
||||||
promiseLikeResolve(ready.beforeEnd[index](layero, index))
|
|
||||||
.then(function(result){
|
.then(function(result){
|
||||||
if(result !== false){
|
if(result !== false){
|
||||||
delete ready.beforeEnd[index];
|
delete ready.beforeEnd[index];
|
||||||
|
|
Loading…
Reference in New Issue