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

Bootstrap动态增删行表格仅首行自动计算生效问题求助

Bootstrap动态表格新增行自动计算失效修复

问题现象

基于Bootstrap搭建的支持手动增删行的交互式表格,基础增删行功能运行正常,但配置的「格栅长度×格栅容量=最大容量」数值自动计算逻辑仅在初始加载的默认首行生效,后续动态新增的表格行无法触发自动计算。

原有代码

行增删功能JS

jQuery(document).delegate('a.add-record_venr', 'click', function(e) {
    e.preventDefault();
    var content = jQuery('#sample_table_venr tr'),
    size = jQuery('#tbl_posts_venr >tbody >tr').length + 1,
    element = null,
    element = content.clone();
    element.attr('id', 'rec_venr-'+size);
    element.find('.delete-record_venr').attr('data-id', size);
    element.appendTo('#tbl_posts_body_venr');
    element.find('.sn').html(size);
});
jQuery(document).delegate('a.delete-record_venr', 'click', function(e) {
    e.preventDefault();
    var didConfirm = confirm("Ventilatierooster verwijderen?");
    if (didConfirm == true) {
        var id = jQuery(this).attr('data-id');
        var targetDiv = jQuery(this).attr('targetDiv');
        jQuery('#rec_venr-' + id).remove();
        
        // 重新生成表格序号
        $('#tbl_posts_body_venr tr').each(function(index) {
            $(this).find('span.sn').html(index+1);
        });
        return true;
    } else {
        return false;
    }
});

表格HTML结构

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

<div class="wellclearfix">
<a class="btn btn-primary pull-right add-record_venr" data-added="0"><i class="glyphicon glyphicon-plus"></i> Toevoegen </a>
</div>

<div class="container-fluid" style="margin-left:1px ;">
    <table class="table table-stripped" id="tbl_posts_venr">
        <thead style="background-color:#c7c8cc; width: 100% !important;">
            <tr>
                <th style="width:30px ;">Merk</th>
                <th>Lengte rooster</th>
                <th>Type rooster</th>
                <th>Capaciteit [dm3/s]</th>
                <th>Max. capaciteit [dm3/s]</th>
                <th>Verblijfsgebied</th>
                <th>Verblijfsruimte</th>
                <th>Verwijderen</th>
            </tr>
        </thead>
        <tbody id="tbl_posts_body_venr">
            <tr id="rec_venr-1">
                <td><input class="inputtext" type="text" name="" placeholder="Merk"> </td>
                <td><input class="inputtext" type="text" name="lrooster" id="lrooster" placeholder="Lengte rooster"></td>
                <td><input class="inputtext" type="text" name="" placeholder="Type rooster"></td>
                <td><input class="inputtext" type="text" name="caprooster" id="caprooster" placeholder="Capaciteit [dm3/s]"></td>
                <td><input class="inputtext" type="text" name="maxcaprooster" id="maxcaprooster" placeholder="Max. capaciteit [dm3/s]"></td>
                <td><input class="inputtext" type="text" name="" placeholder="Verblijfsgebied"></td>
                <td><input class="inputtext" type="text" name="" placeholder="Verblijfsruimte"></td>
                <td><a class="btn btn-xs delete-record" data-id="1"><i class="glyphicon glyphicon-trash"></i></a></td>
            </tr>
        </tbody>
    </table>
</div>

<div style="display:none;">
    <table id="sample_table_venr">
        <tr id="">
            <td><input class="inputtext" type="text" name="" placeholder="Merk"> </td>
            <td><input class="inputtext" type="text" name="lrooster" id="lrooster" placeholder="Lengte rooster"></td>
            <td><input class="inputtext" type="text" name="" placeholder="Type rooster"></td>
            <td><input class="inputtext" type="text" name="caprooster" id="caprooster" placeholder="Capaciteit [dm3/s]"></td>
            <td><input class="inputtext" type="text" name="maxcaprooster" id="maxcaprooster" placeholder="Max. capaciteit [dm3/s]"></td>
            <td><input class="inputtext" type="text" name="" placeholder="Verblijfsgebied"></td>
            <td><input class="inputtext" type="text" name="" placeholder="Verblijfsruimte"></td>
            <td><a class="btn btn-xs delete-record" data-id="1"><i class="glyphicon glyphicon-trash"></i></a></td>
        </tr>
    </table>
