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

Foreach循环下产品每行单价与数量的总价计算方案咨询

解决多行产品总价计算的方案

核心思路

不用手动维护递增ID,而是利用DOM元素的层级关系,通过输入框定位到所在的表格行,再获取该行内的单价和总价元素——既避免了重复ID的问题,又能灵活处理任意数量的产品行。

修改后的代码实现

1. PHP/HTML部分调整

<?php
include 'main.php';
check_loggedin($pdo);
$minerals = $pdo->query('SELECT * FROM products WHERE category = "mineral"');
?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,minimum-scale=1">
        <title>Test</title>
        <link href="style.css" rel="stylesheet" type="text/css">
        <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
    </head>
    <body class="loggedin">
        <?php include 'navigation.php' ;?>
        <main>
            <div class="content">
                <h2>Caisse</h2>
                <div class="content-block">
                    <form action="" method="post" class="">
                        <div class="table">
                            <h3>Minérales</h3>
                            
                            <table>
                                <colgroup>
                                    <col width="5%">
                                    <col width="35%">
                                    <col width="20%">
                                    <col width="20%">
                                    <col width="20%">
                                </colgroup>
                                <thead>
                                    <tr>
                                        <td>QTY</td>
                                        <td class="center">Product</td>
                                        <td>Unit</td>
                                        <td>Price</td>
                                        <td>Total</td>
                                    </tr>
                                </thead>
                                <tbody>
                                    <?php if (!$minerals): ?>
                                    <tr>
                                        <td colspan="5" style="text-align:center">There are no minerals</td>
                                    </tr>
                                    <?php endif; ?>
                                    <?php foreach ($minerals as $mineral): ?>
                                    <tr>
                                        <!-- 传入当前input元素到计算函数,用class替代重复id -->
                                        <td><input type="number" min="0" step="1" name="qty_mineral[<?=$mineral['id']?>]" oninput="Calcul_total(this)"></td>
                                        <td class="center"><?=$mineral['name']?></td>
                                        <td><?=$mineral['unit']?></td>
                                        <td class="price"><?=$mineral['price']?></td>
                                        <td class="total"></td>
                                    </tr>
                                    <?php endforeach; ?>
                                </tbody>
                            </table>
                        </div>
                    </form>
                </div>
            </div>
        </main>
    </body>
</html>

关键改动说明:

  • 移除重复的id属性,改用class标识可复用的单价、总价元素
  • 输入框name改为数组格式qty_mineral[<?=$mineral['id']?>],提交表单时能区分不同产品的数量
  • 输入框类型设为number并限制范围,提升输入体验
  • oninput事件传入当前输入框元素this,让JS能精准定位对应行

2. JavaScript部分调整

function Calcul_total(input) {
    // 定位当前输入框所在的表格行
    const row = input.closest('tr');
    // 获取该行的单价并转为数字
    const price = parseFloat(row.querySelector('.price').textContent);
    // 获取输入数量,空值或非数字时默认设为0
    const qty = parseFloat(input.value) || 0;
    // 计算总价并保留两位小数,赋值给对应位置
    row.querySelector('.total').textContent = (qty * price).toFixed(2);
}

逻辑说明:

  • 用closest('tr')快速定位当前行,无需依赖任何ID
  • 用querySelector在该行内精准获取单价和总价元素
  • 处理空输入或非数字输入的情况,避免出现NaN
  • toFixed(2)确保总价以标准金额格式显示

额外优化建议

如果需要计算所有产品的总价总和,可以添加以下函数:

function calculateGrandTotal() {
    let grandTotal = 0;
    document.querySelectorAll('.total').forEach(el => {
        grandTotal += parseFloat(el.textContent) || 0;
    });
    // 把总和插入到页面指定位置,比如表格下方的元素
    document.getElementById('grand-total').textContent = grandTotal.toFixed(2);
}

只需在每个行计算后调用该函数,或者添加一个"计算总计"按钮触发即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 09:00:59