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

求助:实现表格每行成绩输入时自动更新平均分与观察列的PHP+JavaScript方案

求助:实现表格每行成绩输入时自动更新平均分与观察列的PHP+JavaScript方案

我目前在做一个学生成绩管理的页面,想要实现一个功能:每行根据计算出的平均分(moyennne列),自动在"observation"列显示"admis"(通过)或者"ajourné"(不通过)。但现在遇到了问题:只有表格的第一行能正常触发更新,修改其他行的成绩时,平均分和观察列完全没反应。

我现在的代码如下:

PHP+HTML部分:

<table name="cart" class="table table-bordered">
  <tr style='background: whitesmoke;'>
    <th>Evaluation</th>
    <th>Devoir</th>
    <th>Examen</th>
    <th>moyennne</th>
    <th>observation</th>
  </tr>
  <?php 
  $query = "SELECT * FROM s3 limit 10"; 
  $result = mysqli_query($conn,$query); 
  while($row = mysqli_fetch_array($result) ){ 
    $id = $row['id']; 
    $numstudent = $row['numstudent']; 
    $evaluation = $row['evaluation']; 
    $devoir = $row['devoir']; 
    $examen = $row['examen']; 
  ?>
  <tr name="line_items">
    <td><input class="decimal form-control" type='text' name='evaluation_<?= $id ?>' value='<?= $evaluation ?>' ></td>
    <td><input class="decimal form-control" type='text' name='devoir_<?= $id ?>' value='<?= $devoir ?>' ></td>
    <td><input class="decimal form-control" type='text' name='examen_<?= $id ?>' value='<?= $examen ?>' ></td>
    <td><input class="decimal form-control" type='text' id="fname" name='item_total' jAutoCalc="((({evaluation_<?= $id ?>} + {devoir_<?= $id ?>})/2)+({examen_<?= $id ?>}*2))/3" > </td>
    <td><input class="form-control" type='text' id="fname1" readonly></td>
  </tr>
  <?php } ?>
</table>

JavaScript部分:

document.getElementById("fname").onchange = function() { myFunction() };
function myFunction() {
  var x = document.getElementById("fname");
  var y = document.getElementById("fname1");
  var val = "";
  var z = x.value;
  if (z >= 10.00) {
    val = "admis";
  } else {
    val = "ajourné";
  }
  y.value = val;;
}

问题原因分析:

问题出在重复的id属性上:所有行的平均分输入框都用了id="fname",观察列输入框都用了id="fname1",而document.getElementById()只会返回页面中第一个匹配该id的元素,所以只有第一行能触发更新逻辑。

解决方案:

我们需要给每行的元素设置唯一的标识,并调整JavaScript的事件绑定和处理逻辑,让它能针对当前行的元素进行操作。

修改后的完整代码:

<table name="cart" class="table table-bordered">
  <tr style='background: whitesmoke;'>
    <th>Evaluation</th>
    <th>Devoir</th>
    <th>Examen</th>
    <th>moyennne</th>
    <th>observation</th>
  </tr>
  <?php 
  $query = "SELECT * FROM s3 limit 10"; 
  $result = mysqli_query($conn,$query); 
  while($row = mysqli_fetch_array($result) ){ 
    $id = $row['id']; 
    $numstudent = $row['numstudent']; 
    $evaluation = $row['evaluation']; 
    $devoir = $row['devoir']; 
    $examen = $row['examen']; 
  ?>
  <tr name="line_items">
    <td><input class="decimal form-control" type='text' name='evaluation_<?= $id ?>' value='<?= $evaluation ?>' ></td>
    <td><input class="decimal form-control" type='text' name='devoir_<?= $id ?>' value='<?= $devoir ?>' ></td>
    <td><input class="decimal form-control" type='text' name='examen_<?= $id ?>' value='<?= $examen ?>' ></td>
    <!-- 给平均分输入框设置唯一id:fname_<?= $id ?>,并绑定带参数的onchange事件 -->
    <td><input class="decimal form-control" type='text' id="fname_<?= $id ?>" name='item_total' jAutoCalc="((({evaluation_<?= $id ?>} + {devoir_<?= $id ?>})/2)+({examen_<?= $id ?>}*2))/3" onchange="myFunction(<?= $id ?>)" > </td>
    <!-- 给观察列输入框设置唯一id:fname1_<?= $id ?> -->
    <td><input class="form-control" type='text' id="fname1_<?= $id ?>" readonly></td>
  </tr>
  <?php } ?>
</table>

<script>
// 修改函数,接收当前行的id参数,针对对应行的元素操作
function myFunction(rowId) {
  // 获取当前行的平均分输入框和观察列输入框
  var x = document.getElementById(`fname_${rowId}`);
  var y = document.getElementById(`fname1_${rowId}`);
  var val = "";
  var z = parseFloat(x.value); // 转成数字类型,避免字符串比较的问题
  
  // 处理空值或非数字的情况
  if (isNaN(z)) {
    val = "";
  } else if (z >= 10.00) {
    val = "admis";
  } else {
    val = "ajourné";
  }
  y.value = val;
}
</script>

额外优化建议:

  1. 因为jAutoCalc是实时计算平均分的,除了onchange事件,还可以添加oninput事件,让观察列的更新更及时:
<input class="decimal form-control" type='text' id="fname_<?= $id ?>" name='item_total' jAutoCalc="((({evaluation_<?= $id ?>} + {devoir_<?= $id ?>})/2)+({examen_<?= $id ?>}*2))/3" onchange="myFunction(<?= $id ?>)" oninput="myFunction(<?= $id ?>)" >
  1. 可以考虑用事件委托的方式绑定事件,避免在循环中重复绑定事件,代码更简洁(适合行数较多的情况)。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 08:28:02