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

使用JQuery实现主表与子表条目插入功能技术求助

单页应用剩余功能实现方案

1. 头部输入字段完善

给头部输入框添加实时格式校验逻辑,确保输入符合要求:

// 头部输入框实时校验
document.getElementById('header-input').addEventListener('input', function(e) {
  const value = e.target.value.trim();
  this.classList.toggle('is-invalid', !value);
});

2. 主条目模态框与表格展示

模态框提交与表格插入

绑定主条目模态框的提交按钮事件,收集数据后生成表格行:

// 主条目提交逻辑
document.getElementById('main-item-submit').addEventListener('click', function() {
  const itemName = document.getElementById('main-item-name').value.trim();
  const itemDesc = document.getElementById('main-item-desc').value.trim();
  
  if (!itemName) {
    alert('请输入条目名称');
    return;
  }

  // 生成唯一ID关联子条目
  const itemId = `item-${Date.now()}`;
  // 插入表格行
  const rowHtml = `
    <tr data-item-id="${itemId}">
      <td>${itemName}</td>
      <td>${itemDesc}</td>
      <td>
        <button class="btn btn-sm btn-primary add-sub-item">添加子条目</button>
        <button class="btn btn-sm btn-danger delete-item">删除</button>
      </td>
    </tr>
  `;
  document.getElementById('main-items-table').querySelector('tbody').insertAdjacentHTML('beforeend', rowHtml);

  // 重置表单并关闭模态框
  document.getElementById('main-item-form').reset();
  bootstrap.Modal.getInstance(document.getElementById('main-item-modal')).hide();
  
  // 绑定新增子条目按钮事件
  bindSubItemBtnEvent(itemId);
});

// 主条目删除逻辑
document.getElementById('main-items-table').addEventListener('click', function(e) {
  if (e.target.classList.contains('delete-item')) {
    const targetRow = e.target.closest('tr');
    // 同时删除关联的子条目行
    const subRow = targetRow.nextElementSibling;
    if (subRow && subRow.querySelector('.sub-items-table')) subRow.remove();
    targetRow.remove();
  }
});

3. 子条目模态框与表格展示

子条目按钮绑定与提交

// 绑定子条目按钮点击事件
function bindSubItemBtnEvent(itemId) {
  const addBtn = document.querySelector(`tr[data-item-id="${itemId}"] .add-sub-item`);
  addBtn.addEventListener('click', function() {
    document.getElementById('sub-item-modal').dataset.parentId = itemId;
    bootstrap.Modal.getInstance(document.getElementById('sub-item-modal')).show();
  });
}

// 子条目提交逻辑
document.getElementById('sub-item-submit').addEventListener('click', function() {
  const parentId = this.closest('.modal').dataset.parentId;
  const subName = document.getElementById('sub-item-name').value.trim();
  const subValue = document.getElementById('sub-item-value').value.trim();
  
  if (!subName) {
    alert('请输入子条目名称');
    return;
  }

  const parentRow = document.querySelector(`tr[data-item-id="${parentId}"]`);
  let subTable = parentRow.nextElementSibling?.querySelector('.sub-items-table');

  // 若不存在子表格则创建
  if (!subTable) {
    const subTableHtml = `
      <tr>
        <td colspan="3">
          <table class="table table-sm sub-items-table mt-2">
            <thead><tr><th>子条目名称</th><th>子条目值</th><th>操作</th></tr></thead>
            <tbody></tbody>
          </table>
        </td>
      </tr>
    `;
    parentRow.insertAdjacentHTML('afterend', subTableHtml);
    subTable = parentRow.nextElementSibling.querySelector('.sub-items-table');
  }

  // 插入子条目行
  const subRowHtml = `
    <tr>
      <td>${subName}</td>
      <td>${subValue}</td>
      <td><button class="btn btn-sm btn-danger delete-sub-item">删除</button></td>
    </tr>
  `;
  subTable.querySelector('tbody').insertAdjacentHTML('beforeend', subRowHtml);

  // 重置表单并关闭模态框
  document.getElementById('sub-item-form').reset();
  bootstrap.Modal.getInstance(document.getElementById('sub-item-modal')).hide();
});

// 子条目删除逻辑
document.addEventListener('click', function(e) {
  if (e.target.classList.contains('delete-sub-item')) {
    const subRow = e.target.closest('tr');
    subRow.remove();
    // 子表格为空时移除整行
    const subTable = subRow.closest('.sub-items-table');
    if (!subTable.querySelector('tbody').children.length) {
      subTable.closest('tr').remove();
    }
  }
});

4. 数据提交至接口(Ajax)

收集所有数据并发送请求

document.getElementById('submit-all').addEventListener('click', function() {
  // 校验头部输入
  const headerVal = document.getElementById('header-input').value.trim();
  if (!headerVal) {
    alert('请填写头部输入字段');
    return;
  }

  // 收集所有主条目及子条目
  const submitData = {
    header: headerVal,
    items: []
  };

  document.querySelectorAll('#main-items-table tbody tr').forEach(row => {
    const itemId = row.dataset.itemId;
    const subItems = [];
    // 读取关联子条目
    const subRow = row.nextElementSibling;
    if (subRow && subRow.querySelector('.sub-items-table')) {
      subRow.querySelectorAll('.sub-items-table tbody tr').forEach(sub => {
        subItems.push({
          name: sub.cells[0].textContent,
          value: sub.cells[1].textContent
        });
      });
    }
    // 添加主条目数据
    submitData.items.push({
      id: itemId,
      name: row.cells[0].textContent,
      desc: row.cells[1].textContent,
      subItems
    });
  });

  // 发送Ajax请求
  fetch('/your-api-url', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(submitData)
  })
  .then(res => {
    if (!res.ok) throw new Error('请求失败');
    return res.json();
  })
  .then(() => {
    alert('提交成功');
    // 可选:重置页面数据
    document.getElementById('header-input').value = '';
    document.getElementById('main-items-table').querySelector('tbody').innerHTML = '';
  })
  .catch(err => {
    console.error('提交出错:', err);
    alert('提交失败,请重试');
  });
});

关键注意事项

  • 确保Bootstrap模态框结构符合官方规范,表单元素需设置唯一id
  • 可根据需求扩展数据校验规则(如正则匹配、长度限制)
  • 若需防止页面刷新丢失数据,可在提交前将数据暂存至localStorage

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 11:45:30