</div>

原有自动计算逻辑JS

$('#lrooster, #caprooster').keyup(function(){
    var lrooster = parseFloat($('#lrooster').val());
    var caprooster = parseFloat($('#caprooster').val());

    $('#maxcaprooster').val(lrooster * caprooster );
});

问题根因

  • 事件绑定方式错误:直接给#lrooster、#caprooster绑定keyup事件属于静态绑定,仅能对页面初始加载时已存在的DOM元素生效,后续动态新增的行内输入框没有被绑定事件,无法触发计算。
  • 违反HTML id唯一性规范:模板行和初始行重复使用lrooster、caprooster、maxcaprooster作为id,id在页面中全局唯一,重复id会导致取值、赋值永远只匹配到页面第一个对应id的元素,就算事件绑定成功,也会出现跨行列值计算错误的问题。
  • 选择器不匹配:HTML中删除按钮的class为delete-record,但增删JS中绑定事件时用的选择器是.delete-record_venr,会导致新增行的删除按钮点击无响应。

修复步骤

  1. 替换事件绑定方式:将自动计算的事件改为事件委托,绑定到始终存在的document(或表格父容器)上,支持动态新增元素触发事件。
  2. 替换id选择器为class选择器:删除所有重复的id属性,给对应列的输入框加上专属class,计算时先定位到当前触发事件的输入框所在行,再读取同行的输入值做计算,赋值给同行的结果输入框,避免跨行列错。
  3. 统一删除按钮class:将HTML中所有删除按钮的class统一为delete-record_venr,和JS选择器匹配。
  4. 增加空值兼容:计算时给parseFloat的结果加兜底值0,避免输入为空时计算出NaN。

修复后代码

修改后的自动计算逻辑

// 事件委托绑定,动态新增元素也能触发
jQuery(document).on('keyup', '.lrooster, .caprooster', function(){
    // 定位当前输入框所在行
    const $currentRow = jQuery(this).closest('tr');
    // 读取当前行的两个计算因子,空值兜底为0
    const length = parseFloat($currentRow.find('.lrooster').val()) || 0;
    const capacity = parseFloat($currentRow.find('.caprooster').val()) || 0;
    // 计算结果赋值给当前行的最大容量输入框,保留2位小数
    $currentRow.find('.maxcaprooster').val((length * capacity).toFixed(2));
});

HTML部分调整

将初始行、隐藏模板行中的输入框和删除按钮做如下修改,移除重复id,新增对应class:

<!-- 格栅长度输入框 -->
<td><input class="inputtext lrooster" type="text" name="lrooster" placeholder="Lengte rooster"></td>
<!-- 格栅容量输入框 -->
<td><input class="inputtext caprooster" type="text" name="caprooster" placeholder="Capaciteit [dm3/s]"></td>
<!-- 最大容量输入框 -->
<td><input class="inputtext maxcaprooster" type="text" name="maxcaprooster" placeholder="Max. capaciteit [dm3/s]"></td>
<!-- 删除按钮,统一class -->
<td><a class="btn btn-xs delete-record_venr" data-id="1"><i class="glyphicon glyphicon-trash"></i></a></td>

注:如果使用jQuery 1.7及以上版本,建议将原有增删逻辑中的delegate写法替换为on写法,语法更统一,例如将jQuery(document).delegate('a.add-record_venr', 'click', function(e) {})替换为jQuery(document).on('click', 'a.add-record_venr', function(e) {}),原有逻辑无需改动。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 12:24:23