JS 无限长form表单提交
1 简介
开发时候,总会遇到根据后台传的变量{组件数}来动态渲染组件的情况,比如后台传命令要绑定10个父子关系,则前台展开十个input组件,后台决定绑定5个福字关系,则前台展开5个input组件.再比如,每个门店可以针对每个商品类型设置安全库存,那么随着厂家生产的商品类别增加,则前端动态增加form->input组件.
思路:借用smarty魔板(没有smarty则需要js源生一个个添加组件),根据商品类别变量{$count} ,foreach渲染出表格;表格的每一行有input框.给每一行 <tr> 设置以固定字符串str+key的id,点击确定提交时,获取从str0到str{$count}的input值,集合到一个数组当中,ajax提交到api.
2 源码讲解
2.1 html部分
<table class="layui-table"> <thead> <tr> <th>产品ID</th> <th>产品型号</th> <th>产品名称</th> <th>当前库存</th> <th style="width: 15%; ">满库存值</th> <th style="width: 15%; ">低库存值</th> </tr> </thead> <tbody> {foreach $have_inventories as $key =>$vo} <tr id = "tb1tr{$key}"> <td>{$vo.product_id}</td> <td>{$vo.product.type}</td> <td>{$vo.product.name}</td> <td>{$vo.now_inventory}</td> <td><input type="text" oninput="value=value.replace(/[^\d]/g,'')" class="layui-input" placeholder="请输入" name="max_inventory" value="{$vo.max_inventory}"></td> <td><input type="text" oninput="value=value.replace(/[^\d]/g,'')" class="layui-input" placeholder="请输入" name="min_inventory" value="{$vo.min_inventory}"></td> </tr> {/foreach} {foreach $nohave_products as $key => $vo} <tr id = "tb2tr{$key}"> <td>{$vo.id}</td> <td>{$vo.type}</td> <td>{$vo.name}</td> <td>{$vo.now_inventory}</td> <td><input type="text" oninput="value=value.replace(/[^\d]/g,'')" class="layui-input" placeholder="请输入" name="max_inventory" value=""></td> <td><input type="text" oninput="value=value.replace(/[^\d]/g,'')" class="layui-input" placeholder="请输入" name="min_inventory" value=""></td> </tr> {/foreach} </tbody> </table>
2.2 js部分 (onclick事件)
var gettr1,id1,max1,min1 //初始化变量:tr1部分的节点,节点id->child值,节点id->input值 var gettr2,id2,max2,min2 var newdata = new Array(); //初始化数组 for(var i = 0;i<"{$have_count}";i++){ var itemobj = { wid : 0,wtype : 0,prid : 0,max : 0,min : 0, } itemobj.wid = "{$warehouse_id}"; itemobj.wtype = "{$warehouse_type}"; gettr1 = document.getElementById('tb1tr'+i) id1 = gettr1.children[0].innerHTML; max1 = gettr1.children[4].children[0].value; min1 = gettr1.children[5].children[0].value; max1 = (max1 == ''||max1 == undefined)? 0:max1; min1 = (min1 == ''||min1 == undefined)? 0:min1; itemobj.prid = id1; itemobj.max = max1; itemobj.min = min1; newdata.push(itemobj); } for(var i = 0;i<"{$nohave_count}";i++){ var itemobj = { wid : 0,wtype : 0,prid : 0,max : 0,min : 0, } itemobj.wid = "{$warehouse_id}"; itemobj.wtype = "{$warehouse_type}"; gettr2 = document.getElementById('tb2tr'+i) id2 = gettr2.children[0].innerHTML; max2 = gettr2.children[4].children[0].value; min2 = gettr2.children[5].children[0].value; max2 = (max2 == ''||max2 == undefined)? 0:max2; min2 = (min2 == ''||min2 == undefined)? 0:min2; itemobj.prid = id2; itemobj.max = max2; itemobj.min = min2; newdata.push(itemobj); } if(newdata.length == "{$have_count + $nohave_count}"){ $.ajax({ url: '{$action}', type: 'POST', dataType : "TEXT", data: { newdata:newdata, do:'edit' }, success:function(data){ data = eval("("+ data+ ")"); if(data.code === 0) { layer.msg(data.msg, {icon: 1}, function(){ // 关闭本iframe层 // 父页面刷新 }); } else { //报错 } } }) }else{ //报错 }
3 结尾
① 每个<tr>中有两个input,说明要用二维数组来提交(当然分成两个数组提交也可以,但没必要).js中,二维数组可以传入对象,每个对象存储一个<tr>的两个input值.
② 每次给数组添加对象时,需要重新生成一个新的对象,不然数组中所有一维数组都相同(因为是同一个对象,这个地方在下踩到了坑,为了简化代码,将对象初始化放到了全局)
③ 可以不选择id赋str+key的形式,可以直接遍历页面所有tr获取,只是个人觉得加了id将使得思路更清晰