如何用JavaScript实现动态下拉选框的价格聚合求和?
动态下拉选框价格求和实现方案
已实现功能:点击按钮自动生成下拉选框并填充选项,选中选项后显示对应价格。目前无法实现多个下拉选框的价格求和,求技术支持。现有实现代码如下:
var count = 0; document.getElementById("createNewSelect").addEventListener("click", function() { count++; var selectContainer = document.getElementById("newSelectContainer"); // 创建新的select元素 var newSelect = document.createElement("select"); newSelect.className = "form-control"; newSelect.name = "fault" + count; newSelect.id = "fault" + count; var newLabel = document.createElement("label"); newLabel.className = "control-label col-md-3 col-sm-3 col-xs-12"; newLabel.textContent = "故障 " + count; var firstDiv = document.createElement("div"); firstDiv.className = "form-group"; var secondaryDiv = document.createElement("div"); secondaryDiv.className = "col-md-6 col-sm-6 col-xs-12"; var priceSpan = document.createElement("span"); priceSpan.id = "pricePlaceHolder"; // 存在id重复问题,后续需修改 fetch('/Home/GetFaultOption') .then(response => response.json()) .then(data => { const selectElement = document.getElementById(newSelect.name); // 创建占位选项 const placeholderOption = document.createElement('option'); placeholderOption.value = 0; placeholderOption.textContent = "请选择故障"; selectElement.appendChild(placeholderOption); data.forEach(option => { const optionElement = document.createElement('option'); optionElement.value = option.Id; optionElement.textContent = option.Option; selectElement.appendChild(optionElement); }); }) .catch(error => { console.error('发生错误:', error); }); // 将创建的元素添加到容器 selectContainer.append(firstDiv); firstDiv.appendChild(newLabel); firstDiv.appendChild(secondaryDiv); secondaryDiv.appendChild(newSelect); secondaryDiv.appendChild(priceSpan); $(function() { // 循环绑定事件存在重复绑定问题 for (var i = 1; i <= count; i++) { document.getElementById("fault" + i).addEventListener("change", function() { var selectedValue = this.value; var priceHolder = this.nextElementSibling; $.ajax({ method: "GET", url: "/Home/GetPrice?selectedFaultId=" + selectedValue, }).done(function(d) { priceHolder.textContent = "(" + d.UnitPrice + " $)"; }.bind(this)).fail(function(d) { if (d.UnitPrice !== undefined) { alert("发生错误。"); } }); }); } }); });
解决方案步骤:
- 添加总价显示元素
在页面合适位置添加用于展示总价的区域:
<div id="totalPriceContainer" class="form-group"> <label class="control-label col-md-3 col-sm-3 col-xs-12">总价</label> <div class="col-md-6 col-sm-6 col-xs-12"> <span id="totalPrice">0 $</span> </div> </div>
- 修复priceSpan的id重复问题
创建价格显示span时设置唯一id,并添加统一类名方便后续遍历:
var priceSpan = document.createElement("span"); priceSpan.id = "pricePlaceHolder" + count; // 设置唯一标识 priceSpan.className = "price-item"; // 添加统一类名
- 编写价格求和函数
新增函数遍历所有价格元素,提取数值并计算总和:
function calculateTotalPrice() { let total = 0; // 遍历所有价格显示元素 document.querySelectorAll(".price-item").forEach(span => { const priceText = span.textContent.trim(); if (priceText) { // 提取数字部分,去除括号和$符号 const price = parseFloat(priceText.replace(/[()$]/g, "")); if (!isNaN(price)) { total += price; } } }); // 更新总价显示,保留两位小数 document.getElementById("totalPrice").textContent = total.toFixed(2) + " $"; }
- 优化事件监听逻辑并调用求和函数
移除重复的循环绑定逻辑,直接给当前新生成的select添加事件监听,并在价格更新后调用求和函数:
// 替换原有的$(function(){...})代码块 newSelect.addEventListener("change", function() { var selectedValue = this.value; var priceHolder = this.nextElementSibling; $.ajax({ method: "GET", url: "/Home/GetPrice?selectedFaultId=" + selectedValue, }).done(function(d) { priceHolder.textContent = "(" + d.UnitPrice + " $)"; // 更新价格后立即计算总价 calculateTotalPrice(); }.bind(this)).fail(function() { priceHolder.textContent = ""; calculateTotalPrice(); // 出错时同步更新总价 alert("获取价格失败。"); }); });
修改后的完整代码:
var count = 0; // 价格求和函数 function calculateTotalPrice() { let total = 0; document.querySelectorAll(".price-item").forEach(span => { const priceText = span.textContent.trim(); if (priceText) { const price = parseFloat(priceText.replace(/[()$]/g, "")); if (!isNaN(price)) { total += price; } } }); document.getElementById("totalPrice").textContent = total.toFixed(2) + " $"; } document.getElementById("createNewSelect").addEventListener("click", function() { count++; var selectContainer = document.getElementById("newSelectContainer"); // 创建新的select元素 var newSelect = document.createElement("select"); newSelect.className = "form-control"; newSelect.name = "fault" + count; newSelect.id = "fault" + count; var newLabel = document.createElement("label"); newLabel.className = "control-label col-md-3 col-sm-3 col-xs-12"; newLabel.textContent = "故障 " + count; var firstDiv = document.createElement("div"); firstDiv.className = "form-group"; var secondaryDiv = document.createElement("div"); secondaryDiv.className = "col-md-6 col-sm-6 col-xs-12"; var priceSpan = document.createElement("span"); priceSpan.id = "pricePlaceHolder" + count; priceSpan.className = "price-item"; fetch('/Home/GetFaultOption') .then(response => response.json()) .then(data => { const selectElement = document.getElementById(newSelect.name); const placeholderOption = document.createElement('option'); placeholderOption.value = 0; placeholderOption.textContent = "请选择故障"; selectElement.appendChild(placeholderOption); data.forEach(option => { const optionElement = document.createElement('option'); optionElement.value = option.Id; optionElement.textContent = option.Option; selectElement.appendChild(optionElement); }); }) .catch(error => { console.error('发生错误:', error); }); // 将元素添加到容器 selectContainer.append(firstDiv); firstDiv.appendChild(newLabel); firstDiv.appendChild(secondaryDiv); secondaryDiv.appendChild(newSelect); secondaryDiv.appendChild(priceSpan); // 为当前新生成的select添加change事件 newSelect.addEventListener("change", function() { var selectedValue = this.value; var priceHolder = this.nextElementSibling; $.ajax({ method: "GET", url: "/Home/GetPrice?selectedFaultId=" + selectedValue, }).done(function(d) { priceHolder.textContent = "(" + d.UnitPrice + " $)"; calculateTotalPrice(); }.bind(this)).fail(function() { priceHolder.textContent = ""; calculateTotalPrice(); alert("获取价格失败。"); }); }); });
内容的提问来源于stack exchange,提问作者Furkan Türkyılmaz
相关产品推荐
相关产品推荐

