求助:基于select与radio输入计算价格并显示于number输入框
问题描述
需要基于表单的select input和radio input的组合数据计算价格,结果显示在input type="number"的value中,原代码无法实现该功能。
原HTML代码:
<form action="" method="post" id="regForm" > <select id="st" name="st" form="regForm" required > <option value="" disabled selected>Select period...</option> <option value="1">1 DAY</option> <option value="2.9">3 DAYS</option> <option value="5" >7 DAYS</option> <option value="18" >30 DAYS</option> </select> <div class="buttonFrame"> <h4>Select a version</h4> <input type="radio" name="plan" class="planBtn" id="planBtn1" value="0" required /> <label for="planBtn1"><h5><center>FREE</center></h5> </label> <input type="radio" name="plan" class="planBtn" id="planBtn2" value="90" required /> <label for="planBtn2"><h5><center>BASIC</center></h5> </label> <input type="radio" name="plan" class="planBtn" id="planBtn3" value="120" required /> <label for="planBtn3"><h5><center>STANDARD</center></h5> </label> </div> <label for="price"><text>YOUR PRICE: </text> <input type="number" id="regPrice" name="price" form="regForm" readonly value="getTotal()" /> <text> EUR</text> </label> <input type="submit" name="submit" id="submit" value="SUBMIT" /> </form>
原JavaScript代码:
const a1 = document.getElementById("st"); const regPrice = document.getElementById("regPrice"); [a1].forEach(field=> field.addEventListener('change', getTotal)); function getTotal() { if (document.getElementById('planBtn1').checked) { var e1 = parseInt(a1.options[a1.selectedIndex].value); var e2 = 0; try{ regPrice = e1*e2; } catch(e){ console.log(e.message); } } else if (document.getElementById('planBtn2').checked) { var e1 = parseInt(a1.options[a1.selectedIndex].value); var e2 = 90; try{ regPrice = e1*e2; } catch(e){ console.log(e.message); } } else if (document.getElementById('planBtn3').checked) { var e1 = parseInt(a1.options[a1.selectedIndex].value); var e2 = 120; try{ regPrice = e1*e2; } catch(e){ console.log(e.message); } } }
修正方案
问题分析
- 仅给
select绑定了change事件,切换radio时不会触发价格计算 - 错误地直接给DOM元素变量赋值,需设置元素的
value属性 - 使用
parseInt处理带小数的周期值会丢失精度,应改用parseFloat - HTML中
regPrice的初始值写为getTotal()无法自动执行,需设为默认值 - 代码冗余,可直接获取选中radio的value简化逻辑
修正后的HTML
<form action="" method="post" id="regForm"> <select id="st" name="st" required> <option value="" disabled selected>Select period...</option> <option value="1">1 DAY</option> <option value="2.9">3 DAYS</option> <option value="5">7 DAYS</option> <option value="18">30 DAYS</option> </select> <div class="buttonFrame"> <h4>Select a version</h4> <input type="radio" name="plan" class="planBtn" id="planBtn1" value="0" required /> <label for="planBtn1"> <h5><center>FREE</center></h5> </label> <input type="radio" name="plan" class="planBtn" id="planBtn2" value="90" required /> <label for="planBtn2"> <h5><center>BASIC</center></h5> </label> <input type="radio" name="plan" class="planBtn" id="planBtn3" value="120" required /> <label for="planBtn3"> <h5><center>STANDARD</center></h5> </label> </div> <label for="price"> <text>YOUR PRICE: </text> <input type="number" id="regPrice" name="price" readonly value="0" /> <text> EUR</text> </label> <input type="submit" name="submit" id="submit" value="SUBMIT" /> </form>
修正后的JavaScript
const periodSelect = document.getElementById("st"); const priceInput = document.getElementById("regPrice"); const planRadios = document.querySelectorAll(".planBtn"); // 给select和所有radio绑定change事件 periodSelect.addEventListener('change', calculateTotal); planRadios.forEach(radio => radio.addEventListener('change', calculateTotal)); function calculateTotal() { // 获取选中的周期值(保留小数) const periodValue = parseFloat(periodSelect.value); // 获取选中的radio值 const planValue = parseFloat(document.querySelector('input[name="plan"]:checked')?.value || 0); // 计算并设置价格,处理未选择的情况 if (!isNaN(periodValue) && !isNaN(planValue)) { priceInput.value = periodValue * planValue; } else { priceInput.value = 0; } }
关键修改点
- 给所有radio按钮添加
change事件监听,确保切换方案时触发计算 - 使用
parseFloat处理周期值,保留小数精度 - 通过
document.querySelector('input[name="plan"]:checked')直接获取选中的radio,简化判断逻辑 - 设置
priceInput.value而非直接给变量赋值,正确更新输入框内容 - 初始价格设为0,避免无效的函数调用文本
- 添加数值合法性判断,防止NaN显示
内容的提问来源于stack exchange,提问作者Tomas
相关产品推荐
相关产品推荐

