feat(form-select): 新增 lay-append-to 属性 (#1926)

* feat(form-select): 新增 `lay-append-to` 属性

docs(form-select): 更新文档

fix: 修复定向渲染 BUG

fix: 修复点击元素外部关闭面板时的一些问题

refactor: 重命名部分变量

feat: lay.onClickOutside 新增 capture 选项

feat: lay.onClickOutside 新增 detectIframe 属性

chore: 修改部分变量命名

fix: 窗口大小改变时,面板位置异常

revert: 1fe122b

fix: 修复一些边缘情况

refactor: 将 lay-append-to-body 重命名为 lay-append-to

fix: 重新渲染时,应该移除旧的面板元素

* update code

* docs(form): 新增 `lay-append-position` 属性的文档介绍

* docs: 优化 select 在 table 多样化编辑中的示例

* docs(form-select): 增加 `lay-append-to` 的相关示例

* feat(form-select): 新增 `lay-append-position` 属性,用于设置 `select` 面板开启 `lay-append-to` 属性后的定位方式

* chore(form-select): 剔除多余代码

* docs(form-select): 优化 select 在 layer 中使用的示例
当鼠标滑动 layer 内部滚动条时移除下拉框,以规避错位

---------

Co-authored-by: 贤心 <3277200+sentsim@users.noreply.github.com>
This commit is contained in:
morning-star
2024-06-17 18:35:03 +08:00
committed by GitHub
parent d61226ae93
commit 2e5ad41aef
6 changed files with 284 additions and 98 deletions

View File

@@ -118,6 +118,8 @@ form 还可以借助*栅格*实现更灵活的响应式布局。
| lay-skin | [#详见](checkbox.html#default) | 设置 UI 风格。 `<input type="checkbox">``<input type="radio">` 元素 **私有属性** |
| lay-search | 默认不区分大小写;<br>设置`cs`区分大小写 | 给 `select` 组件开启搜索功能。`<select>` 元素 **私有属性** |
| lay-creatable <sup>2.9.7+</sup> | 无需值 | 是否允许创建新条目,需要配合 `lay-search` 使用。`<select>` 元素 **私有属性** |
| lay-append-to <sup>2.9.12+</sup> <sup>实验性</sup> | `body` | 是否将 select 面板追加到 body 元素中。`<select>` 元素 **私有属性** |
| lay-append-position <sup>2.9.12+</sup> <sup>实验性</sup> | `absolute` 绝对定位 (默认)<br>`fixed` 固定定位 | 用于设置 select 面板开启 `lay-append-to` 属性后的定位方式。`<select>` 元素 **私有属性** |
| lay-submit | 无需值 | 设置元素(一般为`<button>` 标签)触发 `submit` 提交事件 |
| lay-ignore | 无需值 | 设置表单元素忽略渲染,即让元素保留系统原始 UI 风格 |

View File

@@ -179,6 +179,62 @@ toc: true
</textarea>
</pre>
<h2 id="lay-append" lay-toc="{hot: true}">独立选择框 <sup>2.9.12+</sup></h2>
`<select>` 元素中设置 `lay-append-to="body"` 属性,可将 select 面板插入到 `<body>` 根节点下,以便让选择框从 form 结构中剥离,成为更灵活的独立选择框。借助该特性,可完美解决 select 在 table, layer 等组件中使用的若干问题。
### 1. 在 table 中使用 select
参考 table 示例: [实现多样化编辑](/docs/2/table/#demo-editmodes)
### 2. 在 layer 中使用 select
<pre class="layui-code" lay-options="{preview: true, layout: ['preview', 'code'], tools: ['full'], done: function(obj){
obj.render();
}}">
<textarea>
<button class="layui-btn" lay-on="layer-select">弹出 layer+select</button>
<!-- import layui -->
<script>
layui.use(function(){
var form = layui.form;
var table = layui.table;
var layer = layui.layer;
var util = layui.util;
// 事件
util.on({
// 在 layer 中使用 select
"layer-select": function() {
layer.open({
type: 1, // page 层类型
area: ['500px', '300px'],
title: 'layer+select',
shadeClose: true, // 点击遮罩区域,关闭弹层
maxmin: true, // 允许全屏最小化
// 注: 这里特别对 select 设置了 lay-append-position 属性,以便与 layer 的定位方式保持一致
content: '<form class="layui-form layui-padding-3" lay-filter="test"><select lay-append-to="body" lay-append-position="fixed"><option value="">请选择</option<option value="AAA">选项 A</option><option value="AAA">选项 A</option><option value="AAA">选项 A</option><option value="AAA">选项 A</option><option value="AAA">选项 A</option><option value="AAA">选项 A</option><option value="AAA">选项 A</option><option value="AAA">选项 A</option><option value="AAA">选项 A</option><option value="AAA">选项 A</option><option value="AAA">选项 A</option><option value="AAA">选项 A</option><option value="BBB">选项 B</option><option value="CCC">选项 C</option></select></form>',
success: function (layero) {
// 定向渲染 select
form.render(layero.find('.layui-form select'));
// 鼠标滑动 layer 内部滚动条时移除下拉框,以规避错位
// 若 layer 内部不存在滚动条,以下代码可删除
var selectElem = layero.find('.layui-form-select');
layero.find('.layui-layer-content').on('scroll', function() {
selectElem.removeClass('layui-form-selected');
layui.$('.layui-select-panel-wrap').remove();
});
},
});
}
});
});
</script>
</textarea>
</pre>
<h2 id="on" lay-toc="{hot: true}">选择框事件</h2>

View File

@@ -1,28 +1,19 @@
<table class="layui-hide" id="ID-table-demo-editmodes"></table>
{{!<!-- 原生 select 模板(推荐) -->
<script type="text/html" id="TPL-select-primary">
{{!<!-- select -->
<!--注: 自 2.9.12 版本开始select 可与 table 实现友好兼容。若使用旧版本,则推荐采用原生 select即添加 lay-ignore 属性)-->
<script type="text/html" id="TPL-select-demo">
{{# var cityList = d.cityList || ["北京","上海","广州","城市-1"]; }}
<select name="city" class="layui-border select-demo-primary" lay-ignore>
<option value="">原生 select</option>
{{# layui.each(cityList, function(i, v){ }}
<option value="{{= v }}" {{= v === d.city ? 'selected' : '' }}>{{= v }}</option>
{{# }); }}
</select>
</script>
<!-- layui select 在 table 中使用(不推荐。因为当 select 出现在 table 底部时,可能会撑起多余高度) -->
<script type="text/html" id="TPL-select-city">
{{# var cityList = d.cityList || ["北京","上海","广州","城市-1"]; }}
<select name="city" lay-filter="select-demo">
<select name="city" lay-filter="select-demo" lay-append-to="body">
<option value="">select 方式</option>
{{# layui.each(cityList, function(i, v){ }}
<option value="{{= v }}" {{= v === d.city ? 'selected' : '' }}>{{= v }}</option>
{{# }); }}
</select>
</script>
<!-- 推荐 -->
<!-- dropdpwn -->
<script type="text/html" id="TPL-dropdpwn-demo">
<button class="layui-btn layui-btn-primary dropdpwn-demo">
<span>{{= d.sex || '保密' }}</span>
<span>{{= d.sex || '' }}</span>
<i class="layui-icon layui-icon-down layui-font-12"></i>
</button>
</script>
@@ -45,6 +36,7 @@ layui.use(function(){
var dropdown = layui.dropdown;
var laydate = layui.laydate;
var colorpicker = layui.colorpicker;
var util = layui.util;
// 渲染
table.render({
@@ -59,49 +51,40 @@ layui.use(function(){
].join(''),
cols: [[ // 表头
{field: 'id', title: 'ID', width:80, align: 'center', fixed: 'left'},
{field: 'city', title: '原生 select', width:135, unresize: true, templet: '#TPL-select-primary'},
//{field: 'city', title: 'layui select', width:150, templet: '#TPL-select-city'},
{field: 'sex', title: 'dropdown', width:115, unresize: true, align: 'center', templet: '#TPL-dropdpwn-demo'},
{field: 'date', title: 'laydate', width:150, templet: '#TPL-laydate-demo'},
{field: 'color', title: 'color', width:80, unresize: true, align: 'center', templet: '#TPL-colorpicker-demo'},
{field: 'city', title: 'select', minWidth: 150, templet: '#TPL-select-demo'},
{field: 'sex', title: 'dropdown', width: 130, unresize: true, align: 'center', templet: '#TPL-dropdpwn-demo'},
{field: 'date', title: 'laydate', minWidth: 150, templet: '#TPL-laydate-demo'},
{field: 'color', title: 'color', width: 80, unresize: true, align: 'center', templet: '#TPL-colorpicker-demo'},
{field: 'sign', title: '文本', edit: 'textarea'}
]],
done: function(res, curr, count){
var options = this;
// 获取当前行数据
// 获取当前行数据 - 自定义方法
table.getRowData = function(tableId, elem){
var index = $(elem).closest('tr').data('index');
return table.cache[tableId][index] || {};
};
// 原生 select 事件
var tableViewElem = this.elem.next();
// 解除 tbSelect 命名空间下的所有 change 事件处理程序
tableViewElem.off("change.tbSelect");
// 将 '.select-demo-primary' 元素的 change 事件委托给 tableViewElem, 事件命名空间为 tbSelect
tableViewElem.on("change.tbSelect", ".select-demo-primary", function () {
var value = this.value; // 获取选中项 value
var data = table.getRowData(options.id, this); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
// 更新数据中对应的字段
data.city = value;
// 显示 - 仅用于演示
layer.msg('选中值: '+ value +'<br>当前行数据:'+ JSON.stringify(data));
});
// 展示数据 - 仅用于演示
var showData = function(data) {
return layer.msg('当前行最新数据:<br>'+ util.escape(JSON.stringify(data)), {
offset: '16px',
anim: 'slideDown'
});
};
// layui form select 事件
form.on('select(select-demo)', function(obj){
console.log(obj); // 获取选中项数据
var value = obj.value; // 获取选中项 value
// 获取当前行数据(如 id 等字段,以作为数据修改的索引)
var data = table.getRowData(options.id, obj.elem);
// 更新数据中对应的字段
data.city = value;
console.log(data);
// 显示当前行最新数据 - 仅用于示例展示
showData(data);
});
// dropdown 方式的下拉选择
@@ -127,8 +110,8 @@ layui.use(function(){
// 更新数据中对应的字段
data.sex = obj.title;
// 显示 - 仅用于
layer.msg('选中值: '+ obj.title +'<br>当前行数据:'+ JSON.stringify(data));
// 显示当前行最新数据 - 仅用于示例展
showData(data);
}
});
@@ -141,8 +124,8 @@ layui.use(function(){
// 更新数据中对应的字段
data.date = value;
// 显示 - 仅用于
layer.msg('选中值: '+ value +'<br>当前行数据:'+ JSON.stringify(data));
// 显示当前行最新数据 - 仅用于示例展
showData(data);
}
});
@@ -155,8 +138,8 @@ layui.use(function(){
// 更新数据中对应的字段
data.color = value;
// 显示 - 仅用于
layer.msg('选中值: '+ value +'<br>当前行数据:'+ JSON.stringify(data));
// 显示当前行最新数据 - 仅用于示例展
showData(data);
}
});
@@ -174,8 +157,8 @@ layui.use(function(){
// 编辑后续操作,如提交更新请求,以完成真实的数据更新
// …
// 显示 - 仅用于
layer.msg('编辑值: '+ value +'<br>当前行数据:'+ JSON.stringify(data));
// 显示当前行最新数据 - 仅用于示例展
showData(data);
});
// 更多编辑方式……