PHP表格行编辑仅最后一行estadoActa修改可保存 其余行不生效问题求助
问题产生原因
- HTML结构非法嵌套:按照HTML规范,
<tbody>的直接子元素只能是<tr>,你在<tbody>和<tr>之间插入<form>标签属于非法结构,浏览器会自动修正DOM结构,把所有<form>标签移到表格外,导致所有行的输入控件都被合并到同一个表单下。 - 表单未按行闭合:你在
foreach循环内开启了<form>标签,但</form>闭合标签写在了循环结束之后,相当于生成了N个表单开标签,只有1个闭标签,所有行的输入控件共享同一个表单上下文。 - 重复name属性覆盖:所有行的
NroContacto、estadoActa等控件的name属性完全相同,浏览器提交表单时会自动用最后一行的控件值覆盖前面的同名值,所以后台只能拿到最后一行的数据。
解决方案
提供两种常用落地方案:
方案1:每行独立表单(推荐,改造成本最低)
仅修改视图层代码即可,核心是保证每行对应一个独立合法的表单,修正后的核心代码片段如下:
<tbody id="myTable"> <?php if ($actascreadas): ?> <?php foreach ($actascreadas as $act): ?> <tr> <td> <a href="<?php echo base_url(); ?>index.php/creacionacta/edit/<?php echo $act->NroContacto; ?>" target="_blank"><?php echo $act->NroContacto; ?></a> <!-- 每行独立form放在第一个td内,所有本行控件通过form属性关联该表单 --> <form method="post" action="<?= base_url() ?>index.php/administradoractas/update" id="form_<?= $act->NroContacto ?>"> <input type="hidden" name="NroContacto" value="<?php echo $act->NroContacto; ?>" /> </form> </td> <td><?php echo $act->fechaGeneracion; ?></td> <td><?php echo $act->tipoGestion; ?></td> <td><?php echo $act->Comuna1; ?></td> <td><?php echo $act->estadoActa; ?></td> <td><?php echo $act->fechaGeneracion; ?></td> <td> <select form="form_<?= $act->NroContacto ?>" style="width:100px;align:left;border-color:#6A148E;" name="estadoActa" placeholer="Seleciona una opcion"> <optgroup label="Ingresado"> <option <?php if($act->estadoActa == "No Tomado"){ echo 'selected="selected"'; } ?> value="No Tomado">No Tomado</option> <option <?php if($act->estadoActa == "Ingresado - Ingresado"){ echo 'selected="selected"'; } ?> value="Ingresado - Ingresado">Ingresado - Ingresado</option> </optgroup> <optgroup label="Realizado"> <option <?php if($act->estadoActa == "Realizado - Retiro Realizado"){ echo 'selected="selected"'; } ?> value="Realizado - Retiro Realizado">Realizado - Retiro Realizado</option> <option <?php if($act->estadoActa == "Realizado - Cambio Realizado"){ echo 'selected="selected"'; } ?> value="Realizado - Cambio Realizado">Realizado - Cambio Realizado</option> </optgroup> <optgroup label="Incompleto"> <option <?php if($act->estadoActa == "Incompleto - Capacidad del Camion"){ echo 'selected="selected"'; } ?> value="Incompleto - Capacidad del Camion">Incompleto - Capacidad del Camion</option> <option <?php if($act->estadoActa == "Incompleto - Retiro Incompleto"){ echo 'selected="selected"'; } ?> value="Incompleto - Retiro Incompleto">Incompleto - Retiro Incompleto</option> </optgroup> <optgroup label="Incumplimiento"> <option <?php if($act->estadoActa == "Incumplimiento - Sin Moradores"){ echo 'selected="selected"'; } ?> value="Incumplimiento - Sin Moradores">Incumplimiento - Sin Moradores</option> <option <?php if($act->estadoActa == "Incumplimiento - Cliente Desiste"){ echo 'selected="selected"'; } ?> value="Incumplimiento - Cliente Desiste">Incumplimiento - Cliente Desiste</option> <option <?php if($act->estadoActa == "Incumplimiento - Capacidad del Camion"){ echo 'selected="selected"'; } ?> value="Incumplimiento - Capacidad del Camion">Incumplimiento - Capacidad del Camion</option> </optgroup> </select> </td> <td> <input form="form_<?= $act->NroContacto ?>" name="fechaRealCumplimiento" type="date" value="<?php echo $act->fechaRealCumplimiento; ?>"> </td> <td> <input form="form_<?= $act->NroContacto ?>" type="submit" name="actualizar" class="btn btn-primary float-center" value="Guardar"> </td> <td> <a href="<?php echo base_url(); ?>index.php/administradoractas/historialdeticketpornumeroticket/?NroContacto=<?php echo $act->NroContacto; ?>" target="_blank"><?php echo $act->NroContacto; ?></a> </td> </tr> <?php endforeach;?> <?php endif;?> </tbody>
该方案无需修改控制器和模型代码,提交时只会提交当前点击按钮对应行的数据,不会出现值覆盖问题。
方案2:批量提交表单
如果需要支持同时修改多行后一次性提交,可将所有控件的name加上主键索引,后台循环处理:
- 视图层仅保留一个全局form包裹整个表格,控件name写法改为:
<input type="hidden" name="data[<?= $act->NroContacto ?>][NroContacto]" value="<?php echo $act->NroContacto; ?>" /> <select name="data[<?= $act->NroContacto ?>][estadoActa]"> <!-- 其他选项省略 --> </select> <input name="data[<?= $act->NroContacto ?>][fechaRealCumplimiento]" type="date" value="<?php echo $act->fechaRealCumplimiento; ?>">
- 控制器修改为循环处理所有提交的行数据:
public function update() { $this->load->model('Creacionacta_model'); $allData = $this->input->post('data'); foreach ($allData as $item) { $data = array( 'table_name' => 'actas_creadas', 'NroContacto' => $item['NroContacto'], 'estadoActa' => $item['estadoActa'] ); $this->Creacionacta_model->update3($data); } redirect("index.php/administradoractas"); }
额外优化建议
- 移除重复id:所有的select、date输入的id属性增加主键后缀(如
id="slct_<?= $act->NroContacto ?>"),避免id重复导致的前端JS异常。 - 模型层增加返回值判断:当前模型无论更新成功失败都返回true,建议改为返回
$db3->affected_rows() > 0,方便控制器判断更新结果。
内容的提问来源于stack exchange,提问作者joyanader
相关产品推荐
相关产品推荐

