feat(form): 优化 lay-ignore 的判断逻辑 (#2585)

* feat: 修改ignore的判断逻辑;增加ignore的开发案例;

* Update src/modules/form.js

Co-authored-by: morning-star <26325820+Sight-wcg@users.noreply.github.com>

* Update src/modules/form.js

Co-authored-by: morning-star <26325820+Sight-wcg@users.noreply.github.com>

* Update src/modules/form.js

Co-authored-by: morning-star <26325820+Sight-wcg@users.noreply.github.com>

* Update src/modules/form.js

Co-authored-by: morning-star <26325820+Sight-wcg@users.noreply.github.com>

* test(form): 优化 lay-ignore 示例布局

* docs(form): 优化 lay-ignore 文档说明

* fix(form): 修复 tips 提示风格时对 lay-ignore 目标元素的判断问题

---------

Co-authored-by: 贤心 <3277200+sentsim@users.noreply.github.com>
Co-authored-by: morning-star <26325820+Sight-wcg@users.noreply.github.com>
This commit is contained in:
augushong 2025-03-28 17:20:02 +08:00 committed by GitHub
parent 40a19ae8fd
commit 83ce0d3817
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 87 additions and 50 deletions

View File

@ -2,7 +2,7 @@
title: 表单组件 form title: 表单组件 form
toc: true toc: true
--- ---
# 表单组件 🔥 # 表单组件 🔥
> 表单组件`form`是包含输入框、选择框、复选框、开关、单选框等表单项组件的集合,主要用于对表单域进行各类动态化渲染和相关的交互操作。`form`是 Layui 最常用的组件之一。 > 表单组件`form`是包含输入框、选择框、复选框、开关、单选框等表单项组件的集合,主要用于对表单域进行各类动态化渲染和相关的交互操作。`form`是 Layui 最常用的组件之一。
@ -121,7 +121,7 @@ form 还可以借助*栅格*实现更灵活的响应式布局。
| lay-append-to <sup>2.9.12+</sup> <sup>实验性</sup> | `body` | 是否将 select 面板追加到 body 元素中。`<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-append-position <sup>2.9.12+</sup> <sup>实验性</sup> | `absolute` 绝对定位 (默认)<br>`fixed` 固定定位 | 用于设置 select 面板开启 `lay-append-to` 属性后的定位方式。`<select>` 元素 **私有属性** |
| lay-submit | 无需值 | 设置元素(一般为`<button>` 标签)触发 `submit` 提交事件 | | lay-submit | 无需值 | 设置元素(一般为`<button>` 标签)触发 `submit` 提交事件 |
| lay-ignore | 无需值 | 设置表单元素忽略渲染,即让元素保留系统原始 UI 风格 | | lay-ignore | 无需值 | 设置表单元素忽略渲染,即让元素保留系统原始 UI 风格。注 <sup>2.10.2+</sup>:该属性若设置在 `<div>` 等父元素上,则该父元素下的所有表单均可被忽略渲染。 |
<h2 id="render" lay-toc="{hot: true, level: 2}">渲染</h2> <h2 id="render" lay-toc="{hot: true, level: 2}">渲染</h2>
@ -139,12 +139,12 @@ form 还可以借助*栅格*实现更灵活的响应式布局。
<form class="layui-form" lay-filter="test"> <form class="layui-form" lay-filter="test">
动态插入的表单域 动态插入的表单域
</form> </form>
<!-- import layui --> <!-- import layui -->
<script> <script>
layui.use(function(){ layui.use(function(){
var form = layui.form; var form = layui.form;
// 当表单元素被动态插入时,需主动进行组件渲染才能显示 // 当表单元素被动态插入时,需主动进行组件渲染才能显示
form.render(); // 渲染全部表单 form.render(); // 渲染全部表单
form.render('select'); // 仅渲染 select 元素 form.render('select'); // 仅渲染 select 元素
@ -170,15 +170,15 @@ layui.use(function(){
</select> </select>
<!-- 其他表单元素 --> <!-- 其他表单元素 -->
</div> </div>
<!-- import layui --> <!-- import layui -->
<script> <script>
layui.use('form', function(){ layui.use('form', function(){
var $ = layui.$; var $ = layui.$;
var form = layui.form; var form = layui.form;
// 定向渲染(一般当表单存在动态生成时,进行渲染) // 定向渲染(一般当表单存在动态生成时,进行渲染)
// 传入需要渲染的相应表单元素的 jQuery 对象 // 传入需要渲染的相应表单元素的 jQuery 对象
form.render($('#form-id')); // 渲染 id="form-id" 的表单域中的所有表单项 form.render($('#form-id')); // 渲染 id="form-id" 的表单域中的所有表单项
form.render($('#select-id')); // 仅渲染 id="select-id" 的表单项 form.render($('#select-id')); // 仅渲染 id="select-id" 的表单项
}); });
@ -278,7 +278,7 @@ form.verify({
obj.render() obj.render()
}}"> }}">
<textarea> <textarea>
{{- d.include("/form/examples/form.verify.md") }} {{- d.include("/form/examples/form.verify.md") }}
</textarea> </textarea>
</pre> </pre>
@ -297,7 +297,7 @@ form.verify({
obj.render() obj.render()
}}"> }}">
<textarea> <textarea>
{{- d.include("/form/examples/form.validate.md") }} {{- d.include("/form/examples/form.validate.md") }}
</textarea> </textarea>
</pre> </pre>
@ -330,14 +330,14 @@ form.verify({
obj.render() obj.render()
}}"> }}">
<textarea> <textarea>
<form class="layui-form"> <form class="layui-form">
<input type="text" name="nickname" lay-verify="required" class="layui-input"> <input type="text" name="nickname" lay-verify="required" class="layui-input">
<hr> <hr>
<button class="layui-btn" lay-submit lay-filter="demo-submit">提交按钮</button> <button class="layui-btn" lay-submit lay-filter="demo-submit">提交按钮</button>
<button class="layui-btn" id="test-btn-other">普通按钮</button> <button class="layui-btn" id="test-btn-other">普通按钮</button>
</form> </form>
<!-- import layui --> <!-- import layui -->
<script> <script>
layui.use(function(){ layui.use(function(){
var $ = layui.$; var $ = layui.$;
@ -370,7 +370,7 @@ layui.use(function(){
### **提交方法** <sup>2.7+</sup> ### **提交方法** <sup>2.7+</sup>
`form.submit(filter, callback);` `form.submit(filter, callback);`
- 参数 `filter` 为表单域容器的 `lay-filter` 属性值 - 参数 `filter` 为表单域容器的 `lay-filter` 属性值
- 参数 `callback` 为执行提交事件后的回调函数 - 参数 `callback` 为执行提交事件后的回调函数
@ -384,7 +384,7 @@ layui.use(function(){
<fieldset class="layui-elem-field"> <fieldset class="layui-elem-field">
<legend>表单内部</legend> <legend>表单内部</legend>
<div class="layui-field-box"> <div class="layui-field-box">
<form class="layui-form" lay-filter="form-demo-submit"> <form class="layui-form" lay-filter="form-demo-submit">
<input type="text" name="nickname" lay-verify="required" class="layui-input"> <input type="text" name="nickname" lay-verify="required" class="layui-input">
</form> </form>
</div> </div>
@ -392,7 +392,7 @@ layui.use(function(){
<button class="layui-btn" id="test-btn-submit">任意位置按钮</button> <button class="layui-btn" id="test-btn-submit">任意位置按钮</button>
<!-- import layui --> <!-- import layui -->
<script> <script>
layui.use(function(){ layui.use(function(){
var $ = layui.$; var $ = layui.$;
@ -437,7 +437,7 @@ layui.use(function(){
form.on('select', function(data){ form.on('select', function(data){
console.log(data); console.log(data);
}); });
// 指向元素为 `<select lay-filter="test"></select>` 的选择事件 // 指向元素为 `<select lay-filter="test"></select>` 的选择事件
form.on('select(test)', function(data){ form.on('select(test)', function(data){
console.log(data); console.log(data);

View File

@ -6,7 +6,7 @@
<meta name="renderer" content="webkit"> <meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="telephone=no">
@ -140,7 +140,7 @@
<div class="layui-col-md12"> <div class="layui-col-md12">
<button class="layui-btn" id="testSubmit">立即提交</button> <button class="layui-btn" id="testSubmit">立即提交</button>
</div> </div>
</div> </div>
</form> </form>
<hr> <hr>
@ -163,7 +163,7 @@
<div class="layui-input-inline"> <div class="layui-input-inline">
<input type="text" name="vercode" lay-verify="required" autocomplete="off" class="layui-input"> <input type="text" name="vercode" lay-verify="required" autocomplete="off" class="layui-input">
</div> </div>
<div class="layui-form-mid" style="padding: 0!important;"> <div class="layui-form-mid" style="padding: 0!important;">
<button type="button" class="layui-btn layui-btn-primary" lay-on="get-vercode">获取验证码</button> <button type="button" class="layui-btn layui-btn-primary" lay-on="get-vercode">获取验证码</button>
</div> </div>
</div> </div>
@ -226,7 +226,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">选择框</label> <label class="layui-form-label">选择框</label>
<div class="layui-input-block"> <div class="layui-input-block">
@ -240,7 +240,7 @@
</select> </select>
</div> </div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">
<div class="layui-inline"> <div class="layui-inline">
<label class="layui-form-label">搜索选择框</label> <label class="layui-form-label">搜索选择框</label>
@ -309,7 +309,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="layui-form-item" pane> <div class="layui-form-item" pane>
<label class="layui-form-label">复选框</label> <label class="layui-form-label">复选框</label>
<div class="layui-input-block"> <div class="layui-input-block">
@ -398,14 +398,14 @@
} }
} }
}); });
/* /*
form.on('submit(top)', function(data){ form.on('submit(top)', function(data){
console.log(data); console.log(data);
return false; return false;
}); });
*/ */
//方法提交 //方法提交
$('#testSubmit').on('click', function(){ $('#testSubmit').on('click', function(){
form.submit('top', function(data){ form.submit('top', function(data){
@ -416,18 +416,18 @@
setTimeout(function(){ setTimeout(function(){
alert(JSON.stringify(data.field)); alert(JSON.stringify(data.field));
}) })
}); });
}); });
return false; return false;
}); });
//日期 //日期
laydate.render({ laydate.render({
elem: '#date' elem: '#date'
}); });
//初始赋值 //初始赋值
var thisValue = form.val('first', { var thisValue = form.val('first', {
'title': '测试测试测试' 'title': '测试测试测试'
@ -449,32 +449,32 @@
var elem = data.elem; var elem = data.elem;
elem.value = '通过自定义事件设置的值'; elem.value = '通过自定义事件设置的值';
}); });
//事件 //事件
form.on('select(quiz111)', function(data){ form.on('select(quiz111)', function(data){
console.log('select: ', this, data); console.log('select: ', this, data);
}); });
form.on('select(quiz)', function(data){ form.on('select(quiz)', function(data){
console.log('select.quiz', this, data); console.log('select.quiz', this, data);
}); });
form.on('select(interest)', function(data){ form.on('select(interest)', function(data){
console.log('select.interest: ', this, data); console.log('select.interest: ', this, data);
}); });
form.on('checkbox', function(data){ form.on('checkbox', function(data){
console.log(this.checked, data.elem.checked); console.log(this.checked, data.elem.checked);
}); });
form.on('switch', function(data){ form.on('switch', function(data){
console.log(data); console.log(data);
}); });
form.on('radio', function(data){ form.on('radio', function(data){
console.log(data); console.log(data);
}); });
// 提交事件 // 提交事件
form.on('submit(*)', function(data){ form.on('submit(*)', function(data){
console.log(data) console.log(data)
@ -497,16 +497,54 @@
} }
} }
}); });
}); });
</script> </script>
<h3>设置 lay-ignore 忽略渲染</h3>
<hr>
<div class="layui-form">
<div class="layui-form-item">
<div class="layui-inline">未设置 ignore 时:</div>
<div class="layui-inline">
<input type="checkbox" name="like[write]" title="checkbox">
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">忽略指令直接设置:</div>
<div class="layui-inline">
<input type="checkbox" name="like[write]" lay-ignore title="写作">
<input type="radio" name="sex" value="1" lay-ignore title="男">
<select name="quiz" lay-ignore>
<option value="">请选择</option>
<option value="AAAAA" selected>AAAAA</option>
<option value="BBBBB">BBBBB</option>
<option value="CCCCC">CCCCC</option>
<option value="DDDDD" disabled>DDDDD</option>
<option value="EEEEE">EEEEE</option>
</select>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">忽略指令父元素设置:</div>
<div class="layui-inline" lay-ignore>
<input type="checkbox" name="like[write]" title="写作">
<input type="radio" name="sex" value="1" title="男">
<select name="quiz">
<option value="">请选择</option>
<option value="AAAAA">AAAAA</option>
<option value="BBBBB">BBBBB</option>
<option value="CCCCC" selected>CCCCC</option>
<option value="DDDDD" disabled>DDDDD</option>
<option value="EEEEE">EEEEE</option>
</select>
</div>
</div>
</div>
<h3>原始表单调试:</h3> <h3>原始表单调试:</h3>
<hr> <hr>
<form id="test1" action="" target="_blank"> <form id="test1" action="" target="_blank">
<input type="radio" value="girl" disabled> <input type="radio" value="girl" disabled>
<input type="checkbox" name="love[a]"> <input type="checkbox" name="love[a]">
@ -525,5 +563,6 @@
<button type="submit">原始表单,测试提交</button> <button type="submit">原始表单,测试提交</button>
</form> </form>
<br><br>
</body> </body>
</html> </html>

View File

@ -766,7 +766,6 @@ hr.layui-border-black{border-width: 0 0 1px;}
.layui-form select, .layui-form select,
.layui-form input[type=checkbox], .layui-form input[type=checkbox],
.layui-form input[type=radio]{display: none;} .layui-form input[type=radio]{display: none;}
.layui-form *[lay-ignore]{display: initial;}
.layui-form-item{position: relative; margin-bottom: 15px; clear: both;} .layui-form-item{position: relative; margin-bottom: 15px; clear: both;}
.layui-form-item:after{content:'\20'; clear: both; display: block; height:0;} .layui-form-item:after{content:'\20'; clear: both; display: block; height:0;}

View File

@ -863,7 +863,7 @@ layui.define(['lay', 'layer', 'util'], function(exports){
var selected = $(select.options[select.selectedIndex]); // 获取当前选中项 var selected = $(select.options[select.selectedIndex]); // 获取当前选中项
var optionsFirst = select.options[0]; var optionsFirst = select.options[0];
if(typeof othis.attr('lay-ignore') === 'string') return othis.show(); if(othis.closest('[lay-ignore]').length > 0) return othis.show();
var isSearch = typeof othis.attr('lay-search') === 'string' var isSearch = typeof othis.attr('lay-search') === 'string'
var isCreatable = typeof othis.attr('lay-creatable') === 'string' && isSearch var isCreatable = typeof othis.attr('lay-creatable') === 'string' && isSearch
@ -1028,7 +1028,7 @@ layui.define(['lay', 'layer', 'util'], function(exports){
// 若为开关,则对 title 进行分隔解析 // 若为开关,则对 title 进行分隔解析
title = skin === 'switch' ? title.split('|') : [title]; title = skin === 'switch' ? title.split('|') : [title];
if(typeof othis.attr('lay-ignore') === 'string') return othis.show(); if(othis.closest('[lay-ignore]').length > 0) return othis.show();
// 处理 IE8 indeterminate 属性重新定义 get set 后无法设置值的问题 // 处理 IE8 indeterminate 属性重新定义 get set 后无法设置值的问题
if(needCheckboxFallback){ if(needCheckboxFallback){
@ -1111,7 +1111,7 @@ layui.define(['lay', 'layer', 'util'], function(exports){
var disabled = this.disabled; var disabled = this.disabled;
var skin = othis.attr('lay-skin'); var skin = othis.attr('lay-skin');
if(typeof othis.attr('lay-ignore') === 'string') return othis.show(); if(othis.closest('[lay-ignore]').length > 0) return othis.show();
if(needCheckboxFallback){ if(needCheckboxFallback){
toggleAttribute.call(radio, 'lay-form-sync-checked', radio.checked); toggleAttribute.call(radio, 'lay-form-sync-checked', radio.checked);
@ -1300,13 +1300,12 @@ layui.define(['lay', 'layer', 'util'], function(exports){
if (verst) { if (verst) {
// 提示层风格 // 提示层风格
if (verType === 'tips') { if (verType === 'tips') {
layer.tips(errorText, function(){ layer.tips(errorText, function() {
if(typeof othis.attr('lay-ignore') !== 'string'){ if (othis.closest('[lay-ignore]').length > 0) {
if(isForm2Elem){ return othis;
return othis.next(); } else if(isForm2Elem) {
} return othis.next();
} }
return othis;
}(), {tips: 1}); }(), {tips: 1});
} else if(verType === 'alert') { } else if(verType === 'alert') {
layer.alert(errorText, {title: '提示', shadeClose: true}); layer.alert(errorText, {title: '提示', shadeClose: true});