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

动态生成表格行时dateTimePicker崩溃且新增行不生效问题

问题根因

datetimepicker崩溃、新增行组件失效由4个问题直接导致:

  • 首行datetimepicker初始化时机错误:若在父容器处于hidden隐藏状态时初始化组件,DOM无实际渲染尺寸,组件位置、尺寸计算逻辑会直接报错崩溃
  • 动态新增行插入DOM后,仅初始化了select2组件,未对新行内的datetimepicker执行初始化,新增行内的input只是原生文本框,无日期选择能力
  • 动态生成的删除按钮重复使用idcomments_remove,违反id全局唯一规范,会导致DOM查询、事件绑定异常
  • 动态生成的日期选择器外层.cal-icondiv未写闭合标签,HTML结构错误会干扰组件渲染
修复方案
  1. 不在元素隐藏状态下初始化UI组件,等表格实际显示后再初始化首行的select2、datetimepicker
  2. 抽离单行组件初始化逻辑,每次新增行插入DOM后,仅对新行内的组件执行初始化,避免重复初始化已有元素导致报错
  3. 将重复的idcomments_remove改为class,通过class绑定删除事件
  4. 补全动态生成HTML里未闭合的标签,修正DOM结构
修正后代码

JS逻辑

$(function() {
  // 表格显示时初始化首行组件,避免隐藏状态下初始化崩溃
  $('#tableshow').on('show', function() {
    initRowComponents($('#table_achievements_tbody tr'))
  })
  // 页面加载时表格若默认可见,直接初始化首行
  if (!$('#tableshow').hasClass('hidden')) {
    initRowComponents($('#table_achievements_tbody tr'))
  }

  $(document).on("click", '.btn-add-row', function() {
    var table = $(this).closest("table.table-review");
    var tableId = table.attr('id');
    var newRow = $("<tr />");
    newRow.html(GetDynamicTextBox(tableId));
    $("#" + tableId + "_tbody").append(newRow);
    // 仅初始化新插入行的组件,避免重复初始化
    initRowComponents(newRow);
  });

  // 用class绑定删除事件,解决id重复问题
  $(document).on("click", ".comments_remove", function() {
    var currentRow = $(this).closest("tr");
    var prevRow = currentRow.prev();
    if (prevRow.length) {
      prevRow.find('td:last-child').html('<button type="button" class="btn btn-danger comments_remove"><i class="fa fa-trash-o"></i></button>');
    }
    currentRow.remove();
    // 删除后重新排序号
    $('#table_achievements_tbody tr').each(function(index) {
      $(this).find('td:first, th:first').text(index + 1)
    })
  });

  // 单行组件初始化通用逻辑
  function initRowComponents(row) {
    row.find('.prodName3, #prodName').select2({width: '289.3px'});
    row.find('.varName3, #varName').select2({width: '289.3px'});
    // 跳过已经初始化过的datetimepicker,避免重复初始化报错
    row.find('.datetimepicker').not('.datetimepicker-loaded').each(function() {
      $(this).addClass('datetimepicker-loaded').datetimepicker({
        format: 'YYYY-MM-DD HH:mm',
        allowInputToggle: true
      })
    })
  }

  function GetDynamicTextBox(table_id) {
    var tbody = document.getElementById(table_id).getElementsByTagName("tbody")[0];
    var rowsLength = tbody.getElementsByTagName("tr").length + 1;
    // 补全未闭合的cal-icon标签,删除按钮改用class
    return '<td>' + rowsLength + '</td>' +
      '<td><select name="DynamicTextBox" class="select form-control prodName3" value="" style="width:289.3px;"><option>Select</option><option>ProdDolar</option><option>ProdLBP</option><option>Souna</option></select></td>' +
      '<td><select name="DynamicTextBox" class="select form-control varName3" value="" style="width:289.3px;"><option>Select</option><option>ProdLBPmmm1B3</option></select></td>' +
      '<td><input type="text" name="DynamicTextBox" class="form-control" value="mm" readonly></td>' +
      '<td><div class="cal-icon"><input class="form-control floating datetimepicker" name="DynamicTextBox" type="text"></div></td>' +
      '<td><input type="text" class="form-control" name="DynamicTextBox" onkeyup="javascript:this.value=Comma(this.value);"></td>' +
      '<td><button type="button" class="btn btn-danger comments_remove"><i class="fa fa-trash-o"></i></button></td>'
  }
});

HTML结构修正

仅需要补全首行日期选择器的未闭合标签即可:

<th>
  <div class="cal-icon"><input class="form-control floating datetimepicker" type="text"></div>
</th>
注意事项

bootstrap-datetimepicker、select2这类UI组件初始化时会读取DOM的实际宽高、位置属性,元素处于display:none隐藏状态时这些属性值为0,直接初始化必然报错,一定要等元素实际渲染到页面后再执行初始化逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 10:12:20