點擊圖標在表格中動態增加/刪除行,每行包含輸入框、日歷圖標、操作按鈕。
<table id="dataTable">
<thead>
<tr><th>日期</th><th>操作</th></tr>
</thead>
<tbody>
<tr class="data-row">
<td><input type="text" class="date-input" name="meetingDate" /></td>
<td>
<button type="button" class="btn-del">刪除</button>
<button type="button" class="btn-add">增加</button>
</td>
</tr>
</tbody>
</table>
$(function() {
// 1. 刪除行(事件委託,支持動態新增)
$('#dataTable').on('click', '.btn-del', function() {
const $tbody = $('#dataTable tbody');
if ($tbody.find('tr').length <= 1) {
alert('至少保留一行');
return;
}
$(this).closest('tr').remove();
reindex(); // 重新索引 name/id
});
// 2. 增加行(插入到當前行後)
$('#dataTable').on('click', '.btn-add', function() {
const $tr = $(this).closest('tr');
const $newTr = $tr.clone(true); // true: 複製事件綁定
$newTr.find('input').val(''); // 清空輸入框
$tr.after($newTr);
reindex();
});
// 3. 重新索引 name 屬性(如需表單提交)
function reindex() {
$('#dataTable tbody tr').each(function(i) {
$(this).find('input[name^="meetingDate"]').attr('name', 'meetingDate[' + i + ']');
// 其他帶索引的屬性同理
});
}
// 4. 日期選擇器初始化(動態元素需重新綁定)
$('#dataTable').on('focus', '.date-input', function() {
if (!$(this).hasClass('hasDatepicker')) {
$(this).datepicker({ dateFormat: 'yy-mm-dd' });
}
});
});
| 技術 | 作用 |
|---|---|
| .on('click', selector, fn) | 事件委託,動態元素自動生效 |
| .closest('tr') | 查找最近祖先 tr |
| .clone(true) | 深度複製含事件綁定 |
| .after() / .before() | 插入同級節點 |
| .remove() | 移除自身及後代 |
document.addEventListener('click', function(e) {
const target = e.target;
const tr = target.closest('tr');
const tbody = document.querySelector('#dataTable tbody');
if (target.matches('.btn-del')) {
if (tbody.rows.length <= 1) return alert('至少保留一行');
tr.remove();
reindex();
} else if (target.matches('.btn-add')) {
const newTr = tr.cloneNode(true);
newTr.querySelectorAll('input').forEach(inp => inp.value = '');
tr.after(newTr);
reindex();
}
});
function reindex() {
document.querySelectorAll('#dataTable tbody tr').forEach((tr, i) => {
tr.querySelectorAll('input[name^="meetingDate"]').forEach(inp =>
inp.name = 'meetingDate[' + i + ']');
});
}
const rowTemplate = (index, data = {}) => `
`;
// 新增
const index = $('#dataTable tbody tr').length;
$('#dataTable tbody').append(rowTemplate(index));
// jQuery 序列化
$('#dataTable').closest('form').serializeArray();
// 結果: [{name: "meetingDate[0]", value: "2024-01-15"}, {name: "meetingDate[1]", value: "2024-01-16"}, ...]
// 後端 Spring MVC 自動綁定
public void submit(@RequestParam List meetingDate) { ... }