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

动态输入表格添加下拉框并实现多变量值与多总计计算

问题描述

现有一套可动态增删行的输入表格,运行状态良好,需要实现以下需求:

  • 为表格添加更多下拉选择框
  • 将<select>的value属性从原本的数字改为包含多个变量的对象,以此计算出多个维度的总计结果
    此前尝试用switch-case语句绑定变量但未生效,希望找到更简洁易维护的实现方式。
解决方案

核心思路是用产品数据映射表替代繁琐的switch-case,将每个产品对应的多属性值统一管理,同时修复原代码中遍历目标错误、逻辑分散的问题。

1. 定义产品数据映射表

把每个产品对应的各维度数值(总价、pencil、ruler、highlighter)存入一个对象,后续新增/修改产品只需更新这个映射表,无需改动逻辑代码:

const productData = {
  product1: { price: 10, pencil: 10, ruler: 11, highlighter: 13 },
  product2: { price: 14, pencil: 14, ruler: 16, highlighter: 17 },
  product3: { price: 18, pencil: 18, ruler: 19, highlighter: 20 },
  product4: { price: 22, pencil: 22, ruler: 23, highlighter: 25 },
  product5: { price: 26, pencil: 26, ruler: 27, highlighter: 29 },
  product6: { price: 30, pencil: 30, ruler: 31, highlighter: 33 }
};

2. 修改HTML结构

  • 移除冗余的<select>代码,确保模板结构统一
  • 给下拉框选项的value设置为映射表对应的产品key:
<button id="btn-add-row">Add new row</button>
<table id="my-table">
  <thead>
    <tr>
      <th>Quantity</th>
      <th>Product</th>
      <th>Total</th>
      <th></th>
    </tr>
  </thead>
  <tbody></tbody>
  <tfoot>
    <tr>
      <td colspan="3"> TOTAL = <input type="text" name="anstotal" value="0" readonly></td>
      <td></td>
    </tr>
  </tfoot>
</table>

<template id="template-row">
  <tr>
    <td><input type="number" name="qty" value="0" min="0"></td>
    <td>
      <select name="sel">
        <option value="" disabled selected>Choose a product</option>
        <option value="product1">Product one</option>
        <option value="product2">Product two</option>
        <option value="product3">Product three</option>
        <option value="product4">Product four</option>
        <option value="product5">Product five</option>
        <option value="product6">Product six</option>
      </select>
    </td>
    <td><input type="text" name="total" value="0" readonly></td>
    <td><button name="delete-row">Delete</button></td>
  </tr>
</template>

<div class="product_total">
  <div>Pencil: <span id="pencil">0</span></div>
  <div>Ruler: <span id="ruler">0</span></div>
  <div>Highlighter: <span id="highlighter">0</span></div>
</div>

3. 重构JS逻辑

合并原有的setTotals和calc函数,统一在输入变化时计算所有总计,同时修正原代码中遍历模板元素的错误:

const myTable_tBody = document.querySelector('#my-table tbody');
const templateRow = document.querySelector('#template-row');
const myTable_Total = document.querySelector('#my-table tfoot input[name="anstotal"]');
const pencilTotalEl = document.getElementById('pencil');
const rulerTotalEl = document.getElementById('ruler');
const highlighterTotalEl = document.getElementById('highlighter');

// 产品数据映射表
const productData = {
  product1: { price: 10, pencil: 10, ruler: 11, highlighter: 13 },
  product2: { price: 14, pencil: 14, ruler: 16, highlighter: 17 },
  product3: { price: 18, pencil: 18, ruler: 19, highlighter: 20 },
  product4: { price: 22, pencil: 22, ruler: 23, highlighter: 25 },
  product5: { price: 26, pencil: 26, ruler: 27, highlighter: 29 },
  product6: { price: 30, pencil: 30, ruler: 31, highlighter: 33 }
};

// 初始化第一行
AddNewRow();

// 绑定事件
document.querySelector('#btn-add-row').addEventListener('click', AddNewRow);
myTable_tBody.addEventListener('input', calculateAllTotals);
myTable_tBody.addEventListener('click', e => {
  if (e.target.matches('button[name="delete-row"]')) {
    e.target.closest('tr').remove();
    calculateAllTotals();
  }
});

// 统一计算所有总计
function calculateAllTotals() {
  let grandTotal = 0;
  let totalPencil = 0;
  let totalRuler = 0;
  let totalHighlighter = 0;

  [...myTable_tBody.rows].forEach(row => {
    const qty = row.querySelector('input[name="qty"]').valueAsNumber || 0;
    const productKey = row.querySelector('select[name="sel"]').value;
    const product = productData[productKey] || { price: 0, pencil: 0, ruler: 0, highlighter: 0 };

    // 计算当前行的总价
    const rowTotal = qty * product.price;
    row.querySelector('input[name="total"]').value = rowTotal;

    // 累加所有总计
    grandTotal += rowTotal;
    totalPencil += qty * product.pencil;
    totalRuler += qty * product.ruler;
    totalHighlighter += qty * product.highlighter;
  });

  // 更新页面显示
  myTable_Total.value = grandTotal;
  pencilTotalEl.textContent = totalPencil;
  rulerTotalEl.textContent = totalRuler;
  highlighterTotalEl.textContent = totalHighlighter;
}

// 添加新行
function AddNewRow() {
  if (myTable_tBody.rows.length < 4) {
    myTable_tBody.append(document.importNode(templateRow.content, true));
  } else {
    alert("Maximum Passenger per ticket is 4.");
  }
}

方案优势

  • 易维护:新增产品只需在productData中添加对应条目,无需修改逻辑代码
  • 逻辑统一:把分散的计算逻辑合并,减少重复操作
  • 错误处理:针对未选择产品的情况做了默认值处理,避免NaN错误
  • 扩展性强:后续要新增更多维度的统计,只需在映射表和计算逻辑中添加对应字段即可

内容的提问来源于stack exchange,提问作者Bouali Ramzi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 13:55:02