如何优化预算编辑Modal弹窗,实现数据回显与更新
解决弹窗数据回显与更新问题
问题现状
已实现编辑按钮触发Modal弹窗,但点击编辑时弹窗无法加载对应条目数据,修改后也无法更新原有列表数据。
解决方案
1. 完善弹窗表单元素标识
给弹窗内的表单元素添加ID,方便后续获取DOM节点:
<div class="budget-update"></div> <div class="modal" tabindex="-1"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">Want to make changes?</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> <form class="budget-update"> <select id="cashflow-update" name="income/expense" class="income/expense"> <option class="options-update" value="income">Income</option> <option class="options-update" value="expense">Expense</option> </select> <select id="catagory-update" name="Catagory" value="Catagory"> <option class="options-update" value="House Hold">House Hold</option> <option class="options-update" value="Car">Car</option> <option class="options-update" value="entertainment">Entertainment</option> <option class="options-update" value="investments">Investments</option> <option class="options-update" value="business">Business</option> <option class="options-update" value="savings">Savings</option> </select> <input id="label-update" class="label-update" type="text" placeholder="Example rent"> <input id="number-update" class="number-update" type="number" placeholder="0,0"> </form> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> <button type="button" id="save-edit" class="btn btn-primary"> <img src="/resources/Images/Save-icon.png" alt="Save Icon"> </button> </div> </div> </div> </div>
2. 修改JavaScript逻辑
(1)扩展DOM元素引用与编辑索引记录
在全局添加编辑索引变量,同时扩展el对象包含弹窗元素:
// 记录当前编辑的条目索引 let currentEditIndex = -1; const el = { list: document.querySelector(".list"), cashflow: document.querySelector("#cashflow"), catagory: document.querySelector(".catagory"), label: document.querySelector(".label"), number: document.querySelector(".number"), modal: document.querySelector(".modal"), // 弹窗表单元素引用 cashflowUpdate: document.querySelector("#cashflow-update"), catagoryUpdate: document.querySelector("#catagory-update"), labelUpdate: document.querySelector("#label-update"), numberUpdate: document.querySelector("#number-update"), saveEditBtn: document.querySelector("#save-edit") };
(2)修改editItem函数实现数据回显
接收条目索引,将对应数据填充到弹窗表单:
/*----Edit budget Entry----*/ function editItem(event, i){ currentEditIndex = i; const editData = budgetArray[i]; // 填充弹窗表单 el.cashflowUpdate.value = editData.cashflowNew; el.catagoryUpdate.value = editData.catagoryNew; el.labelUpdate.value = editData.labelNew; el.numberUpdate.value = editData.numberNew; el.modal.style.display = "block"; }
(3)实现保存修改功能
给保存按钮添加点击事件,更新数组、本地存储并重新渲染列表:
// 保存编辑逻辑 el.saveEditBtn.addEventListener('click', () => { if (currentEditIndex === -1) return; // 更新数组数据,保留原有ID和日期 budgetArray[currentEditIndex] = { ...budgetArray[currentEditIndex], cashflowNew: el.cashflowUpdate.value, catagoryNew: el.catagoryUpdate.value, labelNew: el.labelUpdate.value, numberNew: el.numberUpdate.value }; storedEntry(); renderList(); el.modal.style.display = "none"; currentEditIndex = -1; // 清空弹窗表单 el.cashflowUpdate.value = ''; el.catagoryUpdate.value = ''; el.labelUpdate.value = ''; el.numberUpdate.value = ''; });
(4)优化弹窗关闭逻辑
关闭弹窗时重置编辑索引与表单:
/*----Close Modal----*/ let close = document.querySelector(".btn-close") let xBtn = document.querySelector(".btn-secondary") close.addEventListener('click', () => { el.modal.style.display = "none"; currentEditIndex = -1; // 清空表单 el.cashflowUpdate.value = ''; el.catagoryUpdate.value = ''; el.labelUpdate.value = ''; el.numberUpdate.value = ''; }); xBtn.addEventListener('click', () => { el.modal.style.display = "none"; currentEditIndex = -1; // 清空表单 el.cashflowUpdate.value = ''; el.catagoryUpdate.value = ''; el.labelUpdate.value = ''; el.numberUpdate.value = ''; });
3. 完整修改后的JavaScript代码
/*----Storage key----*/ const BUDGETLIST_KEY = "user-key-entryList"; /*----Generate ID----*/ const createId = () =>`${Math.floor(Math.random() * 10000)}${(new Date().getTime())}`; /*----Get current Date----*/ function createdDate() { let currentDate = new Date(); let day = String(currentDate.getDate()).padStart(2, '0'); let month = String(currentDate.getMonth() + 1).padStart(2, '0'); let year = currentDate.getFullYear(); currentDate = month + '/' + day + '/' + year; return currentDate; } // 记录当前编辑的条目索引 let currentEditIndex = -1; /*----Variable Objects----*/ const el = { list: document.querySelector(".list"), cashflow: document.querySelector("#cashflow"), catagory: document.querySelector(".catagory"), label: document.querySelector(".label"), number: document.querySelector(".number"), modal: document.querySelector(".modal"), // 弹窗表单元素引用 cashflowUpdate: document.querySelector("#cashflow-update"), catagoryUpdate: document.querySelector("#catagory-update"), labelUpdate: document.querySelector("#label-update"), numberUpdate: document.querySelector("#number-update"), saveEditBtn: document.querySelector("#save-edit") }; /*----Array with local Storage----*/ let budgetArray = JSON.parse(window.localStorage.getItem(BUDGETLIST_KEY) ?? "[]"); /*----Budget list Object----*/ function makeNewBudget(){ const data = { id: createId(), cashflowNew: el.cashflow.value, catagoryNew: el.catagory.value, labelNew: el.label.value, dateNew: createdDate(), numberNew: el.number.value, }; return data; } /*----Render Budget List----*/ function renderList(){ el.list.innerHTML = budgetArray.map(function (data,i) { return `<div class="entry"> <div class="list"> <button onclick="deleteItem(event, ${i})" class="Archive" data-id="${data.id}"> <img src="../resources/Images/archive.png" alt="Archive"> </button> <button onclick="editItem(event, ${i})" class = "edit" data-id="${data.id}"> <img src="../resources/Images/edit.png" alt="Edit"> </button> <div class="input" data-id="${data.id}"></div> <label class="dateNew">${data.dateNew}</label> <label class="cashflowNew">${data.cashflowNew}</label> <label class="catagoryNew">${data.catagoryNew}</label> <label class="labelNew">${data.labelNew}</label> <label class="numberNew">${data.numberNew}</label> </div> </div>`; }); el.label.value=""; el.number.value=""; } /*----keep list after browser refreshed----*/ document.addEventListener('DOMContentLoaded', () =>{ renderList() }) /*----form validation----*/ let budgetButton = document.querySelector(".budget-button"); let label = document.querySelector(".label"); let num = document.querySelector(".number"); budgetButton.addEventListener("click", () => { if (!label.value || !num.value) { alert("please make sure all inputs are filled"); } budgetArray.push(makeNewBudget()) renderList(); storedEntry(); }); /*----Remove from array----*/ function deleteItem(event, i){ budgetArray.splice(i, 1); storedEntry() renderList(); } /*----Close Modal----*/ let close = document.querySelector(".btn-close") let xBtn = document.querySelector(".btn-secondary") close.addEventListener('click', () => { el.modal.style.display = "none"; currentEditIndex = -1; // 清空表单 el.cashflowUpdate.value = ''; el.catagoryUpdate.value = ''; el.labelUpdate.value = ''; el.numberUpdate.value = ''; }); xBtn.addEventListener('click', () => { el.modal.style.display = "none"; currentEditIndex = -1; // 清空表单 el.cashflowUpdate.value = ''; el.catagoryUpdate.value = ''; el.labelUpdate.value = ''; el.numberUpdate.value = ''; }); /*----Edit budget Entry----*/ function editItem(event, i){ currentEditIndex = i; const editData = budgetArray[i]; // 填充弹窗表单 el.cashflowUpdate.value = editData.cashflowNew; el.catagoryUpdate.value = editData.catagoryNew; el.labelUpdate.value = editData.labelNew; el.numberUpdate.value = editData.numberNew; el.modal.style.display = "block"; } // 保存编辑逻辑 el.saveEditBtn.addEventListener('click', () => { if (currentEditIndex === -1) return; // 更新数组数据,保留原有ID和日期 budgetArray[currentEditIndex] = { ...budgetArray[currentEditIndex], cashflowNew: el.cashflowUpdate.value, catagoryNew: el.catagoryUpdate.value, labelNew: el.labelUpdate.value, numberNew: el.numberUpdate.value }; storedEntry(); renderList(); el.modal.style.display = "none"; currentEditIndex = -1; // 清空弹窗表单 el.cashflowUpdate.value = ''; el.catagoryUpdate.value = ''; el.labelUpdate.value = ''; el.numberUpdate.value = ''; }); /*----Store Stored budget list----*/ function storedEntry(){ window.localStorage.setItem(BUDGETLIST_KEY, JSON.stringify(budgetArray)); }
内容的提问来源于stack exchange,提问作者Sheldon
相关产品推荐
相关产品推荐

