40 lines
24 KiB
HTML
40 lines
24 KiB
HTML
<!doctype html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>ERP 查询构建器 Demo</title>
|
||
<style>
|
||
:root{--border:#e5e7eb;--border-strong:#cfd6e2;--text:#20242b;--muted:#7b8491;--primary:#1677ff;--primary-soft:#edf5ff;--bg:#f4f6f8;--danger:#e5484d;--shadow:0 16px 44px rgba(30,41,59,.18)}
|
||
*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--text);font:14px -apple-system,BlinkMacSystemFont,"Segoe UI","Microsoft YaHei",sans-serif}button,input,select{font:inherit}button{cursor:pointer}
|
||
.page{padding:24px;max-width:1500px;margin:auto}.header{height:42px;display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}.title{font-size:20px;font-weight:650}.subtitle{color:var(--muted);font-size:12px;margin-top:4px}
|
||
.btn{height:34px;padding:0 13px;background:#fff;border:1px solid var(--border-strong);border-radius:6px;color:#303640;display:inline-flex;align-items:center;gap:6px;white-space:nowrap}.btn:hover{background:#f8fafc;border-color:#aeb9c8}.btn.primary{background:var(--primary);border-color:var(--primary);color:#fff}.btn.primary:hover{background:#0f69e8}.btn.link-btn{border:0;background:transparent;color:var(--primary);padding:0 4px}.btn.danger{color:var(--danger)}
|
||
.search-panel,.table-panel{background:#fff;border:1px solid var(--border);border-radius:8px}.search-panel{padding:14px 16px;margin-bottom:14px}.search-line{display:flex;gap:8px;align-items:center}.search{position:relative;flex:1;max-width:680px}.search input{width:100%;height:36px;border:1px solid var(--border-strong);border-radius:6px;padding:0 12px 0 35px;outline:none}.search input:focus{border-color:var(--primary);box-shadow:0 0 0 2px #1677ff16}.search .icon{position:absolute;left:12px;top:7px;color:#8c95a2;font-size:18px}.badge{padding:2px 7px;border-radius:10px;background:#dcecff;color:var(--primary);font-size:12px}.query-summary{display:flex;align-items:center;gap:9px;margin-top:10px;min-height:28px}.summary-label{font-size:12px;color:var(--muted);white-space:nowrap}.conditions{display:flex;flex-wrap:wrap;gap:7px;min-width:0}.tag{height:28px;display:flex;align-items:center;gap:5px;border:1px solid #cfe0f8;background:#f7faff;border-radius:5px;padding:0 8px;color:#394454;white-space:nowrap}.tag .label{color:#6f7b89}.tag .x{border:0;background:none;color:#8993a0;padding:0 2px;font-size:16px;line-height:1}.table-head{height:48px;padding:0 16px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid #eef0f3}.table-title{font-weight:600}.table-actions{display:flex;align-items:center;gap:10px}.muted{color:var(--muted);font-size:12px}table{width:100%;border-collapse:collapse}th,td{height:48px;padding:0 15px;text-align:left;border-bottom:1px solid #f0f1f3;white-space:nowrap}th{background:#fafbfc;color:#626a76;font-weight:500}tr:hover td{background:#fafcff}.th-label{display:inline-flex;align-items:center;gap:5px}.th-filter{border:0;background:transparent;color:#9aa3ae;padding:3px 2px;font-size:13px}.th-filter:hover{color:var(--primary)}.status{padding:3px 8px;border-radius:4px;background:#fff6df;color:#ad7200;font-size:12px}.link{color:var(--primary);margin-right:14px;cursor:pointer}
|
||
.overlay{display:none;position:fixed;inset:0;background:rgba(16,24,40,.32);z-index:20}.overlay.show{display:block}.drawer{position:absolute;right:0;top:0;width:min(820px,100%);height:100%;background:#fff;box-shadow:var(--shadow);display:flex;flex-direction:column}.drawer-head{height:64px;padding:0 22px;border-bottom:1px solid #edf0f3;display:flex;align-items:center;justify-content:space-between}.drawer-title{font-size:16px;font-weight:650}.drawer-title small{display:block;color:var(--muted);font-size:12px;font-weight:400;margin-top:4px}.close{border:0;background:none;color:#89919d;font-size:24px;line-height:1}.drawer-body{padding:18px 22px;overflow:auto;flex:1}.logic-bar{display:flex;align-items:center;gap:8px;padding:10px 12px;background:#f7f9fc;border:1px solid #e8edf3;border-radius:7px;margin-bottom:14px}.logic-bar label{color:#667180;font-size:12px}.logic-bar select{height:30px;border:1px solid var(--border-strong);background:#fff;border-radius:5px;padding:0 28px 0 9px;outline:none}.logic-hint{margin-left:auto;color:var(--muted);font-size:12px}
|
||
.builder{display:flex;flex-direction:column;gap:9px}.condition-row{display:grid;grid-template-columns:minmax(185px,1.15fr) 130px minmax(150px,1fr) 28px;gap:8px;align-items:center}.condition-row select,.condition-row input,.field-picker{height:36px;border:1px solid var(--border-strong);border-radius:6px;background:#fff;padding:0 10px;outline:none;min-width:0}.condition-row select:focus,.condition-row input:focus,.field-picker:focus{border-color:var(--primary);box-shadow:0 0 0 2px #1677ff12}.field-picker{width:100%;font-weight:500;color:#303946;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;position:relative;padding-right:28px}.field-picker:after{content:'⌄';position:absolute;right:10px;color:#8792a0}.value-wrap{min-width:0}.value-input{width:100%}.row-values{display:flex;align-items:center;gap:7px}.row-values input{flex:1}.remove-row{height:30px;width:28px;border:0;background:transparent;color:#9aa3ae;font-size:19px;border-radius:4px}.remove-row:hover{background:#fff0f0;color:var(--danger)}.condition-group{border:1px solid #d8e5f5;border-left:3px solid #78aaf1;border-radius:7px;background:#fbfdff;padding:11px 12px}.group-head{display:flex;align-items:center;gap:8px;margin-bottom:9px;color:#607084;font-size:12px}.group-head strong{font-weight:600;color:#40536b}.group-head select{height:28px;border:1px solid var(--border-strong);border-radius:5px;background:#fff;padding:0 24px 0 8px}.group-head .remove-group{margin-left:auto;border:0;background:transparent;color:#8e98a5}.group-rows{display:flex;flex-direction:column;gap:8px}.group-add{margin-top:9px;border:0;background:transparent;color:var(--primary);padding:2px 0}.add-bar{display:flex;align-items:center;gap:16px;margin-top:14px;padding-top:14px;border-top:1px dashed #e0e5eb}.add-bar .btn{height:32px}.field-guide{margin-top:18px;padding:13px 14px;background:#fafbfc;border:1px solid #edf0f3;border-radius:7px}.field-guide-title{font-size:12px;color:#667180;margin-bottom:9px}.quick-fields{display:flex;flex-wrap:wrap;gap:7px}.quick-field{height:28px;border:1px solid #d8e0ea;background:#fff;border-radius:5px;color:#435164;padding:0 9px;font-size:12px}.quick-field:hover{border-color:var(--primary);color:var(--primary);background:var(--primary-soft)}.drawer-foot{padding:13px 22px;border-top:1px solid #edf0f3;text-align:right}.drawer-foot button{margin-left:8px}
|
||
.field-pop{display:none;position:fixed;z-index:40;width:300px;max-height:min(520px,calc(100vh - 24px));background:#fff;border:1px solid var(--border);border-radius:8px;box-shadow:var(--shadow);padding:10px}.field-pop.show{display:block}.field-search{width:100%;height:32px;border:1px solid var(--border-strong);border-radius:5px;padding:0 9px;outline:none;margin-bottom:8px}.field-options{max-height:min(455px,calc(100vh - 100px));overflow:auto}.field-section{font-size:11px;color:#8b95a3;padding:7px 7px 4px}.field-option{display:flex;align-items:center;gap:7px;width:100%;height:31px;border:0;background:#fff;text-align:left;padding:0 7px;border-radius:4px;color:#3c4755}.field-option:hover{background:#f3f7fc;color:var(--primary)}.field-option .path{color:#98a2ae;font-size:11px;margin-left:auto}.toast{position:fixed;left:50%;top:25px;transform:translateX(-50%);background:#20242b;color:#fff;padding:9px 16px;border-radius:6px;display:none;z-index:50}.toast.show{display:block}
|
||
@media(max-width:760px){.page{padding:12px}.search-line{flex-wrap:wrap}.search{max-width:none;flex-basis:100%}.drawer{width:100%}.condition-row{grid-template-columns:1fr 1fr}.condition-row .value-wrap{grid-column:1 / span 2}.condition-row .remove-row{grid-column:2;justify-self:end;margin-top:-38px}.logic-hint{display:none}.query-summary{align-items:flex-start}.summary-label{padding-top:6px}}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="page">
|
||
<div class="header"><div><div class="title">费用列表</div><div class="subtitle">费用单与账单、发票、收付款状态统一查询</div></div><button class="btn primary">+ 新增</button></div>
|
||
<div class="search-panel"><div class="search-line"><div class="search"><span class="icon">⌕</span><input id="keyword" placeholder="搜索费用单号、客户、摘要…"></div><button class="btn" id="filterBtn">高级查询 <span class="badge" id="filterBadge">4</span></button><button class="btn primary" id="searchBtn">查询</button><button class="btn" id="resetBtn">重置</button></div><div class="query-summary"><span class="summary-label">当前查询</span><div class="conditions" id="conditions"></div><button class="btn link-btn" id="editQuery">编辑</button></div></div>
|
||
<div class="table-panel"><div class="table-head"><span class="table-title">费用数据</span><div class="table-actions"><span class="muted" id="resultText">已应用 4 个条件 · 共 18 条</span><button class="btn">保存视图</button></div></div><table><thead><tr><th width="45">☐</th><th><span class="th-label">费用单号 <button class="th-filter" data-field="expense.no" title="按此列添加条件">⌄</button></span></th><th><span class="th-label">客户 <button class="th-filter" data-field="expense.customer" title="按此列添加条件">⌄</button></span></th><th><span class="th-label">费用类型 <button class="th-filter" data-field="expense.type" title="按此列添加条件">⌄</button></span></th><th><span class="th-label">金额 <button class="th-filter" data-field="expense.amount" title="按此列添加条件">⌄</button></span></th><th><span class="th-label">状态 <button class="th-filter" data-field="expense.status" title="按此列添加条件">⌄</button></span></th><th><span class="th-label">创建时间 <button class="th-filter" data-field="expense.createdAt" title="按此列添加条件">⌄</button></span></th><th>操作</th></tr></thead><tbody><tr><td>□</td><td>FY20260906001</td><td>上海东方物流有限公司</td><td>海运费</td><td>¥12,800.00</td><td><span class="status">待审核</span></td><td>2026-09-06</td><td><span class="link">审核</span><span class="link">详情</span></td></tr><tr><td>□</td><td>FY20260906002</td><td>深圳华南供应链</td><td>港杂费</td><td>¥8,620.00</td><td><span class="status">待审核</span></td><td>2026-09-05</td><td><span class="link">审核</span><span class="link">详情</span></td></tr><tr><td>□</td><td>FY20260906003</td><td>宁波海联国际</td><td>拖车费</td><td>¥4,200.00</td><td><span class="status">已审核</span></td><td>2026-09-05</td><td><span class="link">详情</span></td></tr><tr><td>□</td><td>FY20260906004</td><td>上海东方物流有限公司</td><td>报关费</td><td>¥16,300.00</td><td><span class="status">待审核</span></td><td>2026-09-04</td><td><span class="link">审核</span><span class="link">详情</span></td></tr></tbody></table></div>
|
||
</div>
|
||
<div class="overlay" id="overlay"><div class="drawer"><div class="drawer-head"><div class="drawer-title">高级查询<small>当前列表列是快捷字段,也可以查询未展示的关联业务字段</small></div><button class="close" id="closeBtn">×</button></div><div class="drawer-body"><div class="logic-bar"><label>满足</label><select id="rootLogic"><option>全部条件(AND)</option><option>任一条件(OR)</option></select><span class="logic-hint">普通列条件与关联单据条件会组合成同一个查询</span></div><div class="builder" id="builder"></div><div class="add-bar"><button class="btn" id="addCondition">+ 添加条件</button><button class="btn" id="addGroup">+ 添加条件组</button></div><div class="field-guide"><div class="field-guide-title">快捷字段 · 点击即可添加</div><div class="quick-fields"><button class="quick-field" data-quick="expense.status">当前费用单 / 状态</button><button class="quick-field" data-quick="expense.amount">当前费用单 / 金额</button><button class="quick-field" data-quick="invoice.status">关联发票 / 发票状态</button><button class="quick-field" data-quick="payment.unpaidAmount">关联收付款 / 未付款金额</button></div></div></div><div class="drawer-foot"><button class="btn" id="drawerReset">重置条件</button><button class="btn" id="cancelBtn">取消</button><button class="btn primary" id="applyBtn">应用查询</button></div></div></div>
|
||
<div class="field-pop" id="fieldPop"><input class="field-search" id="fieldSearch" placeholder="搜索字段,例如:发票"><div class="field-options" id="fieldOptions"></div></div><div class="toast" id="toast"></div>
|
||
<script>
|
||
(function(){
|
||
var catalog=[{group:'当前费用单',items:[['expense.no','费用单号'],['expense.customer','客户'],['expense.type','费用类型'],['expense.amount','金额'],['expense.status','状态'],['expense.createdAt','创建时间'],['expense.creator','创建人']]},{group:'关联账单',items:[['bill.exists','账单是否存在'],['bill.status','账单状态'],['bill.amount','账单金额'],['bill.createdAt','账单日期']]},{group:'关联发票',items:[['invoice.exists','发票是否存在'],['invoice.status','发票状态'],['invoice.no','发票号码'],['invoice.amount','发票金额'],['invoice.createdAt','开票日期']]},{group:'关联收付款',items:[['payment.exists','收付款是否存在'],['payment.status','收付款状态'],['payment.unpaidAmount','未付款金额'],['payment.paidAt','付款日期']]}];var fieldMap={};catalog.forEach(function(g){g.items.forEach(function(i){fieldMap[i[0]]={label:i[1],group:g.group};});});var operators={text:[['contains','包含'],['eq','等于'],['ne','不等于'],['isNull','为空']],enum:[['eq','等于'],['ne','不等于'],['in','属于']],number:[['gt','大于'],['ge','大于等于'],['lt','小于'],['le','小于等于'],['between','介于']],date:[['eq','等于'],['ge','不早于'],['le','不晚于'],['between','介于']],exists:[['eq','是']]};var types={no:'text',customer:'text',type:'enum',amount:'number',status:'enum',createdAt:'date',creator:'text',exists:'exists',unpaidAmount:'number',paidAt:'date'};var applied=[{field:'expense.status',op:'eq',value:'待审核'},{field:'expense.amount',op:'gt',value:'10000'},{field:'invoice.status',op:'eq',value:'未开具'},{field:'payment.unpaidAmount',op:'gt',value:'0'}];var draft=[];var overlay=document.getElementById('overlay'),builder=document.getElementById('builder'),conditions=document.getElementById('conditions'),badge=document.getElementById('filterBadge'),resultText=document.getElementById('resultText'),fieldPop=document.getElementById('fieldPop'),fieldOptions=document.getElementById('fieldOptions'),fieldSearch=document.getElementById('fieldSearch'),toast=document.getElementById('toast');
|
||
function typeFor(field){return types[field.split('.').pop()]||'text'}function valueOptions(field){var k=field.split('.').pop();if(k==='status')return ['待审核','已审核','已驳回','已生成','未开具','已开具','未付款','部分付款','已付款'];if(k==='type')return ['海运费','港杂费','拖车费','报关费'];return []}function inputHtml(row){var type=typeFor(row.field),opts=valueOptions(row.field);if(type==='enum'||type==='exists')return '<select class="value-input"><option value="">请选择</option>'+opts.map(function(o){return '<option>'+o+'</option>'}).join('')+'</select>';if(type==='date')return '<input class="value-input" type="date">';if(row.op==='between')return '<div class="row-values"><input class="value-input" placeholder="最小值"><span>至</span><input class="value-input" placeholder="最大值"></div>';return '<input class="value-input" placeholder="输入值">'}
|
||
function renderBuilder(){builder.innerHTML='';draft.forEach(function(item,index){if(item.kind==='group'){builder.appendChild(makeGroup(item,index))}else builder.appendChild(makeRow(item,index,false))})}function makeFieldButton(row,index,inGroup){var b=document.createElement('button');b.type='button';b.className='field-picker';b.textContent=fieldMap[row.field].group+' / '+fieldMap[row.field].label;b.onclick=function(){openFieldPop(b,row,index,inGroup)};return b}function makeRow(row,index,inGroup){var wrap=document.createElement('div');wrap.className='condition-row';var fs=makeFieldButton(row,index,inGroup);var os=document.createElement('select');os.innerHTML=operators[typeFor(row.field)].map(function(o){return '<option value="'+o[0]+'">'+o[1]+'('+o[0]+')</option>'}).join('');os.value=row.op;os.onchange=function(){row.op=os.value;renderBuilder()};var vw=document.createElement('div');vw.className='value-wrap';vw.innerHTML=inputHtml(row);var inputs=vw.querySelectorAll('.value-input');inputs.forEach(function(inp,i){if(row.value&&inputs.length===1)inp.value=row.value;if(Array.isArray(row.value))inp.value=row.value[i]||'';inp.oninput=function(){row.value=inputs.length===1?inp.value:Array.from(inputs).map(function(x){return x.value})}});var rm=document.createElement('button');rm.className='remove-row';rm.textContent='×';rm.title='删除条件';rm.onclick=function(){if(inGroup)draft.forEach(function(x){if(x.kind==='group'){var n=x.children.indexOf(row);if(n>-1)x.children.splice(n,1)}});else draft.splice(index,1);renderBuilder()};wrap.appendChild(fs);wrap.appendChild(os);wrap.appendChild(vw);wrap.appendChild(rm);return wrap}
|
||
function makeGroup(group,index){var box=document.createElement('div');box.className='condition-group';var head=document.createElement('div');head.className='group-head';head.innerHTML='<strong>条件组</strong><span>满足</span>';var logic=document.createElement('select');logic.innerHTML='<option value="and">全部条件(AND)</option><option value="or">任一条件(OR)</option>';logic.value=group.logic||'and';logic.onchange=function(){group.logic=logic.value};head.appendChild(logic);var remove=document.createElement('button');remove.className='remove-group';remove.textContent='删除条件组';remove.onclick=function(){draft.splice(index,1);renderBuilder()};head.appendChild(remove);box.appendChild(head);var rows=document.createElement('div');rows.className='group-rows';group.children.forEach(function(row){rows.appendChild(makeRow(row,index,true))});box.appendChild(rows);var add=document.createElement('button');add.className='group-add';add.textContent='+ 在组内添加条件';add.onclick=function(){group.children.push({field:'invoice.status',op:'eq',value:''});renderBuilder()};box.appendChild(add);return box}
|
||
function openFieldPop(anchor,target){var r=anchor.getBoundingClientRect();fieldPop.style.left=Math.min(r.left,window.innerWidth-320)+'px';fieldPop.style.top=Math.min(r.bottom+5,window.innerHeight-390)+'px';fieldPop.classList.add('show');fieldPop._target=target;fieldSearch.value='';renderFieldOptions('');fieldSearch.focus()}function renderFieldOptions(query){var q=query.toLowerCase();fieldOptions.innerHTML='';catalog.forEach(function(g){var items=g.items.filter(function(i){return !q||i[1].toLowerCase().includes(q)||g.group.toLowerCase().includes(q)});if(!items.length)return;var s=document.createElement('div');s.className='field-section';s.textContent=g.group;fieldOptions.appendChild(s);items.forEach(function(i){var b=document.createElement('button');b.className='field-option';b.innerHTML=i[1]+'<span class="path">'+g.group.replace('当前费用单','当前')+'</span>';b.onclick=function(){var target=fieldPop._target;target.field=i[0];target.op=operators[typeFor(i[0])][0][0];target.value='';fieldPop.classList.remove('show');renderBuilder()};fieldOptions.appendChild(b)})})}
|
||
function cloneRows(rows){return rows.map(function(r){if(r.kind==='group')return {kind:'group',logic:r.logic,children:cloneRows(r.children)};return {field:r.field,op:r.op,value:Array.isArray(r.value)?r.value.slice():r.value}})}function operatorLabel(op){return {eq:'=',ne:'≠',gt:'>',ge:'≥',lt:'<',le:'≤',contains:'包含',between:'介于',isNull:'为空'}[op]||op}function displayValue(r){if(r.op==='isNull')return '';if(Array.isArray(r.value))return (r.value[0]||'不限')+' 至 '+(r.value[1]||'不限');return r.value||'未设置'}function countConditions(rows){return rows.reduce(function(n,r){return n+(r.kind==='group'?countConditions(r.children):1)},0)}function renderSummary(){conditions.innerHTML='';applied.forEach(function(r){var tag=document.createElement('div');tag.className='tag';if(r.kind==='group'){tag.innerHTML='<span class="label">条件组</span><span>'+countConditions(r.children)+' 个条件 · '+String(r.logic||'and').toUpperCase()+'</span>'}else{tag.innerHTML='<span class="label">'+fieldMap[r.field].label+'</span><span>'+operatorLabel(r.op)+' '+displayValue(r)+'</span>'}var x=document.createElement('button');x.className='x';x.textContent='×';x.onclick=function(){applied.splice(applied.indexOf(r),1);renderSummary()};tag.appendChild(x);conditions.appendChild(tag)});var count=countConditions(applied);badge.textContent=count;badge.style.display=count?'inline-block':'none';resultText.textContent='已应用 '+count+' 个条件 · 共 '+(count?18:128)+' 条'}function validRow(r){return r.op==='isNull'||(r.value!==''&&!(Array.isArray(r.value)&&!r.value[0]&&!r.value[1]))}function normalizeRows(rows){var out=[];rows.forEach(function(r){if(r.kind==='group'){var children=normalizeRows(r.children);if(children.length)out.push({kind:'group',logic:r.logic||'and',children:children})}else if(validRow(r))out.push(r)});return cloneRows(out)}function showDrawer(){draft=cloneRows(applied.length?applied:[{field:'expense.status',op:'eq',value:''}]);renderBuilder();overlay.classList.add('show')}function hideDrawer(){overlay.classList.remove('show');fieldPop.classList.remove('show')}
|
||
document.getElementById('filterBtn').onclick=showDrawer;document.getElementById('editQuery').onclick=showDrawer;document.getElementById('closeBtn').onclick=hideDrawer;document.getElementById('cancelBtn').onclick=hideDrawer;overlay.onclick=function(e){if(e.target===overlay)hideDrawer()};document.getElementById('addCondition').onclick=function(){draft.push({field:'expense.status',op:'eq',value:''});renderBuilder()};document.getElementById('addGroup').onclick=function(){draft.push({kind:'group',logic:'and',children:[{field:'invoice.status',op:'eq',value:''}]});renderBuilder()};document.querySelectorAll('.quick-field').forEach(function(b){b.onclick=function(){draft.push({field:b.dataset.quick,op:operators[typeFor(b.dataset.quick)][0][0],value:''});renderBuilder()}});document.querySelectorAll('.th-filter').forEach(function(b){b.onclick=function(){draft=cloneRows(applied);draft.push({field:b.dataset.field,op:operators[typeFor(b.dataset.field)][0][0],value:''});renderBuilder();overlay.classList.add('show')}});document.getElementById('drawerReset').onclick=function(){draft=[];renderBuilder()};document.getElementById('applyBtn').onclick=function(){applied=normalizeRows(draft);renderSummary();hideDrawer();showToast('查询条件已应用')};document.getElementById('resetBtn').onclick=function(){document.getElementById('keyword').value='';applied=[];renderSummary();showToast('查询条件已重置')};document.getElementById('searchBtn').onclick=function(){var k=document.getElementById('keyword').value.trim();if(k){resultText.textContent='搜索“'+k+'” · 已应用 '+countConditions(applied)+' 个条件';showToast('正在查询:'+k)}else showToast('请输入关键词,或使用高级查询')};document.getElementById('keyword').onkeydown=function(e){if(e.key==='Enter')document.getElementById('searchBtn').click()};fieldSearch.oninput=function(){renderFieldOptions(fieldSearch.value)};document.addEventListener('click',function(e){if(fieldPop.classList.contains('show')&&!fieldPop.contains(e.target)&&!e.target.classList.contains('field-picker'))fieldPop.classList.remove('show')});function showToast(t){toast.textContent=t;toast.classList.add('show');clearTimeout(window.__t);window.__t=setTimeout(function(){toast.classList.remove('show')},1500)}renderSummary();
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|