我正在寻找一种显示每行最后2个单元格中所有输入元素的总和(数量和数量)的方法。 该表中的每个元素都有唯一的ID。每个输入元素都有一个ID,该ID包含有关它出现在该行中的信息:
var trRows = ['tr2', 'tr3', 'tr4', 'tr5', 'tr6', 'tr7', 'tr8', 'tr9', 'tr10', 'tr11', 'tr12'];
trRows.forEach(function(trRow) {
var $sumQuantity = 0;
var $sumAmount = 0;
$(this).find('#tr' + trRow + 'input[id *= "qty"]').each(function() {
$sumQuantity += +$(this).text() || 0;
});
$(this).find('#tr' + trRow + 'input[id *= "amount"]').each(function() {
$sumAmount += +$(this).text() || 0;
});
$('#sumQtyTR' + trRows, this).html($sumQuantity);
$('#sumAmountTR' + trRows, this).html($sumAmount);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr id='tr2'>
<td id='td2_65'><span id='span_i2qty_65'><input id='input_i2qty_65' class='editbox'></span>
</td>
<td id='td2_65'><span id='span_i2amount_65'><input id='input_i2amount_65' class='editbox'></span>
</td>
<td id='td2_66'><span id='span_i2qty_66'><input id='input_i2qty_66' class='editbox'></span>
</td>
<td id='td2_66'><span id='span_i2amount_66'><input id='input_i2amount_66' class='editbox'></span>
</td>
<td id='sumQtyTR2'></td>
<td id='sumAmountTR2'></td>
</tr>
<tr id='tr3'>
<td id='td3_65'><span id='span_i3qty_65'><input id='input_i3qty_65' class='editbox'></span>
</td>
<td id='td3_65'><span id='span_i3amount_65'><input id='input_i3amount_65' class='editbox'></span>
</td>
<td id='td3_66'><span id='span_i3qty_66'><input id='input_i3qty_66' class='editbox'></span>
</td>
<td id='td3_66'><span id='span_i3amount_66'><input id='input_i3amount_66' class='editbox'></span>
</td>
<td id='sumQtyTR3'></td>
<td id='sumAmountTR3'></td>
</tr>
<!-- More rows -->
</table>
我不知道为什么不显示总和。选择器?谢谢
答案 0 :(得分:-1)
在您的代码中,有一些有趣的地方可能值得考虑,以减少混乱:
id
的地方,应该改用class
出于学习目的,以下示例旨在在结构/设计上与OP中的原始源代码非常接近;但是,应注意,有许多方法可以进行优化以提高性能和可读性。
逻辑流程值得一提。这些示例中的结构效率低下,因为每次更新输入时,它都会循环遍历并重新计算所有行的总和。可以通过仅计算和更新更改后的行的总和来改善这一点。此外,通过使用更多的语义HTML和使用类(如果需要选择),可以更好地改善包含感兴趣行(例如row_ids
)的数组的功能。
下面的jQuery和ES6 +示例也进行了其他一些重大更改。最值得注意的是onChange事件处理程序。 OP中的代码会在页面加载后立即遍历每个ID,但是再也不会遍历。在修改输入框时,需要挂钩某个事件,该事件将被调用。因此onChange或onBlur事件对于重新计算值是必需的。
鉴于这两项建议,我对您的HTML和JavaScript进行了一些实质性更改,包括但不限于:
jQuery(document).ready(function($) {
let row_ids = ['tr2', 'tr3', 'tr4', 'tr5', 'tr6', 'tr7', 'tr8', 'tr9', 'tr10', 'tr11', 'tr12'];
function changeEventHandler() {
$.each(row_ids, function(ndx, row_id) {
const $row = $('#' + row_id)
if (!$row.length)
return;
const quantity = $row.find('input.quantity').get().reduce(function(acc, input) {
acc += parseFloat(input.value) || 0;
return acc
}, 0)
const amount = $row.find('input.amount').get().reduce(function(acc, input) {
acc += parseFloat(input.value) || 0;
return acc
}, 0)
$row.find('.sum.quantity').text(quantity)
$row.find('.sum.amount').text(amount)
});
}
$(document).on('change', 'input', changeEventHandler)
})
.sum { background: #eee; }
th,td {
vertical-align: bottom;
white-space: nowrap;
text-align: center;
}
table { width: 100%; }
input { width: 40%; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Fill in each input with a number (watch sums auto-update):
<table>
<thead>
<tr>
<th>QTY 1</th>
<th>AMT 1</th>
<th>QTY 2</th>
<th>AMT 2</th>
<th>SUM QTY</th>
<th>SUM AMT</th>
</tr>
</thead>
<tbody>
<tr id='tr2'>
<!-- td: use class and not id -->
<!-- remove unnecessary classes -->
<td class="item_65"><span><input class='quantity'></span></td>
<td class="item_65"><span><input class='amount'></span></td>
<td class="item_66"><span><input class='quantity'></span></td>
<td class="item_66"><span><input class='amount'></span></td>
<td class="sum quantity"></td>
<td class="sum amount"></td>
</tr>
<tr id='tr3'>
<td class="item_65"><span><input class='quantity'></span></td>
<td class="item_65"><span><input class='amount'></span></td>
<td class="item_66"><span><input class='quantity'></span></td>
<td class="item_66"><span><input class='amount'></span></td>
<td class="sum quantity"></td>
<td class="sum amount"></td>
</tr>
<!-- More rows -->
</tbody>
</table>
鉴于两项建议,我对您的HTML和JavaScript进行了一些实质性更改,包括但不限于:
reduce
进行总和计算注意:如前所述,该代码可能无法在所有浏览器(所有版本和变体)中运行,但应在大多数较新的浏览器中运行。由于该代码段配置为使用babel
,因此该代码段可在大多数(如果不是全部)范围内使用
function changeEventHandler() {
let row_ids = ['tr2', 'tr3', 'tr4', 'tr5', 'tr6', 'tr7', 'tr8', 'tr9', 'tr10', 'tr11', 'tr12'];
// could iterate over the rows:
// document.querySelectorAll(selector)
// where selector is 'tr' or '[id^="tr"]'
row_ids.forEach(row_id => {
const row = document.querySelector(`#${row_id}`)
if (row == null)
return;
const qty_el = row.querySelectorAll('input.quantity')
const quantity = [...qty_el].reduce((acc, cv) => acc += parseFloat(cv.value) || 0, 0)
const amt_el = row.querySelectorAll('input.amount')
const amount = [...amt_el].reduce((acc, cv) => acc += parseFloat(cv.value) || 0, 0)
row.querySelector('.sum.quantity').textContent = quantity
row.querySelector('.sum.amount').textContent = amount
});
}
window.setTimeout(function() {
document.querySelectorAll('input').forEach(() => this.onchange = changeEventHandler)
},0);
.sum { background: #eee; }
th,td {
vertical-align: bottom;
white-space: nowrap;
text-align: center;
}
table { width: 100%; }
input { width: 40%; }
Fill in each input with a number (watch sums auto-update):
<table>
<thead>
<tr>
<th>QTY 1</th>
<th>AMT 1</th>
<th>QTY 2</th>
<th>AMT 2</th>
<th>SUM QTY</th>
<th>SUM AMT</th>
</tr>
</thead>
<tbody>
<tr id='tr2'>
<!-- td: use class and not id -->
<!-- remove unnecessary classes -->
<td class="item_65"><span><input class='quantity'></span></td>
<td class="item_65"><span><input class='amount'></span></td>
<td class="item_66"><span><input class='quantity'></span></td>
<td class="item_66"><span><input class='amount'></span></td>
<td class="sum quantity"></td>
<td class="sum amount"></td>
</tr>
<tr id='tr3'>
<td class="item_65"><span><input class='quantity'></span></td>
<td class="item_65"><span><input class='amount'></span></td>
<td class="item_66"><span><input class='quantity'></span></td>
<td class="item_66"><span><input class='amount'></span></td>
<td class="sum quantity"></td>
<td class="sum amount"></td>
</tr>
<!-- More rows -->
</tbody>
</table>