You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化预算编辑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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 20:39:14