layui关联表单的方法
更新时间:2023-12-22
Layui 的关联表单是指在一个表单中,其中一个表单项的值会受到其他表单项值的影响。在实际的开发中,关联表单非常基础且常用,例如在一个订单表单中,选择了商品后需要将商品的价格填充到相应的表单项上。Layui提供了简单易用的方式来实现关联表单。本文将带领你了解Layui的关联表单方法,以及该方法的基本原理。
### 简单的关联表单实现
最简单的关联表单实现,莫过于将表单项的值存放在一个对象中,当其他表单项的值发生改变时,设置关联表单项的值即可。下面是一个简单的示例:
HTML
<div class="layui-form-item"> <label class="layui-form-label">商品名</label> <div class="layui-input-block"> <input type="text" name="goods_name" class="layui-input" id="goods_name" value=""> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">商品价格</label> <div class="layui-input-block"> <input type="text" name="goods_price" class="layui-input" id="goods_price" value=""> </div> </div>
上述示例中,我们定义了一个商品名和一个商品价格的表单项,需要实现的功能是,当商品名项的值改变时,将其对应的商品价格填充到商品价格项上。以下是其中一个实现方式:
JavaScript
layui.use(['form'], function () { var form = layui.form; // 存储商品价格 const goodsPrice = { "iPhone": "9999", "iPad": "5999", "Macbook": "12999", "iMac": "8999", "Apple Watch": "4799" } // 监听商品名字段改变事件 form.on('select(goods_name)', function (data) { $("#goods_price").val(goodsPrice[data.value]) }); });在上述实现中,我们监听了商品名表单项的select事件,并将对应的商品价格填充到商品价格表单项上。 ### 动态添加的表单项关联 当表单项是动态添加的时,我们需要使用Layui提供的元素选择器来实现关联表单。示例如下:
HTML
<div id="order-detail"> <div class="layui-form-item"> <label class="layui-form-label">商品名</label> <div class="layui-input-block"> <select name="goods_name[]" lay-search onchange="syncGoodsDetail(this)"> <option value="">请选择商品</option> <option value="iPhone">iPhone</option> <option value="iPad">iPad</option> <option value="Macbook">Macbook</option> <option value="iMac">iMac</option> <option value="Apple Watch">Apple Watch</option> </select> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">商品价格</label> <div class="layui-input-block"> <input type="text" name="goods_price[]" class="layui-input" readonly> </div> </div> </div> <button id="addGoodsItem">添加商品项</button>
上述示例中,我们定义了一个订单明细表单,当我们点击“添加商品项”时,会动态添加一组商品表单项。其中,“商品名”项是下拉框,“商品价格”项为只读输入框。当“商品名”项改变时,会自动填充对应的商品价格。
JavaScript
layui.use(['form'], function () { var form = layui.form; // 存储商品价格 const goodsPrice = { "iPhone": "9999", "iPad": "5999", "Macbook": "12999", "iMac": "8999", "Apple Watch": "4799" } // 动态添加的表单进行监听 form.on('select', function (data) { var elem = $(data.elem); if (elem.attr('name') == "goods_name[]") { var idx = elem.index('select[name="goods_name[]"]'); $('input[name="goods_price[]"]').eq(idx).val(goodsPrice[data.value]); } }); // 点击“添加商品项”按钮 $("#addGoodsItem").click(function () { var orderDetail = $("#order-detail"); var newGoodsItem = orderDetail.children(":last-child").clone(); newGoodsItem.find("select:first-child").val(""); newGoodsItem.find("input").val(""); orderDetail.append(newGoodsItem); form.render(); }); });在上述实现中,我们监听了select字段的change事件,并使用Layui的元素选择器确定了对应的“商品价格”表单项。当“商品名”项改变时,我们通过eq()方法确定表单项序号,并将对应序号的商品价格填充到相应的表单项上。在添加新的商品明细项时,我们使用了Layui的表单重渲染方法render(),确保新添加的表单项同样拥有关联效果。 ### 多级关联表单 当我们有多级关联表单需求时,直接按照上述实现方式会变得困难和繁琐。以下是一种基于递归的多级关联表单实现方式:
HTML
<div class="layui-form-item"> <label class="layui-form-label">省份</label> <div class="layui-input-block"> <select name="province" lay-filter="province" lay-search> <option value="">请选择省份</option> <option value="北京">北京</option> <option value="天津">天津</option> <option value="上海">上海</option> <option value="重庆">重庆</option> </select> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">城市</label> <div class="layui-input-block"> <select name="city" lay-filter="city" lay-search disabled> <option value="">请选择城市</option> </select> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">区县</label> <div class="layui-input-block"> <select name="county" lay-filter="county" lay-search disabled> <option value="">请选择区县</option> </select> </div> </div>
上述示例中,我们定义了三个下拉框表单项,分别代表省份、城市和区县。当用户选择了省份,城市表单项会动态填充相应的城市选择项。当用户在城市表单中选择了城市,区县表单项会动态填充。对于三个表单项的关联设置如下:
JavaScript
layui.use(['form'], function () { var form = layui.form; // 地区列表 const regions = [ {name: "北京市", children: [ {name: "北京市", children: [ {name: "东城区"}, {name: "西城区"}, {name: "朝阳区"}, {name: "丰台区"}, {name: "石景山区"}, {name: "海淀区"}, {name: "门头沟区"}, {name: "房山区"}, {name: "通州区"}, {name: "顺义区"}, {name: "昌平区"}, {name: "大兴区"}, {name: "怀柔区"}, {name: "平谷区"}, {name: "密云区"}, {name: "延庆区"} ]} ]}, {name: "天津市", children: [ {name: "天津市", children: [ {name: "和平区"}, {name: "河东区"}, {name: "河西区"}, {name: "南开区"}, {name: "河北区"}, {name: "红桥区"}, {name: "东丽区"}, {name: "西青区"}, {name: "津南区"}, {name: "北辰区"}, {name: "武清区"}, {name: "宝坻区"}, {name: "滨海新区"}, {name: "宁河区"}, {name: "静海区"}, {name: "蓟州区"} ]} ]}, {name: "上海市", children: [ {name: "上海市", children: [ {name: "黄浦区"}, {name: "徐汇区"}, {name: "长宁区"}, {name: "静安区"}, {name: "普陀区"}, {name: "虹口区"}, {name: "杨浦区"}, {name: "闵行区"}, {name: "宝山区"}, {name: "嘉定区"}, {name: "浦东新区"}, {name: "金山区"}, {name: "松江区"}, {name: "青浦区"}, {name: "奉贤区"}, {name: "崇明区"} ]} ]}, {name: "重庆市", children: [ {name: "重庆市", children: [ {name: "万州区"}, {name: "涪陵区"}, {name: "渝中区"}, {name: "大渡口区"}, {name: "江北区"}, {name: "沙坪坝区"}, {name: "九龙坡区"}, {name: "南岸区"}, {name: "北碚区"}, {name: "綦江区"}, {name: "大足区"}, {name: "渝北区"}, {name: "巴南区"}, {name: "黔江区"}, {name: "长寿区"}, {name: "江津区"}, {name: "合川区"}, {name: "永川区"}, {name: "南川区"}, {name: "璧山区"}, {name: "铜梁区"}, {name: "潼南县"}, {name: "荣昌区"}, {name: "开州区"}, {name: "梁平区"}, {name: "武隆区"}, {name: "城口县"}, {name: "丰都县"}, {name: "垫江县"}, {name: "忠县"}, {name: "云阳县"}, {name: "奉节县"}, {name: "巫山县"}, {name: "巫溪县"}, {name: "石柱土家族自治县"}, {name: "秀山土家族苗族自治县"}, {name: "酉阳土家族苗族自治县"}, {name: "彭水苗族土家族自治县"} ]} ]} ]; // 多级关联表单 function bindRegionPicker(parentElem, childrenElem, childrenData, selectedData) { var childElem = $(childrenElem); if(selectedData) { childElem.find("[value='"+selectedData+"']").attr("selected", "selected"); } form.on('select('+parentElem+')', function (data) { var regionList = childElem.find('option').remove().end(); // 清空子选项 if(data.value.length == 0) { childElem.attr('disabled', 'true'); } else { childElem.attr('disabled', false); let regionData = childrenData.filter(region => region.name === data.value)[0]; if(regionData) { $.each(regionData.children, function (i, item) { regionList.append(""); }); if(selectedData) { childElem.find("[value='"+selectedData+"']").attr("selected", "selected"); } form.render('select'); } } }); form.on('select('+childrenElem+')', function (data) { console.log(data.value); }); } bindRegionPicker('province', 'city', regions, null); bindRegionPicker('city', 'county', regions[0].children[0].children, null); });在上述实现中,我们使用了递归的方式来实现多级关联表单。我们首先定义了一个包含地区数据的数组regions,其中每个元素为一个地区节点。每个地区节点又包含name、children两个属性,分别表示地区的名称和儿子节点列表。在JS代码中,我们使用bindRegionPicker()方法来绑定每个表单项的关联,其中parentElem参数表示父节点表单项的元素标识符,childrenElem表示儿子节点表单项的元素标识符,childrenData表示对应的地区数据,selectedData表示当前表单项选中的节点名称,可以是null。在bindRegionPicker()方法中,我们根据父节点表单项选中的值,动态填充对应的儿子节点选项,实现了多级关联表单的效果。 ### 总结 本文介绍了Layui的关联表单方法实现,其中涵盖了简单的关联表单、动态表单项关联、多级关联表单三种常见场景,可以供读者在实际开发中参考使用。总之,Layui的强大和易用性让前端开发变得简单而快速。