求助:实现表格每行成绩输入时自动更新平均分与观察列的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>
额外优化建议:
- 因为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 ?>)" >
- 可以考虑用事件委托的方式绑定事件,避免在循环中重复绑定事件,代码更简洁(适合行数较多的情况)。
内容来源于stack exchange
相关产品推荐
相关产品推荐

