如何在可拖拽重排仪表板中隔离各Panel的FormData
解决仪表板面板FormData数据隔离问题
1. 给每个面板添加唯一标识与独立隐藏输入框
每个面板创建时生成唯一ID(自增数字或UUID均可),在面板内部嵌入专属隐藏输入框,用于存储当前面板的FormData。输入框的name和id需关联面板ID,保证唯一性。
JSP动态生成示例:
<c:forEach var="panel" items="${panels}" varStatus="status"> <div class="dashboard-panel" data-panel-id="${panel.id}"> <div class="panel-content"> <!-- 面板配置控件(下拉框、多选框等) --> </div> <!-- 隐藏输入框存储当前面板的FormData --> <input type="hidden" name="panel-form-data-${panel.id}" id="panel-form-data-${panel.id}" value="${panel.formDataJson}" /> </div> </c:forEach>
2. 新增面板时初始化独立的FormData
点击新增按钮时,生成新面板ID并初始化与已有面板不同的默认FormData,写入对应隐藏输入框,避免数据重复。
JavaScript示例:
let panelCounter = document.querySelectorAll('.dashboard-panel').length; document.getElementById('add-panel-btn').addEventListener('click', function() { panelCounter++; const newPanelId = `panel-${panelCounter}`; // 初始化新面板的独立FormData,与已有面板区分 const defaultFormData = { type: `${panelCounter}`, panellogsource: "19", fieldSelected: [], timeWindow: "Last 15 Minutes" // 根据面板类型追加对应字段,如type=2时添加aggregateType }; const formDataJson = JSON.stringify(defaultFormData); // 构建新面板DOM const newPanel = document.createElement('div'); newPanel.className = 'dashboard-panel'; newPanel.dataset.panelId = newPanelId; newPanel.innerHTML = ` <div class="panel-content"> <select name="chartType" class="chart-type-select">...</select> <!-- 其他配置控件 --> </div> <input type="hidden" name="panel-form-data-${newPanelId}" id="panel-form-data-${newPanelId}" value="${formDataJson}" /> `; document.getElementById('dashboard-container').appendChild(newPanel); // 绑定配置控件的变更事件 bindPanelFormEvents(newPanelId); });
3. 配置控件变更时同步更新对应面板的FormData
给每个面板的配置控件绑定变更事件,修改时实时更新对应隐藏输入框中的FormData,保证数据一致性。
JavaScript绑定函数示例:
function bindPanelFormEvents(panelId) { const panel = document.querySelector(`[data-panel-id="${panelId}"]`); const formDataInput = panel.querySelector(`#panel-form-data-${panelId}`); const controls = panel.querySelectorAll('select, input[type="text"], input[type="checkbox"]'); controls.forEach(control => { control.addEventListener('change', function() { let formData = JSON.parse(formDataInput.value); const controlName = this.name; // 处理多选框特殊情况 if (this.type === 'checkbox') { formData[controlName] = formData[controlName] || []; if (this.checked) { formData[controlName].push(this.value); } else { formData[controlName] = formData[controlName].filter(item => item !== this.value); } } else { formData[controlName] = this.value; } // 重新序列化写入隐藏输入框 formDataInput.value = JSON.stringify(formData); }); }); }
4. 保存时遍历获取所有面板的独立FormData
点击保存按钮时,遍历所有面板的隐藏输入框,收集每个面板的FormData,统一提交或处理。
JavaScript保存逻辑示例:
document.getElementById('save-dashboard-btn').addEventListener('click', function() { const allPanelData = []; const formDataInputs = document.querySelectorAll('input[name^="panel-form-data-"]'); formDataInputs.forEach(input => { const panelId = input.name.replace('panel-form-data-', ''); allPanelData.push({ panelId: panelId, formData: JSON.parse(input.value) }); }); // 提交到后台或进行后续处理 console.log('所有面板数据:', allPanelData); // fetch('/save-dashboard', { // method: 'POST', // headers: { 'Content-Type': 'application/json' }, // body: JSON.stringify(allPanelData) // }); });
5. 编辑面板时读取对应FormData填充控件
点击面板编辑按钮时,根据面板ID读取对应隐藏输入框的FormData,将数据填充到配置控件中。
JavaScript编辑逻辑示例:
document.addEventListener('click', function(e) { if (e.target.classList.contains('edit-panel-btn')) { const panel = e.target.closest('.dashboard-panel'); const panelId = panel.dataset.panelId; const formDataInput = panel.querySelector(`#panel-form-data-${panelId}`); const formData = JSON.parse(formDataInput.value); // 填充配置控件 panel.querySelectorAll('select, input').forEach(control => { const controlName = control.name; if (formData[controlName] === undefined) return; if (control.type === 'checkbox') { control.checked = formData[controlName].includes(control.value); } else { control.value = formData[controlName]; } }); } });
内容的提问来源于stack exchange,提问作者CypherBee
相关产品推荐
相关产品推荐

