document.getElementById("searchForm").submit is not a function

本文探讨了在使用JavaScript进行表单提交时遇到的一个常见错误:submit不是函数。作者通过实际案例分享了解决这一问题的经验,并揭示了表单中元素名称为'submit'时可能引发的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在写代码的时候JS一直报上面这个错。搞了半天一直想不明白 。我看别的页面都是这样写了就是没有一点错。。

可能是写了一个晚上的代码。。头有点晕。。后来终于找到原因了。。浪费我两个小时啊。。杯具。。

 

有时候需要用javascript提交表单,这个时候我们会用javascript:userform.submit();可是我在这样做的时候怎么也提交不成功,报出javascript错误 Javascript Error: submit is not a function。百思不得其解,后来查阅资料才发现,在用userForm.submit() 提交表单的时候,表单里面不能有name="submit"的元素,否则在提交的 时候,该对象会和submit();方法发生混淆造成该错误!! 切记,切记!

文章转载于:http://ware.iteye.com/blog/1113250

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>总订单完成状况</title> <style> :root{ --bg:#f5faff; --panel:#fff; --border:#cce7ff; --primary:#3ca9ff; --primary-dark:#0077e6; --primary-light:#e6f4ff; --text:#003366; --text-light:#0077e6; --shadow:rgba(60,169,255,.12); } body{margin:0;background:var(--bg);font-family:"Segoe UI",Arial,"PingFang SC","Microsoft YaHei",sans-serif} .status-container{max-width:98%;margin:22px auto;background:var(--panel);border:1px solid var(--border);padding:22px 18px 30px 18px;border-radius:12px;box-shadow:0 6px 30px var(--shadow);position:relative} .status-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:18px;background:var(--bg)} .status-header h3{color:var(--text-light);letter-spacing:2px} .status-header .btns{display:flex;gap:12px} .btn{padding:7px 18px;border:none;border-radius:4px;font-size:15px;cursor:pointer;background:var(--primary);color:#fff;transition:background .2s} .btn:hover{background:var(--primary-dark)} .btn.modify{background:var(--primary-light);color:var(--text)} .btn.modify:hover{background:var(--primary-dark);color:#fff} .search-box{display:flex;align-items:center;gap:8px} .search-box input{height:32px;border:1px solid var(--primary);border-radius:4px;padding:0 10px;font-size:14px;background:#fff;color:var(--text)} table{width:100%;border-collapse:collapse;font-size:14px;color:var(--text)} thead{background-color:var(--primary-light);color:var(--text)} th,td{border:1px solid var(--border);padding:9px 7px;text-align:center} th{background:var(--primary-light);color:var(--text)} tr:nth-child(even){background:var(--bg)} .tag{border-radius:10px;padding:2px 10px;font-size:13px;display:inline-block} .tag-success{background:#d0ffd0;color:#006100} .tag-danger{background:#ffecec;color:#c00000;cursor:pointer} td:last-child{white-space:nowrap;min-width:120px} /* 弹窗 */ .modal-mask{position:fixed;left:0;top:0;width:100%;height:100%;background:rgba(0,119,230,.2);z-index:999;display:none} .modal{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);background:#fff;min-width:360px;border-radius:8px;box-shadow:0 8px 32px rgba(60,169,255,.15);padding:22px;z-index:1000;display:none} .modal-title{font-weight:bold;font-size:1.18rem;color:var(--primary-dark);margin-bottom:19px} .modal-form-row{margin-bottom:13px;display:flex;align-items:center} .modal-form-row label{width:86px;color:var(--text-light);font-size:14px} .modal-form-row input,.modal-form-row select{flex:1;height:28px;padding:0 7px;border:1px solid var(--primary);border-radius:4px;background:var(--bg);color:var(--text)} .modal-btns{text-align:right;margin-top:18px} .modal-btns .btn{margin-left:12px;background:var(--primary)} /* 分页 */ .pager-box{display:flex;align-items:center;gap:8px;position:absolute;right:22px;bottom:-80px;background:var(--primary-light);padding:6px 10px;border-radius:6px;box-shadow:0 2px 8px var(--shadow);font-size:14px;color:var(--text-light)} .pager-label input{width:46px;height:24px;text-align:center;border:1px solid var(--primary);border-radius:4px;margin:0 4px;background:#fff;color:var(--text-light)} </style> </head> <body> <div class="status-container"> <div class="status-header"> <h3>总订单完成状况</h3> <div class="btns"> <div class="search-box"> <input type="text" id="searchInput" placeholder="订单编号、产品名称...关键词查询"> <button class="btn" onclick="searchOrders()">查询</button> </div> <button class="btn" onclick="openAddModal()">增加</button> </div> </div> <table> <thead> <tr> <th>序号</th><th>销售类型</th><th>订单编号</th><th>产品编号</th><th>产品名称</th> <th>订单数量</th><th>GTM要求交期</th><th>订单评审出货日期</th> <th>电子料齐套</th><th>组装料齐套</th> <th>SMT累计出货</th><th>SMT欠订单数</th><th>SMT工厂</th> <th>组装累计出货</th><th>组装欠订单数</th><th>组装工厂</th> <th>结单状况</th><th>备注</th><th>操作</th> </tr> </thead> <tbody id="orderTableBody"><tr><td colspan="19">加载中...</td></tbody> </table> <div id="pagerBox" class="pager-box"> <button class="btn" id="btnPrev" onclick="prevPage()">上一页</button> <label class="pager-label"> 第<input type="number" id="pageInput" min="1" max="1" value="1" onkeydown="if(event.key==='Enter') jumpToPage()">页 / 共<span id="totalPages">1</span>页 </label> <button class="btn" id="btnNext" onclick="nextPage()">下一页</button> <button class="btn modify" onclick="jumpToPage()">跳转</button> </div> </div> <!-- 订单弹窗 --> <div class="modal-mask" id="modalMask"></div> <div class="modal" id="modalBox"> <div class="modal-title" id="modalTitle">新增订单</div> <form id="modalForm"> <div class="modal-form-row"><label>销售类型</label><input name="saleType" required></div> <div class="modal-form-row"><label>订单编号</label><input name="orderNo" required></div> <div class="modal-form-row"><label>产品编号</label><input name="productNo" required></div> <div class="modal-form-row"><label>产品名称</label><input name="productName" required></div> <div class="modal-form-row"><label>订单数量</label><input type="number" name="orderQuantity" required></div> <div class="modal-form-row"><label>GTM交期</label><input type="date" name="gtmDueDate"></div> <div class="modal-form-row"><label>评审出货日期</label><input type="date" name="reviewShipDate"></div> <div class="modal-form-row"><label>电子料齐套</label> <select name="materialElectronic"><option value="1">齐套</option><option value="0">未齐套</option></select></div> <div class="modal-form-row"><label>组装料齐套</label> <select name="materialAssembly"><option value="1">齐套</option><option value="0">未齐套</option></select></div> <div class="modal-form-row"><label>SMT累计出货</label><input type="number" name="smtShippedQty"></div> <div class="modal-form-row"><label>SMT欠订单数</label><input type="number" name="smtOwedQty"></div> <div class="modal-form-row"><label>SMT工厂</label><input name="smtFactory"></div> <div class="modal-form-row"><label>组装累计出货</label><input type="number" name="assemblyShippedQty"></div> <div class="modal-form-row"><label>组装欠订单数</label><input type="number" name="assemblyOwedQty"></div> <div class="modal-form-row"><label>组装工厂</label><input name="assemblyFactory"></div> <div class="modal-form-row"><label>接单状况</label><input name="receiveStatus"></div> <div class="modal-form-row"><label>备注</label><input name="remark"></div> <div class="modal-btns"> <button type="button" class="btn" onclick="closeModal()">取消</button> <button type="submit" class="btn modify" id="modalSubmitBtn">保存</button> </div> </form> </div> <!-- 通用 BOM 详情弹窗 --> <div class="modal-mask" id="bomModalMask"></div> <div class="modal" id="bomModalBox"> <div class="modal-title" id="bomModalTitle">BOM 齐套详情</div> <form id="bomModalForm"> <input type="hidden" id="bomType"> <input type="hidden" id="bomOrderNo"> <div class="modal-form-row"> <label>BOM 版本</label> <select id="bomVersionSelect" required></select> </div> <!-- 物料编码 --> <div class="modal-form-row"> <label>物料编码</label> <input type="text" id="materialCode" required placeholder="请输入物料编码"> </div> <!-- 物料名称 --> <div class="modal-form-row"> <label>物料名称</label> <input type="text" id="materialName" required placeholder="如:贴片电阻"> </div> <!-- 规格 --> <div class="modal-form-row"> <label>规格</label> <input type="text" id="specification" placeholder="如:0603 1KΩ ±1%"> </div> <!-- 技术参数 --> <div class="modal-form-row"> <label>技术参数</label> <input type="text" id="technicalParam" placeholder="如:阻值范围/温度系数"> </div> <!-- 参数值 --> <div class="modal-form-row"> <label>参数值</label> <input type="text" id="paramValue" placeholder="如:1KΩ/±100ppm/℃"> </div> <!-- 用量 --> <div class="modal-form-row"> <label>用量</label> <input type="number" id="quantity" required min="1" placeholder="单个产品所需数量"> </div> <!-- 制造商 --> <div class="modal-form-row"> <label>制造商</label> <input type="number" id="manufacturerSelect" required min="1" placeholder="单个产品所需数量"> </div> <!-- 制造商料号 --> <div class="modal-form-row"> <label>制造商料号</label> <input type="text" id="mpn" required placeholder="如:RC0603FR-071KL"> </div> <div class="modal-btns"> <button type="button" class="btn" onclick="closeBomModal()">取消</button> <button type="submit" class="btn modify">保存</button> </div> </form> </div> <!-- 电子料齐套弹窗 --> <div class="modal-mask" id="eBomModalMask"></div> <div class="modal" id="eBomModalBox"> <div class="modal-title">电子料齐套详情</div> <form id="eBomModalForm"> <div class="modal-form-row"><label>订单编号</label><input id="eBomOrderNo" readonly></div> <div class="modal-form-row"><label>BOM版本</label><select id="eBomVersionSelect" required></select></div> <div class="modal-form-row"><label>订单数量</label><input type="number" id="eBomOrderQty" min="1" required></div> <div class="modal-btns"> <button type="button" class="btn" onclick="closeEBomModal()">取消</button> <button type="submit" class="btn modify">保存</button> </div> </form> </div> <script> let editingId = null, allOrders = [], currentPage = 1, totalPages = 1; const eBomQtyCache = {}; // 已录入电子料齐套数量缓存 async function request(url, method='GET', body=null){ const res = await fetch(url, { method, headers: body ? {'Content-Type':'application/json'} : {}, body: body ? JSON.stringify(body) : undefined }); return res.json(); } async function loadOrders(keyword, page){ const tbody=document.getElementById('orderTableBody'); tbody.innerHTML='<tr><td colspan="19">加载中...</td></tr>'; try{ let url=`/api/orders?page=${page}&size=10`; if(keyword) url+=`&keyword=${encodeURIComponent(keyword)}`; const data=await request(url); allOrders=data.records; renderOrders(data.records); currentPage=data.current; totalPages=data.pages; updatePager(); }catch(e){ tbody.innerHTML='<tr><td colspan="19">加载失败</td></tr>'; } } function renderOrders(data){ const tbody=document.getElementById('orderTableBody'); if(!data.length){ tbody.innerHTML='<tr><td colspan="19">暂无数据</td></tr>'; return; } tbody.innerHTML=data.map(r=>` <tr> <td>${r.id}</td><td>${r.saleType||'-'}</td><td>${r.orderNo||'-'}</td><td>${r.productNo||'-'}</td><td>${r.productName||'-'}</td> <td>${r.orderQuantity??'-'}</td><td>${r.gtmDueDate||'-'}</td><td>${r.reviewShipDate||'-'}</td> <!-- 电子料齐套列:未齐套可点击 --> <td> <span class="tag ${r.materialElectronic?'tag-success':'tag-danger'}" style="cursor:${r.materialElectronic?'default':'pointer'}" onclick="${!r.materialElectronic?`openEBomDetailModal('${r.orderNo}',${r.orderQuantity||0})`:''}"> ${r.materialElectronic?'齐套':'未齐套'} </span> <button class="btn modify" style="font-size:12px;padding:2px 8px" onclick="openEBomDetailTable('${r.orderNo}')">详情</button> </td> <!-- 组装料齐套列:保持原状 --> <td> <span class="tag ${r.materialAssembly?'tag-success':'tag-danger'}"> ${r.materialAssembly?'齐套':'未齐套'} </span> <button class="btn modify" style="font-size:12px;padding:2px 8px" onclick="openBomDetail('assembly','${r.orderNo}',${r.orderQuantity||0})"> 详情 </button> </td> <td>${r.smtShippedQty??'-'}</td><td>${r.smtOwedQty??'-'}</td><td>${r.smtFactory||'-'}</td> <td>${r.assemblyShippedQty??'-'}</td><td>${r.assemblyOwedQty??'-'}</td><td>${r.assemblyFactory||'-'}</td> <td>${r.receiveStatus||'-'}</td><td>${r.remark||'-'}</td> <td> <button class="btn modify" onclick="openEditModal(${r.id})">修改</button> <button class="btn" style="margin-left:6px;background:#f56c6c" onclick="deleteOrder(${r.id})">删除</button> </td> </tr>`).join(''); } function searchOrders(){loadOrders(document.getElementById('searchInput').value.trim(),1);} function updatePager(){ const p=document.getElementById('pageInput'); p.max=totalPages; p.value=currentPage; document.getElementById('totalPages').textContent=totalPages; document.getElementById('btnPrev').disabled=currentPage<=1; document.getElementById('btnNext').disabled=currentPage>=totalPages; } function jumpToPage(){ const v=parseInt(document.getElementById('pageInput').value,10); if(v>=1&&v<=totalPages) loadOrders(document.getElementById('searchInput').value.trim(),v); } function prevPage(){if(currentPage>1) loadOrders(document.getElementById('searchInput').value.trim(),currentPage-1);} function nextPage(){if(currentPage<totalPages) loadOrders(document.getElementById('searchInput').value.trim(),currentPage+1);} /* 订单弹窗 */ function openAddModal(){editingId=null;resetModal('新增订单');} function openEditModal(id){ editingId=id; const r=allOrders.find(r=>r.id===id); resetModal('修改订单',r); } function resetModal(title,data={}){ document.getElementById('modalTitle').textContent=title; const f=document.getElementById('modalForm'); f.reset(); for(const k in data) if(f[k]!==undefined) f[k].value=data[k]; document.getElementById('modalMask').style.display='block'; document.getElementById('modalBox').style.display='block'; } function closeModal(){ document.getElementById('modalMask').style.display='none'; document.getElementById('modalBox').style.display='none'; } document.getElementById('modalMask').onclick=closeModal; document.getElementById('modalForm').onsubmit=async e=>{ e.preventDefault(); const fd=new FormData(e.target); const data=Object.fromEntries(fd); data.materialElectronic=data.materialElectronic==='1'; data.materialAssembly=data.materialAssembly==='1'; ['orderQuantity','smtShippedQty','smtOwedQty','assemblyShippedQty','assemblyOwedQty'] .forEach(k=>{if(data[k])data[k]=Number(data[k]);}); try{ const url=editingId?`/api/orders/${editingId}`:'/api/orders'; const meth=editingId?'PUT':'POST'; await request(url,meth,data); closeModal(); loadOrders('',currentPage); }catch{alert('保存失败');} }; async function deleteOrder(id){ if(!confirm(`确定删除订单 ${id} 吗?`)) return; try{ await request(`/api/orders/${id}`,'DELETE'); loadOrders(document.getElementById('searchInput').value.trim(),currentPage); }catch{alert('删除失败');} } /* ========= 通用 BOM 弹窗 ========= */ function openBomDetail(type, orderNo, orderQty){ document.getElementById('bomType').value = type; // electronic / assembly document.getElementById('bomOrderNo').value = orderNo; document.getElementById('bomModalTitle').textContent = (type === 'electronic' ? '电子料' : '组装料') + '齐套详情'; /* 拉取或初始化数据 */ fetchBomDetail(type, orderNo).then(data=>{ fillBomModal(data, orderQty); document.getElementById('bomModalMask').style.display='block'; document.getElementById('bomModalBox').style.display='block'; }); } async function fetchBomDetail(type, orderNo){ // 调用后端接口,返回 {bomVersion, orderQty, needQty, oweQty} const res = await request(`/api/bom_detail/${type}/${orderNo}`); return res || {}; } function fillBomModal(data, orderQty){ /* 版本下拉 */ const sel=document.getElementById('bomVersionSelect'); sel.innerHTML=''; const versions = JSON.parse(localStorage.getItem('eBomVersions')||'[]'); versions.forEach(v=>{ const opt=document.createElement('option'); opt.value=opt.textContent=v; if(v===data.bomVersion) opt.selected=true; sel.appendChild(opt); }); document.getElementById('bomOrderQty').value = data.orderQty ?? orderQty; document.getElementById('bomNeedQty').value = data.needQty ?? 0; document.getElementById('bomOweQty').value = data.oweQty ?? 0; } function closeBomModal(){ document.getElementById('bomModalMask').style.display='none'; document.getElementById('bomModalBox').style.display='none'; } document.getElementById('bomModalMask').onclick = closeBomModal; /* 保存 */ document.getElementById('bomModalForm').addEventListener('submit', async e=>{ e.preventDefault(); const type = document.getElementById('bomType').value; const orderNo= document.getElementById('bomOrderNo').value; const payload = { bomVersion : document.getElementById('bomVersionSelect').value, orderQty : Number(document.getElementById('bomOrderQty').value), needQty : Number(document.getElementById('bomNeedQty').value), oweQty : Number(document.getElementById('bomOweQty').value) }; try{ await request(`/api/bom_detail/${type}/${orderNo}`, 'POST', payload); alert('保存成功'); closeBomModal(); }catch{ alert('保存失败'); } }); /* 电子料齐套弹窗 */ function openEBomDetailModal(orderNo,orderQty){ document.getElementById('eBomOrderNo').value=orderNo; const cached=eBomQtyCache[orderNo]||0; document.getElementById('eBomOrderQty').value=cached; document.getElementById('eBomOrderQty').min=cached; const sel=document.getElementById('eBomVersionSelect'); sel.innerHTML=''; const versions=JSON.parse(localStorage.getItem('eBomVersions')||'[]'); if(!versions.length){alert('请先打开“电子料 BOM 明细”页面以同步 BOM 版本数据');return;} versions.forEach(v=>{ const opt=document.createElement('option'); opt.value=opt.textContent=v; sel.appendChild(opt); }); document.getElementById('eBomModalMask').style.display='block'; document.getElementById('eBomModalBox').style.display='block'; } function closeEBomModal(){ document.getElementById('eBomModalMask').style.display='none'; document.getElementById('eBomModalBox').style.display='none'; } document.getElementById('eBomModalMask').onclick=closeEBomModal; document.getElementById('eBomModalForm').addEventListener('submit',async e=>{ e.preventDefault(); const orderNo=document.getElementById('eBomOrderNo').value.trim(); const bomVersion=document.getElementById('eBomVersionSelect').value; const qty=Number(document.getElementById('eBomOrderQty').value); const cached=eBomQtyCache[orderNo]||0; if(qty<cached){alert('订单数量只能增加,不能减少!');return;} try{ await request('/api/electronic_bom_detail','POST',{orderNo,bomVersion,orderQty:qty}); eBomQtyCache[orderNo]=qty; alert('保存成功'); closeEBomModal(); }catch{alert('保存失败');} }); loadOrders('',1); </script> </body> </html>能不能给我当点击未齐套时页面跳转的具体流程,当我单击详情时该怎么实现页面跳转
07-20
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>生产计划排程表</title> <style> /* ======= 天空浅蓝主题 ======= */ :root{ --bg:#f5faff; --panel:#fff; --border:#cce7ff; --primary:#3ca9ff; --primary-dark:#0077e6; --primary-light:#e6f4ff; --text:#003366; --text-light:#0077e6; --shadow:rgba(60,169,255,.12); } body{margin:0;background:var(--bg);font-family:"Segoe UI",Arial,"PingFang SC","Microsoft YaHei",sans-serif} .status-container{max-width:98%;margin:22px auto;background:var(--panel);border:1px solid var(--border);padding:22px 18px 30px 18px;border-radius:12px;box-shadow:0 6px 30px var(--shadow);position:relative} .status-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:18px;background:var(--bg)} .status-header h3{color:var(--text-light);letter-spacing:2px} .status-header .btns{display:flex;gap:12px} .btn{padding:7px 18px;border:none;border-radius:4px;font-size:15px;cursor:pointer;background:var(--primary);color:#fff;transition:background .2s} .btn:hover{background:var(--primary-dark)} .btn.modify{background:var(--primary-light);color:var(--text)} .btn.modify:hover{background:var(--primary-dark);color:#fff} .search-box{display:flex;align-items:center;gap:8px} .search-box input{height:32px;border:1px solid var(--primary);border-radius:4px;padding:0 10px;font-size:14px;background:#fff;color:var(--text)} table{width:100%;border-collapse:collapse;font-size:14px;color:var(--text)} thead{background-color:var(--primary-light);color:var(--text)} th,td{border:1px solid var(--border);padding:9px 7px;text-align:center} th{background:var(--primary-light);color:var(--text)} .tag{border-radius:10px;padding:2px 10px;font-size:13px;display:inline-block} .tag-success{color:#21b97a}.tag-danger{color:#f56c6c} /* 弹窗共用 */ .modal-mask{position:fixed;inset:0;background:rgba(0,119,230,.2);z-index:999;display:none} .modal{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);background:#fff;color:var(--text);border-radius:8px;padding:22px;min-width:360px;z-index:1000;display:none} .modal-title{font-weight:bold;font-size:1.18rem;color:var(--primary-dark);margin-bottom:19px} .modal-form-row{display:flex;align-items:center;margin-bottom:13px} .modal-form-row label{width:86px;color:var(--text-light);font-size:14px} .modal-form-row input,.modal-form-row select{flex:1;height:28px;padding:0 7px;border:1px solid var(--primary);border-radius:4px;background:var(--bg);color:var(--text)} .modal-btns{text-align:right;margin-top:18px} .modal-btns .btn{margin-left:12px;background:var(--primary);color:#fff} /* 详情弹窗专属 */ .detail-modal{min-width:800px;max-width:95vw;max-height:90vh;overflow:auto} .detail-modal table th,.detail-modal table td{color:var(--text);border:1px solid var(--border);padding:6px 4px;min-width:90px;background:#fff} .detail-modal input[type=number]{width:100%;border:1px solid var(--border);border-radius:3px;padding:4px;background:#fff;color:var(--text)} .detail-btns{margin-top:15px;text-align:right} /* 分页 */ .pager-box{display:flex;align-items:center;gap:8px;position:absolute;right:22px;bottom:-80px;background:var(--primary-light);padding:6px 10px;border-radius:6px;box-shadow:0 2px 8px var(--shadow);font-size:14px;color:var(--text-light)} .pager-label input{width:46px;height:24px;text-align:center;border:1px solid var(--primary);border-radius:4px;margin:0 4px;background:#fff;color:var(--text-light)} </style> </head> <body> <div class="status-container"> <div class="status-header"> <h3>生产计划排程表</h3> <div class="btns"> <div class="search-box"> <input type="text" id="searchInput" placeholder="工序、负责人、产品名称...关键词查询"> <button class="btn" onclick="searchPlans()">查询</button> </div> <button class="btn" onclick="openAddModal()">增加</button> </div> </div> <table> <thead> <tr> <th>序号</th><th>工序</th><th>接单日期</th><th>负责人</th><th>订单跟踪号</th><th>产品代码</th> <th>产品名称</th><th>订单量</th><th>GTM出货日期</th><th>工厂入库日期</th><th>是否延误</th> <th>累计交付</th><th>待交付</th><th>结单情况</th><th>排程日期</th><th>备注</th><th>操作</th> </tr> </thead> <tbody id="planTableBody"><tr><td colspan="17">加载中...</td></tbody> </table> <div id="pagerBox" class="pager-box"> <button class="btn" id="btnPrev" onclick="prevPage()">上一页</button> <label class="pager-label"> 第<input type="number" id="pageInput" min="1" max="1" value="1" onkeydown="if(event.key==='Enter') jumpToPage()">页 / 共<span id="totalPages">1</span>页 </label> <button class="btn" id="btnNext" onclick="nextPage()">下一页</button> <button class="btn modify" onclick="jumpToPage()">跳转</button> </div> </div> <!-- 原有增删改弹窗 --> <div class="modal-mask" id="modalMask"></div> <div class="modal" id="modalBox"> <div class="modal-title" id="modalTitle">新增排程</div> <form id="modalForm"> <div class="modal-form-row"><label>工序</label><input type="text" name="processName" required></div> <div class="modal-form-row"><label>接单日期</label><input type="date" name="startDate"></div> <div class="modal-form-row"><label>负责人</label><input type="text" name="leader" required></div> <div class="modal-form-row"><label>订单跟踪号</label><input type="text" name="orderTrackingNo" required></div> <div class="modal-form-row"><label>产品代码</label><input type="text" name="productCode" required></div> <div class="modal-form-row"><label>产品名称</label><input type="text" name="productName" required></div> <div class="modal-form-row"><label>订单量</label><input type="number" name="orderQuantity" required></div> <div class="modal-form-row"><label>GTM出货日期</label><input type="date" name="shipmentDate"></div> <div class="modal-form-row"><label>工厂入库日期</label><input type="date" name="finishDate"></div> <div class="modal-form-row"><label>是否延误</label> <select name="isDelayed"><option value="1">是</option><option value="0">否</option></select></div> <div class="modal-form-row"><label>累计交付</label><input type="number" name="deliveredQty"></div> <div class="modal-form-row"><label>待交付</label><input type="number" name="pendingQty"></div> <div class="modal-form-row"><label>结单情况</label><input type="text" name="receiveStatus"></div> <div class="modal-form-row"><label>排程日期</label><input type="date" name="scheduleDate"></div> <div class="modal-form-row"><label>备注</label><input type="text" name="remark"></div> <div class="modal-btns"> <button type="button" class="btn" onclick="closeModal()">取消</button> <button type="submit" class="btn modify" id="modalSubmitBtn">保存</button> </div> </form> </div> <!-- ===== 新增:详情弹窗 ===== --> <div class="modal-mask" id="detailMask" style="display:none"></div> <div class="modal detail-modal" id="detailWrap" style="display:none"> <div class="modal-title">排程详情</div> <p>订单跟踪号:<span id="detailOrderNo"></span>    产品名称:<span id="detailProductName"></span></p> <div style="overflow-x:auto"> <table id="detailTable"> <thead><tr id="detailHeadRow"></tr></thead> <tbody> <tr id="plannedRow"><td><b>计划交付</b></td></tr> <tr id="actualRow"><td><b>实际交付</b></td></tr> </tbody> </table> </div> <div class="modal-btns"> <button class="btn modify" onclick="saveDetail()">保存</button> <button class="btn" onclick="closeDetail()">关闭</button> </div> </div> <script> let editingId=null,allPlans=[],currentPage=1,totalPages=1; async function loadPlans(k,p){const t=document.getElementById('planTableBody');t.innerHTML='<tr><td colspan="17">加载中...</td></tr>';try{let u=`http://localhost:8080/api/production_plans?page=${p}&size=10`;if(k)u+=`&keyword=${encodeURIComponent(k)}`;const r=await fetch(u),d=await r.json();allPlans=d.records;renderPlans(d.records);toggleOperationColumn();currentPage=d.current;totalPages=d.pages;updatePager();}catch{t.innerHTML='<tr><td colspan="17">加载失败</td></tr>'}} function renderPlans(d){const t=document.getElementById('planTableBody');if(!Array.isArray(d)||d.length===0){t.innerHTML='<tr><td colspan="17">暂无数据</td></tr>';return;}t.innerHTML=d.map(r=>`<tr> <td>${r.id}</td><td>${r.processName||'-'}</td><td>${r.startDate||'-'}</td><td>${r.leader||'-'}</td><td>${r.orderTrackingNo||'-'}</td> <td>${r.productCode||'-'}</td><td>${r.productName||'-'}</td><td>${r.orderQuantity??'-'}</td><td>${r.shipmentDate||'-'}</td> <td>${r.finishDate||'-'}</td><td><span class="tag ${r.isDelayed>0?'tag-danger':'tag-success'}">${r.isDelayed>0?'是':'否'}</span></td> <td>${r.deliveredQty??'-'}</td><td>${r.pendingQty??'-'}</td><td>${r.receiveStatus||'-'}</td> <td><button class="btn modify" onclick="openDetail(${r.id})">查看详情</button></td> <td>${r.remark||'-'}</td> <td><button class="btn modify" onclick="openEditModal(${r.id})">修改</button><button class="btn" style="margin-left:6px;background:#f56c6c" onclick="deletePlan(${r.id})">删除</button></td> </tr>`).join('')} function toggleOperationColumn(){const role=localStorage.getItem('role');const head=document.querySelector('th:last-child'),cells=document.querySelectorAll('td:last-child');if(role==='ADMIN'){head.style.display='';cells.forEach(c=>c.style.display='')}else{head.style.display='none';cells.forEach(c=>c.style.display='none')}} function searchPlans(){loadPlans(document.getElementById('searchInput').value.trim(),1)} function updatePager(){const i=document.getElementById('pageInput');i.max=totalPages;i.value=currentPage;document.getElementById('totalPages').textContent=totalPages;document.getElementById('btnPrev').disabled=currentPage<=1;document.getElementById('btnNext').disabled=currentPage>=totalPages} function prevPage(){if(currentPage>1)loadPlans(document.getElementById('searchInput').value.trim(),currentPage-1)} function nextPage(){if(currentPage<totalPages)loadPlans(document.getElementById('searchInput').value.trim(),currentPage+1)} function jumpToPage(){const v=parseInt(document.getElementById('pageInput').value,10);if(isNaN(v)||v<1||v>totalPages)return;loadPlans(document.getElementById('searchInput').value.trim(),v)} function openAddModal(){editingId=null;resetModal('新增排程')} function openEditModal(id){editingId=id;const r=allPlans.find(p=>p.id===id);if(!r)return;resetModal('修改排程',r)} function resetModal(title,data={}){document.getElementById('modalTitle').textContent=title;const f=document.getElementById('modalForm');f.reset();for(const k in data)if(f[k])f[k].value=data[k];document.getElementById('modalMask').style.display='block';document.getElementById('modalBox').style.display='block'} function closeModal(){document.getElementById('modalMask').style.display='none';document.getElementById('modalBox').style.display='none'} document.getElementById('modalMask').onclick=closeModal; document.getElementById('modalForm').onsubmit=async e=>{e.preventDefault();const fd=new FormData(e.target),data=Object.fromEntries(fd);data.isDelayed=data.isDelayed==='1';['orderQuantity','deliveredQty','pendingQty'].forEach(k=>{if(data[k])data[k]=Number(data[k])});try{const url=editingId?`/api/production_plans/${editingId}`:'/api/production_plans',meth=editingId?'PUT':'POST';const res=await fetch(url,{method:meth,headers:{'Content-Type':'application/json'},body:JSON.stringify(data)});if(res.ok){closeModal();loadPlans('',currentPage)}else alert('保存失败')}catch{alert('网络异常')}} async function deletePlan(id){if(!confirm(`确定删除排程 ${id} 吗?`))return;try{const res=await fetch(`/api/production_plans/${id}`,{method:'DELETE'});if(res.ok){loadPlans(document.getElementById('searchInput').value.trim(),currentPage)}else alert('删除失败')}catch{alert('网络异常')}} let editingId=null,allPlans=[],currentPage=1,totalPages=1; /* 原有函数保持不变…… */ /* ================= 详情弹窗相关 ================= */ let curDetailPlanId = null; /* 打开弹窗(原逻辑未改动) */ async function openDetail(planId) { curDetailPlanId = planId; const plan = allPlans.find(p => p.id === planId); if (!plan) return; document.getElementById('detailOrderNo').textContent = plan.orderTrackingNo; document.getElementById('detailProductName').textContent = plan.productName; /* 1. 生成最近 30 天日期 */ const dates = []; const today = new Date(); for (let i = 0; i < 30; i++) { const d = new Date(today); d.setDate(today.getDate() + i); dates.push(d.toISOString().slice(0, 10)); } /* 2. 读取已保存数据 */ let saved = {}; try { const res = await fetch(`/api/production_plans/${planId}/details`); if (res.ok) (await res.json()).forEach(it => saved[it.date] = it); } catch { /* ignore */ } /* 3. 星期行 */ const weekMap = ['日', '一', '二', '三', '四', '五', '六']; const weekRowHTML = dates .map(d => `<td>周${weekMap[new Date(d + 'T00:00:00').getDay()]}</td>`) .join(''); /* 4. 表头 */ const headRow = document.getElementById('detailHeadRow'); headRow.innerHTML = '<th></th>' + dates.map(d => `<th>${d}</th>`).join(''); /* 5. 渲染三行(计划、实际) */ const tbody = document.querySelector('#detailTable tbody'); tbody.innerHTML = `<tr id="weekRow"><td><b>星期</b></td>${weekRowHTML}</tr>` + `<tr id="plannedRow"><td><b>计划交付</b></td>${dates .map(d => `<td><input type="number" min="0" value="${saved[d]?.plannedQty ?? 0}" data-date="${d}" data-type="planned"></td>`) .join('')}</tr>` + `<tr id="actualRow"><td><b>实际交付</b></td>${dates .map(d => `<td><input type="number" min="0" value="${saved[d]?.actualQty ?? 0}" data-date="${d}" data-type="actual"></td>`) .join('')}</tr>`; /* 6. 显示弹窗 */ document.getElementById('detailMask').style.display = 'block'; document.getElementById('detailWrap').style.display = 'block'; } function closeDetail(){ document.getElementById('detailMask').style.display='none'; document.getElementById('detailWrap').style.display='none'; } /* ======= 修复后的保存函数 ======= */ async function saveDetail(){ const planId = curDetailPlanId; const dates = Array.from(document.querySelectorAll('#detailTable input[data-date]')) .map(el => el.dataset.date) .filter((v,i,a) => a.indexOf(v) === i); // 去重 const payload = dates.map(date => { const plannedInput = document.querySelector(`input[data-date="${date}"][data-type="planned"]`); const actualInput = document.querySelector(`input[data-date="${date}"][data-type="actual"]`); return { planId: planId, date: date, plannedQty: parseInt(plannedInput?.value || 0, 10), actualQty: parseInt(actualInput?.value || 0, 10) }; }); await fetch(`/api/production_plans/${planId}/details`,{ method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify(payload) }); alert('已保存'); closeDetail(); } /* ================= 初始化 ================= */ loadPlans('',1); </script> </body> </html>这是我的前端代码,为什么当点击排程数据按钮,输入计划交付数据保存后,再点击这个界面,数据就又变回0了
最新发布
07-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值