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

使用下拉框值时JQuery药物计算器无法完成计算

药物计算器下拉框填充后计算NaN/Infinity问题修复

问题描述

我是JQuery新手,开发了一款药物计算器。支持用户自定义数值的功能运行正常,但用SQL查询驱动的下拉框填充字段时出现问题:下拉框能正常填充表单字段,填充后调用calcTotals()计算,但结果始终为NaN或Infinity;手动编辑表单字段后计算器恢复正常,但这失去了下拉框填充的意义。

下拉框代码

<select name="stock_item_used" id="stock_item_used" required>
    <option value="" disabled selected>Medication</option>
    <?php
    //Find medications
    $stmt = $conn->prepare("SELECT * from rescue_medication_trans
    LEFT JOIN rescue_medications ON rescue_medication_trans.med_profile_id = rescue_medications.medication_id
    LEFT JOIN rescue_stock_medication ON rescue_stock_medication.medication = rescue_medication_trans.med_profile_id
    WHERE rescue_medication_trans.centre_id = :centre_id
    ORDER BY common_name ASC");
    $stmt->bindParam(':centre_id', $centre_id, PDO::PARAM_INT);     
    // initialise an array for the results
    $instock = array();
    $stmt->execute();
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {

    $med_profile_id = $row["med_profile_id"];
    $batch_number = $row["batch_number"];
    $expiry = $row["expiry"];
    $med_common_name = $row["common_name"];
    $mcd = $row["concentration_dose"];
    $mcv = $row["concentration_volume"];
    $dose_type = $row["concentration_dose_type"];
    $volume_type = $row["concentration_volume_type"];

    //format the exp date
    $exp = new DateTime($expiry);
    $exp = $exp->format('d-m-Y');
                                
    print '<option value="' . $med_profile_id . '" data-dose="' . $mcd . '" data-volume="' . $mcv . '">' . $med_common_name . ' - ' . $mcd . '<i>' . $dose_type . '</i>  in ' . $mcv . '<i>' . $volume_type. '</i> (' . $batch_number . ' exp: ' . $exp . ') </option>'; } ?> 
</select>

注:已移除重复的name="stock_item_used"属性,修复HTML无效问题

JQuery脚本

<script>
var req_dose = 0;
var med_dose = 0;
var med_vol = 0;
var weight = 0;

$("#required_dose").change( function(){
    req_dose = $("#required_dose").val();
    calcTotals();
});
$("#medication_dose").change( function() {
    med_dose = $("#medication_dose").val();
    calcTotals();
});
$("#medication_volume").change( function() {
    med_vol = $("#medication_volume").val();
    calcTotals();
});
$("#animal_weight").change( function() {
    weight = $("#animal_weight").val();
    calcByweight();
});

var selectdose = document.getElementById("stock_item_used");
selectdose.addEventListener("change", function() {
  var optiondose = selectdose.options[selectdose.selectedIndex].getAttribute("data-dose");
  document.getElementById('medication_dose').value = optiondose;
  calcTotals();
  calcByweight();
});

var selectvol = document.getElementById("stock_item_used");
selectvol.addEventListener("change", function() {
  var optionvol = selectvol.options[selectvol.selectedIndex].getAttribute("data-volume");
  document.getElementById('medication_volume').value = optionvol;
  calcTotals();
  calcByweight();
});

function calcTotals(){
    $("#volume").text(req_dose * (med_vol / med_dose));
}
function calcByweight(){
    $("#perweight").text((req_dose * (med_vol / med_dose)) * weight);
}
</script>

问题根源

  1. 全局变量未更新:med_dose、med_vol只有在输入框的change事件触发时才会赋值,但通过下拉框给输入框赋值时,并未触发输入框的change事件,导致这两个变量始终是初始值0,计算时出现0/0(NaN)或除数为0(Infinity)的情况。
  2. 字符串类型运算:从getAttribute获取的data-*值是字符串类型,直接参与运算可能引发类型错误。
  3. 重复事件监听:同一个下拉框绑定了两个change事件,冗余且容易引发逻辑混乱。

修复方案

方案1:合并下拉框事件,直接更新全局变量

替换原有的两个下拉框事件监听,改成以下代码:

$("#stock_item_used").change(function() {
  // 获取选中选项的data值,并转为数字(默认0避免空值/非数字)
  var selectedOption = $(this).find("option:selected");
  var optiondose = parseFloat(selectedOption.data("dose")) || 0;
  var optionvol = parseFloat(selectedOption.data("volume")) || 0;
  
  // 更新输入框值
  $("#medication_dose").val(optiondose);
  $("#medication_volume").val(optionvol);
  
  // 直接更新全局变量
  med_dose = optiondose;
  med_vol = optionvol;
  
  // 执行计算
  calcTotals();
  calcByweight();
});

方案2:触发输入框change事件复用原有逻辑

如果想保留原有的输入框change事件逻辑,可以通过trigger("change")触发事件,让原有代码更新全局变量:

$("#stock_item_used").change(function() {
  var selectedOption = $(this).find("option:selected");
  var optiondose = selectedOption.data("dose");
  var optionvol = selectedOption.data("volume");
  
  // 赋值并触发change事件
  $("#medication_dose").val(optiondose).trigger("change");
  $("#medication_volume").val(optionvol).trigger("change");
  
  // 执行重量计算
  calcByweight();
});

优化计算函数(可选)

为了避免除数为0或非数字输入的问题,在计算函数里增加类型校验和容错处理:

function calcTotals(){
    // 转为数字,默认0避免无效值
    var reqDoseNum = parseFloat(req_dose) || 0;
    var medVolNum = parseFloat(med_vol) || 0;
    var medDoseNum = parseFloat(med_dose) || 0;
    
    // 避免除数为0
    var result = medDoseNum !== 0 ? reqDoseNum * (medVolNum / medDoseNum) : 0;
    $("#volume").text(result);
}

function calcByweight(){
    var reqDoseNum = parseFloat(req_dose) || 0;
    var medVolNum = parseFloat(med_vol) || 0;
    var medDoseNum = parseFloat(med_dose) || 0;
    var weightNum = parseFloat(weight) || 0;
    
    var baseResult = medDoseNum !== 0 ? reqDoseNum * (medVolNum / medDoseNum) : 0;
    $("#perweight").text(baseResult * weightNum);
}

内容的提问来源于stack exchange,提问作者Dan Lindley

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 02:05:56