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

如何在Django循环模板中用JavaScript计算多组输入值

问题解决方案

问题根源

  • 循环渲染时重复使用相同id,违反HTML规范;document.querySelector仅返回第一个匹配元素,导致所有组共用第一组的输入值。
  • 输入框class均为shares,无法区分「投注金额」和「份额」,取值逻辑混乱。
  • 函数定义在循环内部,重复创建同名函数,引发覆盖问题。
  • NaN判断逻辑错误:potential_win === isNan写法完全错误,isNaN是全局函数,需传入计算值进行判断。

修复后的完整代码

Django模板部分

{% for p in prediction.prediction_data.all %}
<div class="mid-area" data-group-id="{{ forloop.counter }}">
    <div class="single-area">
        <div class="item-title d-flex align-items-center justify-content-between">
            <span>Choose Stake Amount</span>
        </div>
        <div class="d-flex in-dec-val">
            <input type="number" required value="{{ p.amount }}" name="amount" placeholder="amount" 
                   class="amount-input" onkeyup="CalculateNewBalance(this)" />

            <div class="btn-area">
                <button class="plus" type="button">
                    <img src="{% static 'assets/images/icon/up-arrow.png' %}" alt="icon" />
                </button>
                <button class="minus" type="button">
                    <img src="{% static 'assets/images/icon/down-arrow.png' %}" alt="icon" />
                </button>
            </div>
        </div>

        <p id="error-div-{{ forloop.counter }}" class="mt-2"></p>
    </div>
    <div class="single-area quick-amounts"></div>
    <div class="single-area quick-amounts">
        <div class="item-title d-flex align-items-center">
            <p>Choose <b>Shares</b> Amount</p>
        </div>
        <div class="d-flex in-dec-val">
            <input type="number" required value="1" name="shares" placeholder="shares" 
                   class="shares-input" onkeyup="CalculateNewBalance(this)" />

            <div class="btn-area">
                <button class="pldus" type="button">
                    <img src="{% static 'assets/images/icon/up-arrow.png' %}" alt="icon" />
                </button>
                <button class="mindus" type="button">
                    <img src="{% static 'assets/images/icon/down-arrow.png' %}" alt="icon" />
                </button>
            </div>
        </div>
    </div>

    <div class="single-area smart-value">
        <div class="item-title d-flex align-items-center">
            <p class="mdr text-capitalize">Potential win</p>
        </div>
        <div class="contact-val d-flex align-items-center">
            <span style="font-size: 24px;" class="potential-win">$0.00</span><br />
        </div>
    </div>
</div>
{% endfor %}

<!-- 脚本移到循环外,只定义一次 -->
<script>
function CalculateNewBalance(element) {
    // 找到当前输入框所在的组容器
    const group = element.closest('.mid-area');
    // 在当前组内获取对应的输入框和结果元素
    const stakeInput = group.querySelector('.amount-input');
    const sharesInput = group.querySelector('.shares-input');
    const potentialWinEl = group.querySelector('.potential-win');

    // 处理输入值,空值或非数字转为0
    const stakeAmount = parseFloat(stakeInput.value) || 0;
    const sharesAmount = parseInt(sharesInput.value) || 0;

    // 计算潜在收益
    let potentialWinValue = stakeAmount * sharesAmount;

    // 处理NaN或无效计算,转为0.00
    if (isNaN(potentialWinValue)) {
        potentialWinValue = 0;
    }

    // 格式化显示为带$的两位小数
    potentialWinEl.innerHTML = `$${potentialWinValue.toFixed(2)}`;
}
</script>

关键修改说明

  1. 唯一组标识:给每个.mid-area添加data-group-id(用forloop.counter生成唯一值),同时修改错误提示框的id为error-div-{{ forloop.counter }},避免重复id。
  2. 区分输入框class:将投注金额输入框的class改为amount-input,份额输入框改为shares-input,确保能精准定位元素。
  3. 函数移至循环外:避免重复定义CalculateNewBalance函数,引发变量覆盖问题。
  4. 传递当前元素:onkeyup="CalculateNewBalance(this)"将触发事件的输入框传入函数,通过closest('.mid-area')定位到当前组,确保每个组独立计算。
  5. 输入值容错处理:用|| 0将空值或非数字输入转为0,避免计算出现NaN。
  6. 正确的NaN判断:使用isNaN(potentialWinValue)判断计算结果是否无效,同时用toFixed(2)保证金额显示为两位小数。

内容的提问来源于stack exchange,提问作者Destiny Franks

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 21:10:28