批量审批功能的前端form表单ajax提交多文件多数据
实现的功能:
勾选需要批量修改的信息,点击批量审批按钮,弹出一个用boostrap框架做的模态框,显示出勾选内容的信息,并且填写了内容,上传了多文件之后,通过ajax发送数据。
第一步:先获取选中项该行中需要的数据
//选中项的信息取出来 $('.checkone:checked').each(function () { flow_id += $(this).val() + ','; var name = $(this).parents('tr').find('.name').text().trim();//获取名字 var Appro_Theme = $(this).parents('tr').find('.Appro_Theme').text().trim();//获取主题 var Appro_ID = $(this).parents('tr').find('.Appro_ID').text().trim();//获取流水号 var infoItem = {}; infoItem.name = name;//存入对象 infoItem.theme = Appro_Theme; infoItem.apid = Appro_ID; info.push(infoItem);//info是定义的全局变量 }); console.log(info,"选择框的值");//取出来就是重复名字
因为我先在弹出框显示的内容是这样,看图:
所以我需要对数据进行构造一下,才好循环渲染在我的这个弹出框里面
第二步:重构数据
// 获取选中的信息显示在弹出窗口中( 一 二) // 一: 重组数据结构,去重 var nameArr = [] for (let i = 0; i < info.length; i++) { nameArr.push(info[i].name) } var setarr = Array.from(new Set(nameArr)) newInfo = []; //全局info for (var i = 0; i < setarr.length; i++) { var t = { name: setarr[i] } t.thems = []; t.appid = []; for (var j = 0; j < info.length; j++) { if (info[j].name == setarr[i]) { t.thems.push(info[j].theme); t.appid.push(info[j].apid); } } newInfo.push(t) } console.log(newInfo,"组出来的结果")
展开thems主题看一下,是不是对应的数据
好的,满足我想要渲染的需求,接下来就是弹出框的显示
第三步:弹出框内容显示
首先看一下,我想实现的页面效果,有点丑,先不管那么多。
因为可能有很多主题,也有很多人,弹出框的高宽固定大小,并且设置overflow-y:auto;就会出现滚动条。可以继续往下拉
弹出框代码实现:
html部分
<!--审批--> <div id="approvalBUI" style="display:none; cursor: default; "> <div class="modal-content"> <div class="modal-header">申请表信息</div> <div class="modal-body"> <div class="bootbox-body"> <form id="fromGroup" class="form-inline"></form> </div> <div class="modal-footer"> <button onclick="return batchflow();" data-bb-handler="delete" type="button" class="btn btn-sm btn-danger"> 保存 </button> <button id="close2" data-bb-handler="close" type="button" class="btn btn-sm"> 取消 </button> </div> </div> </div>
js部分:
//二: 弹出框渲染 var formtext = ''; Array.from(newInfo).forEach(item => { var ulist = ''; // 主题内容展示 Array.from(item.thems).forEach(text => { ulist = ulist + `<li>${text}</li>` }); formtext = formtext + ` <div class="list marginB-10"> <div class="boldtext">申请人: <span class="modal_name">${item.name}</span> </div><ul class="theme">`+ ulist + `</ul> <div class="option-uoload marginB-10"> <div class="option-label"> <select name="State" class="form-control optionstate"> <option value="2">同意</option> <option value="3">驳回</option> </select> </div> </div> <div class="boldtext">审批理由</div> <textarea class="form-control formdes" placeholder="理由填写" name="opinion"></textarea> <div class="boldtext marginB-10">操作</div> <fieldset class="upload-fieldset marginB-10"> <div class="upload-wrap"> <input type="file" name="fujian[0]"> <a class="addPerson" class="btn-add">+</a> <input type="button" value="重置" class="reset"> </div> <div class="shangchuandiv"></div> </fieldset> <hr> </div> ` }); $('#fromGroup').html(formtext);
第四步:获取信息,通过fromdata添加数据,ajax发送请求
接下来,就是点击弹出框的保存按钮了,这个地方,我要得到的数据有申请人、申请人的几个主题、理由、几个文件、审核状态,通通传过去。先贴代码:
// 弹出框点击保存事件 function batchflow() { //newinfo是全局变量,保存了用户信息 在这个对象上又添加了操作状态、申请理由、数量文件 $('.list').each(function(index){ var state = $(this).find('.optionstate').val(); //操作状态:同意/驳回 var des = $(this).find('.formdes').val(); //申请理由 fiels =$(this).find('.upload-fieldset').find(':file');//文件 newInfo[index].files=[]; fiels.each(function(){ newInfo[index].files.push($(this)["0"].files); }) newInfo[index].state=state; newInfo[index].des=des; }); // console.log(newInfo,"最终点击按钮保存数据"); newInfo.forEach(index=>{ var data = new FormData(); data.append('name',index.name); data.append('thems',index.thems); data.append('state',index.state); data.append('appid',index.appid); data.append('des',index.des);
//data.append('files',index.files); for(let i = 0;i<index.files.length;i++){ data.append("files"+i,index.files[i]["0"]); } // console.log(data); $.ajax({ url:"{:url('Approval/batchflow')}", type:'post', data:data, processData:false,//不处理数据 contentType: false, success:function(msg){ console.log(msg); } }) }); }
一开始,我是用 data.append('files',index.files); 发现,传过去,并没有用,他会把files识别成 [object FileList][object FileList]
所有的数据,我是采用json对象来存储的,所以,formdata加入了files的时候,是加入了一个files对象数组,所以对于多个文件。
解决思路是:先传一个文件,并且,先弄一个文件来试试看,能不能传成功,如果行了,再进行多个文件的遍历。貌似不能append一个对象数组,所以采取遍历的方式来一个一个文件append进去。
所以上面的代码就是这样来的:
上传文件测试一下
点击保存
我展开第一个看一下文件是否加进去,以及其他的等等都加进去没有,看到可以了,文件也存起来了。
在控制台看一下,看发过去的参数是怎样的。
问题一:我没有想上面一样 data.append("files"+i,index.files[i]["0"]); 字符串拼接跟上 下标i,去掉试一下,后台会受到怎么样的数据
上传文件试一下
在这儿看preview结果可见下图
在这个地放看header
会发现,同名files会显示最后一个文件。
这个到时候看后台需要什么样的数据了吧
全部代码:
/* 点击批量审批按钮 */ function flowstate() { var flow_id = ""; //选中项的信息取出来 $('.checkone:checked').each(function () { flow_id += $(this).val() + ','; var name = $(this).parents('tr').find('.name').text().trim();//获取名字 var Appro_Theme = $(this).parents('tr').find('.Appro_Theme').text().trim();//获取主题 var Appro_ID = $(this).parents('tr').find('.Appro_ID').text().trim();//获取流水号 var infoItem = {}; infoItem.name = name;//存入对象 infoItem.theme = Appro_Theme; infoItem.apid = Appro_ID; info.push(infoItem); }); console.log(info,"选择框的值");//取出来就是重复名字 // 获取选中的信息显示在弹出窗口中( 一 二) // 一: 重组数据结构,去重 var nameArr = [] for (let i = 0; i < info.length; i++) { nameArr.push(info[i].name) } var setarr = Array.from(new Set(nameArr)) newInfo = []; //全局info for (var i = 0; i < setarr.length; i++) { var t = { name: setarr[i] } t.thems = []; t.appid = []; for (var j = 0; j < info.length; j++) { if (info[j].name == setarr[i]) { t.thems.push(info[j].theme); t.appid.push(info[j].apid); } } newInfo.push(t) } console.log(newInfo,"组出来的结果") //二: 弹出框渲染 var formtext = ''; Array.from(newInfo).forEach(item => { var ulist = ''; // 主题内容展示 Array.from(item.thems).forEach(text => { ulist = ulist + `<li>${text}</li>` }); formtext = formtext + ` <div class="list marginB-10"> <div class="boldtext">申请人: <span class="modal_name">${item.name}</span> </div><ul class="theme">`+ ulist + `</ul> <div class="option-uoload marginB-10"> <div class="option-label"> <select name="State" class="form-control optionstate"> <option value="2">同意</option> <option value="3">驳回</option> </select> </div> </div> <div class="boldtext">审批理由</div> <textarea class="form-control formdes" placeholder="理由填写" name="opinion"></textarea> <div class="boldtext marginB-10">操作</div> <fieldset class="upload-fieldset marginB-10"> <div class="upload-wrap"> <input type="file" name="fujian[0]"> <a class="addPerson" class="btn-add">+</a> <input type="button" value="重置" class="reset"> </div> <div class="shangchuandiv"></div> </fieldset> <hr> </div> ` }); $('#fromGroup').html(formtext); } // 弹出框点击保存事件 function batchflow() { //newinfo是全局变量,保存了用户信息 在这个对象上又添加了操作状态、申请理由、数量文件 $('.list').each(function(index){ var state = $(this).find('.optionstate').val(); //操作状态:同意/驳回 var des = $(this).find('.formdes').val(); //申请理由 fiels =$(this).find('.upload-fieldset').find(':file');//文件 newInfo[index].files=[]; fiels.each(function(){ newInfo[index].files.push($(this)["0"].files); }) newInfo[index].state=state; newInfo[index].des=des; }); console.log(newInfo,"最终点击按钮保存数据"); newInfo.forEach(index=>{ var data = new FormData(); data.append('name',index.name); data.append('thems',index.thems); data.append('state',index.state); data.append('appid',index.appid); data.append('des',index.des); data.append('dd',index.files); for(let i = 0;i<index.files.length;i++){ data.append("files"+i,index.files[i]["0"]); } console.log(data); $.ajax({ url:"{:url('Approval/batchflow')}", type:'post', data:data, processData:false,//不处理数据 contentType: false, success:function(msg){ console.log(msg); } }) }); }