计算table个数量和乘法
Calculating table quantity and multiplication
Table_exaple
你好,
我需要一些帮助。
我的问题是我不知道该怎么做。我的简单项目的重点是仅使用输入文本框创建一个 table,其中仅添加整数,并且我只需要对列求和。
As Quantity sum 我的意思是计算整列,通过 Calculated sum 我需要计算 Quantity * 标题的值。
例如:第 5$ 列的数量为 50,因此计算出的单元格必须为 250$。
我还想添加一个动态添加列的按钮,并且标题是自定义的...因此标题值也应该以某种方式保存为变量。
我用 jQuery 尝试了一些东西,但它不相关,因为无论我在标题中输入什么内容,我都希望动态计算它。
这是我对每一列的错误 jQuery,它有效,但这不是目标。
$(document).ready(function() {
$(".txt").each(function() {
$(this).keyup(function() {
calculateSum();
});
});
});
function calculateSum() {
var sum = 0;
$(".txt").each(function() {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$("#sum").html(sum);
$("#calc").html(sum);
}
$(document).ready(function() {
$(".txt1").each(function() {
$(this).keyup(function() {
calculateSum1();
});
});
});
function calculateSum1() {
var sum = 0;
$(".txt1").each(function() {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$("#sum1").html(sum);
$("#calc1").html(sum *= 2);
}
$(document).ready(function() {
$(".txt2").each(function() {
$(this).keyup(function() {
calculateSum2();
});
});
});
function calculateSum2() {
var sum = 0;
$(".txt2").each(function() {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$("#sum2").html(sum);
$("#calc2").html(sum *= 3);
}
$(document).ready(function() {
$(".txt3").each(function() {
$(this).keyup(function() {
calculateSum3();
});
});
});
function calculateSum3() {
var sum = 0;
$(".txt3").each(function() {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$("#sum3").html(sum);
$("#calc3").html(sum *= 5);
}
$(document).ready(function() {
$(".txt4").each(function() {
$(this).keyup(function() {
calculateSum4();
});
});
});
function calculateSum4() {
var sum = 0;
$(".txt4").each(function() {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$("#sum4").html(sum);
$("#calc4").html(sum *= 10);
}
$(document).ready(function() {
$(".txt5").each(function() {
$(this).keyup(function() {
calculateSum5();
});
});
});
function calculateSum5() {
var sum = 0;
$(".txt5").each(function() {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$("#sum5").html(sum);
$("#calc5").html(sum *= 20);
}
.tftable {
font-size: 12px;
color: #333333;
width: 70%;
margin-right: 15%;
margin-left: 15%;
border-width: 1px;
border-color: #a9a9a9;
border-collapse: collapse;
}
.tftable th {
font-size: 12px;
background-color: #6382c59a;
border-width: 1px;
padding: 18px;
border-style: solid;
border-color: #474747;
text-align: left;
}
.tftable tr {
background-color: #ffffff;
}
.tftable td {
font-size: 12px;
border-width: 2px;
padding: 5px;
border-style: solid;
border-color: #a9a9a9;
}
.tftable td:nth-child(2n+2) {
background: #CCC;
}
.tftable tr td input {
height: 100%;
background: none;
}
.tftable tr th {
font-size: 20px;
font-family: Arial, Helvetica, sans-serif;
text-align: center;
}
.tftable tr td {
font-family: Arial, Helvetica, sans-serif;
text-align: center;
width: 15rem;
}
.tftable tr td input {
border: none;
text-align: center;
padding: 0.7rem;
width: 78%;
}
.button {
padding: 7px 15px;
text-align: center;
color: #fff;
background-color: #04AA6D;
border: none;
border-radius: 5px;
}
.button:hover {
background-color: #3e8e41;
}
.button:active {
background-color: #3e8e41;
transform: scale(1.03);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<table id="tbl" class="tftable" border="1">
<tr>
<button class="button" onclick="addColumn()">Add Column</button>
<th>Types</th>
<th>1 $</th>
<th>2 $</th>
<th>3 $</th>
<th>5 $</th>
<th>10 $</th>
<th>20 $</th>
</tr>
<tr>
<td>Type 1</td>
<td><input type="text" class="txt" name="txt" id="1"></td>
<td><input type="text" class="txt1" name="txt" id="2"></td>
<td><input type="text" class="txt2" name="txt"></td>
<td><input type="text" class="txt3" name="txt"></td>
<td><input type="text" class="txt4" name="txt"></td>
<td><input type="text" class="txt5" name="txt"></td>
</tr>
<tr>
<td>Type 2</td>
<td><input type="text" class="txt" name="txt" id="1"></td>
<td><input type="text" class="txt1" name="txt" id="2"></td>
<td><input type="text" class="txt2" name="txt"></td>
<td><input type="text" class="txt3" name="txt"></td>
<td><input type="text" class="txt4" name="txt"></td>
<td><input type="text" class="txt5" name="txt"></td>
</tr>
<tr>
<td>Type 3</td>
<td><input type="text" class="txt" name="txt" id="1"></td>
<td><input type="text" class="txt1" name="txt" id="2"></td>
<td><input type="text" class="txt2" name="txt"></td>
<td><input type="text" class="txt3" name="txt"></td>
<td><input type="text" class="txt4" name="txt"></td>
<td><input type="text" class="txt5" name="txt"></td>
</tr>
<tr>
<td>Type 4</td>
<td><input type="text" class="txt" name="txt" id="1"></td>
<td><input type="text" class="txt1" name="txt" id="2"></td>
<td><input type="text" class="txt2" name="txt"></td>
<td><input type="text" class="txt3" name="txt"></td>
<td><input type="text" class="txt4" name="txt"></td>
<td><input type="text" class="txt5" name="txt"></td>
</tr>
<tr>
<td>Type 5</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt1" name="txt"></td>
<td><input type="text" class="txt2" name="txt"></td>
<td><input type="text" class="txt3" name="txt"></td>
<td><input type="text" class="txt4" name="txt"></td>
<td><input type="text" class="txt5" name="txt"></td>
</tr>
<tr>
<td>Type 6</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt1" name="txt"></td>
<td><input type="text" class="txt2" name="txt"></td>
<td><input type="text" class="txt3" name="txt"></td>
<td><input type="text" class="txt4" name="txt"></td>
<td><input type="text" class="txt5" name="txt"></td>
</tr>
<tr>
<td>Type 7</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt1" name="txt"></td>
<td><input type="text" class="txt2" name="txt"></td>
<td><input type="text" class="txt3" name="txt"></td>
<td><input type="text" class="txt4" name="txt"></td>
<td><input type="text" class="txt5" name="txt"></td>
</tr>
<tr>
<td>Type 8</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt1" name="txt"></td>
<td><input type="text" class="txt2" name="txt"></td>
<td><input type="text" class="txt3" name="txt"></td>
<td><input type="text" class="txt4" name="txt"></td>
<td><input type="text" class="txt5" name="txt"></td>
</tr>
<tr>
<td>Type 9</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt1" name="txt"></td>
<td><input type="text" class="txt2" name="txt"></td>
<td><input type="text" class="txt3" name="txt"></td>
<td><input type="text" class="txt4" name="txt"></td>
<td><input type="text" class="txt5" name="txt"></td>
</tr>
<tr>
<td>Type 10</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt1" name="txt"></td>
<td><input type="text" class="txt2" name="txt"></td>
<td><input type="text" class="txt3" name="txt"></td>
<td><input type="text" class="txt4" name="txt"></td>
<td><input type="text" class="txt5" name="txt"></td>
</tr>
<tr style="border-top: 5px solid black">
<td>Quantity</td>
<td><span id="sum"></span></td>
<td><span id="sum1"></span></td>
<td><span id="sum2"></span></td>
<td><span id="sum3"></span></td>
<td><span id="sum4"></span></td>
<td><span id="sum5"></span></td>
</tr>
<td>Calculated</td>
<td><span id="calc"></span></td>
<td><span id="calc1"></span></td>
<td><span id="calc2"></span></td>
<td><span id="calc3"></span></td>
<td><span id="calc4"></span></td>
<td><span id="calc5"></span></td>
</tr>
</table>
您要遵循的模式称为“不要重复自己”或 DRY。它的核心原则是创建不包含标识符的可重用通用结构,但只包含处理所需的任何元数据。
在这种情况下,您可以为所有 input
元素提供通用 class 名称,而不是增量名称或 id
。然后在 JS 中,您可以使用 index()
确定用户正在与哪个列进行交互。从那里您可以使用 map()
构建该列中所有值的数组并对它们求和。最后,您可以将列价格存储在标题的 data
属性中,然后将数量乘以该数字得到计算出的总数。
实际上它看起来像下面这样。请注意,此 JS 将适用于无限数量的行和列,它所依赖的只是 th
上的 data
属性以提供单价。
jQuery($ => {
$('.add-column').on('click', e => {
console.log('addColumn() logic here...');
});
let $table = $('#tbl');
$('.txt').on('input', e => {
let tdIndex = $(e.target).closest('td').index();
let colQuantities = $table.find(`tbody td:nth-child(${tdIndex + 1})`).map((i, td) => parseFloat($(td).find('input').val()) || null).get();
let colSum = colQuantities.reduce((acc, cur) => acc + cur, 0);
let colPrice = $table.find(`thead th:nth-child(${tdIndex + 1})`).data('price');
$table.find(`tbody td:nth-child(${tdIndex + 1}) .sum`).text(colSum);
$table.find(`tbody td:nth-child(${tdIndex + 1}) .calc`).text((colSum * colPrice).toLocaleString('en-US', {
style: 'currency',
currency: 'USD'
}));
});
});
input {
width: 50px;
}
.quantity-row {
border-top: 5px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="button add-column">Add Column</button>
<table id="tbl" class="tftable" border="1">
<thead>
<tr>
<th>Types</th>
<th data-price="1">1 $</th>
<th data-price="2">2 $</th>
<th data-price="3">3 $</th>
<th data-price="5">5 $</th>
<th data-price="10">10 $</th>
<th data-price="20">20 $</th>
</tr>
</thead>
<tbody>
<tr>
<td>Type 1</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
</tr>
<tr>
<td>Type 2</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
</tr>
<tr>
<td>Type 3</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
</tr>
<tr>
<td>Type 4</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
</tr>
<tr>
<td>Type 5</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
</tr>
<tr>
<td>Type 6</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
</tr>
<tr>
<td>Type 7</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
</tr>
<tr>
<td>Type 8</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
</tr>
<tr>
<td>Type 9</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
</tr>
<tr>
<td>Type 10</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
</tr>
<tr class="quantity-row">
<td>Quantity</td>
<td><span class="sum"></span></td>
<td><span class="sum"></span></td>
<td><span class="sum"></span></td>
<td><span class="sum"></span></td>
<td><span class="sum"></span></td>
<td><span class="sum"></span></td>
</tr>
<tr>
<td>Calculated</td>
<td><span class="calc"></span></td>
<td><span class="calc"></span></td>
<td><span class="calc"></span></td>
<td><span class="calc"></span></td>
<td><span class="calc"></span></td>
<td><span class="calc"></span></td>
</tr>
</tbody>
</table>
这里要注意的其他重要部分是您不需要为每个代码块重复 document.ready 个处理程序,您可以将依赖于它的所有逻辑放在一个处理程序中。
此外,您不应该使用 onclick
或其他 onX
属性,因为它们已经过时并且不再是好的做法。如上例所示,请改用不显眼的事件处理程序。
首先: $(document).ready()
侦听器只需要为输入声明事件侦听器。其余代码可以在外面。
计算
你有十次相同的事件侦听器和函数对。通过使用 $(this).parent().index()
获取包含单元格的输入的索引,您可以将其减少到只有一对。对于计算,您必须使用该索引作为参数调用函数 calculateSum()
。
在该函数中,您必须获取用于乘法的列的头部单元格的值。您可以通过 select 使用相同的索引 th
并将其 innerHTML
解析为数字来做到这一点。
let factor = parseFloat($("#tbl tr").first().find('th').eq(index).html());
最后你可以使用索引到 select 具有连接的列,例如:$("#sum" + index)
.
其余的就像您的代码一样。
添加一列
我建议不要在您的按钮中使用内联事件侦听器,而是在脚本中声明它。函数 addColumn()
将是监听器的匿名函数:
$('#add_column').click(function() {...});
在该函数中,您首先必须获取新头单元格的值(此处 price
)。函数的其余部分仅在值为真时执行(!!price
/转换为布尔值的双重否定),这意味着用户输入了一个值。
然后你必须得到每行输入的数量,例如从第二行:
const cell_count = $("#tbl tr").eq(2).find('input').length;
和 table 行数,减去最后两行“数量”和“计算”:
const row_count = $("#tbl tr").length - 2;
之后,您必须向每个 table 行添加一个新单元格。 table 行数用于迭代具有输入的行,每行输入数用于制作 id 和 类 串联。
最后,您需要重新声明输入的事件侦听器,以便考虑新的输入。为此,您首先必须删除旧的侦听器,然后重新声明它们。
$("#tbl input").off('keyup').on('keyup', function() {...});
工作示例:
因为没有使用输入的名称和 ID,为了简单起见,我删除了它们。我将过时的 var
更改为 let
和 const
.
function calculateSum(index) {
let factor = parseFloat($("#tbl tr").first().find('th').eq(index).html());
let sum = 0;
index = index == 1 ? '' : index - 1;
$(".txt" + index).each(function() {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$("#sum" + index).html(sum);
$("#calc" + index).html(sum * factor);
}
$(document).ready(function() {
$("#tbl input").on('keyup', function() {
calculateSum($(this).parent().index());
});
});
$('#add_column').click(function() {
const price = prompt('Add the price for the new column (only digits):', '30');
if (!!price) {
const cell_count = $("#tbl tr").eq(2).find('input').length;
const row_count = $("#tbl tr").length - 2;
for (let i = 1; i < row_count; i++) {
$("#tbl tr").eq(i).append(
$('<td></td>').append(
$('<input>').attr({
type: 'text'
}).addClass('txt' + cell_count)
)
);
}
$("#tbl tr").first().append(
$('<th></th>').html(price + ' $')
);
$("#tbl tr:nth-last-child(2)").append(
$('<td></td>').append(
$('<span></span>').attr({
id: ('sum' + cell_count)
})
)
);
$("#tbl tr:last-child").append(
$('<td></td>').append(
$('<span></span>').attr({
id: ('calc' + cell_count)
})
)
);
$("#tbl input").off('keyup').on('keyup', function() {
calculateSum($(this).parent().index());
});
}
});
.tftable {
font-size: 12px;
color: #333333;
width: 70%;
margin-right: 15%;
margin-left: 15%;
border-width: 1px;
border-color: #a9a9a9;
border-collapse: collapse;
}
.tftable th {
font-size: 12px;
background-color: #6382c59a;
border-width: 1px;
padding: 18px;
border-style: solid;
border-color: #474747;
text-align: left;
}
.tftable tr {
background-color: #ffffff;
}
.tftable td {
font-size: 12px;
border-width: 2px;
padding: 5px;
border-style: solid;
border-color: #a9a9a9;
}
.tftable td:nth-child(2n+2) {
background: #CCC;
}
.tftable tr td input {
height: 100%;
background: none;
}
.tftable tr th {
font-size: 20px;
font-family: Arial, Helvetica, sans-serif;
text-align: center;
}
.tftable tr td {
font-family: Arial, Helvetica, sans-serif;
text-align: center;
width: 15rem;
}
.tftable tr td input {
border: none;
text-align: center;
padding: 0.7rem;
width: 78%;
}
.button {
padding: 7px 15px;
text-align: center;
color: #fff;
background-color: #04AA6D;
border: none;
border-radius: 5px;
}
.button:hover {
background-color: #3e8e41;
}
.button:active {
background-color: #3e8e41;
transform: scale(1.03);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="add_column" class="button">Add Column</button>
<table id="tbl" class="tftable" border="1">
<tr>
<th>Types</th>
<th>1 $</th>
<th>2 $</th>
<th>3 $</th>
<th>5 $</th>
<th>10 $</th>
<th>20 $</th>
</tr>
<tr>
<td>Type 1</td>
<td><input type="text" class="txt"></td>
<td><input type="text" class="txt1"></td>
<td><input type="text" class="txt2"></td>
<td><input type="text" class="txt3"></td>
<td><input type="text" class="txt4"></td>
<td><input type="text" class="txt5"></td>
</tr>
<tr>
<td>Type 2</td>
<td><input type="text" class="txt"></td>
<td><input type="text" class="txt1"></td>
<td><input type="text" class="txt2"></td>
<td><input type="text" class="txt3"></td>
<td><input type="text" class="txt4"></td>
<td><input type="text" class="txt5"></td>
</tr>
<tr>
<td>Type 3</td>
<td><input type="text" class="txt"></td>
<td><input type="text" class="txt1"></td>
<td><input type="text" class="txt2"></td>
<td><input type="text" class="txt3"></td>
<td><input type="text" class="txt4"></td>
<td><input type="text" class="txt5"></td>
</tr>
<tr>
<td>Type 4</td>
<td><input type="text" class="txt"></td>
<td><input type="text" class="txt1"></td>
<td><input type="text" class="txt2"></td>
<td><input type="text" class="txt3"></td>
<td><input type="text" class="txt4"></td>
<td><input type="text" class="txt5"></td>
</tr>
<tr>
<td>Type 5</td>
<td><input type="text" class="txt"></td>
<td><input type="text" class="txt1"></td>
<td><input type="text" class="txt2"></td>
<td><input type="text" class="txt3"></td>
<td><input type="text" class="txt4"></td>
<td><input type="text" class="txt5"></td>
</tr>
<tr>
<td>Type 6</td>
<td><input type="text" class="txt"></td>
<td><input type="text" class="txt1"></td>
<td><input type="text" class="txt2"></td>
<td><input type="text" class="txt3"></td>
<td><input type="text" class="txt4"></td>
<td><input type="text" class="txt5"></td>
</tr>
<tr>
<td>Type 7</td>
<td><input type="text" class="txt"></td>
<td><input type="text" class="txt1"></td>
<td><input type="text" class="txt2"></td>
<td><input type="text" class="txt3"></td>
<td><input type="text" class="txt4"></td>
<td><input type="text" class="txt5"></td>
</tr>
<tr>
<td>Type 8</td>
<td><input type="text" class="txt"></td>
<td><input type="text" class="txt1"></td>
<td><input type="text" class="txt2"></td>
<td><input type="text" class="txt3"></td>
<td><input type="text" class="txt4"></td>
<td><input type="text" class="txt5"></td>
</tr>
<tr>
<td>Type 9</td>
<td><input type="text" class="txt"></td>
<td><input type="text" class="txt1"></td>
<td><input type="text" class="txt2"></td>
<td><input type="text" class="txt3"></td>
<td><input type="text" class="txt4"></td>
<td><input type="text" class="txt5"></td>
</tr>
<tr>
<td>Type 10</td>
<td><input type="text" class="txt"></td>
<td><input type="text" class="txt1"></td>
<td><input type="text" class="txt2"></td>
<td><input type="text" class="txt3"></td>
<td><input type="text" class="txt4"></td>
<td><input type="text" class="txt5"></td>
</tr>
<tr style="border-top: 5px solid black">
<td>Quantity</td>
<td><span id="sum"></span></td>
<td><span id="sum1"></span></td>
<td><span id="sum2"></span></td>
<td><span id="sum3"></span></td>
<td><span id="sum4"></span></td>
<td><span id="sum5"></span></td>
</tr>
<tr>
<td>Calculated</td>
<td><span id="calc"></span></td>
<td><span id="calc1"></span></td>
<td><span id="calc2"></span></td>
<td><span id="calc3"></span></td>
<td><span id="calc4"></span></td>
<td><span id="calc5"></span></td>
</tr>
</table>
Table_exaple 你好,
我需要一些帮助。
我的问题是我不知道该怎么做。我的简单项目的重点是仅使用输入文本框创建一个 table,其中仅添加整数,并且我只需要对列求和。
As Quantity sum 我的意思是计算整列,通过 Calculated sum 我需要计算 Quantity * 标题的值。
例如:第 5$ 列的数量为 50,因此计算出的单元格必须为 250$。
我还想添加一个动态添加列的按钮,并且标题是自定义的...因此标题值也应该以某种方式保存为变量。
我用 jQuery 尝试了一些东西,但它不相关,因为无论我在标题中输入什么内容,我都希望动态计算它。
这是我对每一列的错误 jQuery,它有效,但这不是目标。
$(document).ready(function() {
$(".txt").each(function() {
$(this).keyup(function() {
calculateSum();
});
});
});
function calculateSum() {
var sum = 0;
$(".txt").each(function() {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$("#sum").html(sum);
$("#calc").html(sum);
}
$(document).ready(function() {
$(".txt1").each(function() {
$(this).keyup(function() {
calculateSum1();
});
});
});
function calculateSum1() {
var sum = 0;
$(".txt1").each(function() {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$("#sum1").html(sum);
$("#calc1").html(sum *= 2);
}
$(document).ready(function() {
$(".txt2").each(function() {
$(this).keyup(function() {
calculateSum2();
});
});
});
function calculateSum2() {
var sum = 0;
$(".txt2").each(function() {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$("#sum2").html(sum);
$("#calc2").html(sum *= 3);
}
$(document).ready(function() {
$(".txt3").each(function() {
$(this).keyup(function() {
calculateSum3();
});
});
});
function calculateSum3() {
var sum = 0;
$(".txt3").each(function() {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$("#sum3").html(sum);
$("#calc3").html(sum *= 5);
}
$(document).ready(function() {
$(".txt4").each(function() {
$(this).keyup(function() {
calculateSum4();
});
});
});
function calculateSum4() {
var sum = 0;
$(".txt4").each(function() {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$("#sum4").html(sum);
$("#calc4").html(sum *= 10);
}
$(document).ready(function() {
$(".txt5").each(function() {
$(this).keyup(function() {
calculateSum5();
});
});
});
function calculateSum5() {
var sum = 0;
$(".txt5").each(function() {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$("#sum5").html(sum);
$("#calc5").html(sum *= 20);
}
.tftable {
font-size: 12px;
color: #333333;
width: 70%;
margin-right: 15%;
margin-left: 15%;
border-width: 1px;
border-color: #a9a9a9;
border-collapse: collapse;
}
.tftable th {
font-size: 12px;
background-color: #6382c59a;
border-width: 1px;
padding: 18px;
border-style: solid;
border-color: #474747;
text-align: left;
}
.tftable tr {
background-color: #ffffff;
}
.tftable td {
font-size: 12px;
border-width: 2px;
padding: 5px;
border-style: solid;
border-color: #a9a9a9;
}
.tftable td:nth-child(2n+2) {
background: #CCC;
}
.tftable tr td input {
height: 100%;
background: none;
}
.tftable tr th {
font-size: 20px;
font-family: Arial, Helvetica, sans-serif;
text-align: center;
}
.tftable tr td {
font-family: Arial, Helvetica, sans-serif;
text-align: center;
width: 15rem;
}
.tftable tr td input {
border: none;
text-align: center;
padding: 0.7rem;
width: 78%;
}
.button {
padding: 7px 15px;
text-align: center;
color: #fff;
background-color: #04AA6D;
border: none;
border-radius: 5px;
}
.button:hover {
background-color: #3e8e41;
}
.button:active {
background-color: #3e8e41;
transform: scale(1.03);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<table id="tbl" class="tftable" border="1">
<tr>
<button class="button" onclick="addColumn()">Add Column</button>
<th>Types</th>
<th>1 $</th>
<th>2 $</th>
<th>3 $</th>
<th>5 $</th>
<th>10 $</th>
<th>20 $</th>
</tr>
<tr>
<td>Type 1</td>
<td><input type="text" class="txt" name="txt" id="1"></td>
<td><input type="text" class="txt1" name="txt" id="2"></td>
<td><input type="text" class="txt2" name="txt"></td>
<td><input type="text" class="txt3" name="txt"></td>
<td><input type="text" class="txt4" name="txt"></td>
<td><input type="text" class="txt5" name="txt"></td>
</tr>
<tr>
<td>Type 2</td>
<td><input type="text" class="txt" name="txt" id="1"></td>
<td><input type="text" class="txt1" name="txt" id="2"></td>
<td><input type="text" class="txt2" name="txt"></td>
<td><input type="text" class="txt3" name="txt"></td>
<td><input type="text" class="txt4" name="txt"></td>
<td><input type="text" class="txt5" name="txt"></td>
</tr>
<tr>
<td>Type 3</td>
<td><input type="text" class="txt" name="txt" id="1"></td>
<td><input type="text" class="txt1" name="txt" id="2"></td>
<td><input type="text" class="txt2" name="txt"></td>
<td><input type="text" class="txt3" name="txt"></td>
<td><input type="text" class="txt4" name="txt"></td>
<td><input type="text" class="txt5" name="txt"></td>
</tr>
<tr>
<td>Type 4</td>
<td><input type="text" class="txt" name="txt" id="1"></td>
<td><input type="text" class="txt1" name="txt" id="2"></td>
<td><input type="text" class="txt2" name="txt"></td>
<td><input type="text" class="txt3" name="txt"></td>
<td><input type="text" class="txt4" name="txt"></td>
<td><input type="text" class="txt5" name="txt"></td>
</tr>
<tr>
<td>Type 5</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt1" name="txt"></td>
<td><input type="text" class="txt2" name="txt"></td>
<td><input type="text" class="txt3" name="txt"></td>
<td><input type="text" class="txt4" name="txt"></td>
<td><input type="text" class="txt5" name="txt"></td>
</tr>
<tr>
<td>Type 6</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt1" name="txt"></td>
<td><input type="text" class="txt2" name="txt"></td>
<td><input type="text" class="txt3" name="txt"></td>
<td><input type="text" class="txt4" name="txt"></td>
<td><input type="text" class="txt5" name="txt"></td>
</tr>
<tr>
<td>Type 7</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt1" name="txt"></td>
<td><input type="text" class="txt2" name="txt"></td>
<td><input type="text" class="txt3" name="txt"></td>
<td><input type="text" class="txt4" name="txt"></td>
<td><input type="text" class="txt5" name="txt"></td>
</tr>
<tr>
<td>Type 8</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt1" name="txt"></td>
<td><input type="text" class="txt2" name="txt"></td>
<td><input type="text" class="txt3" name="txt"></td>
<td><input type="text" class="txt4" name="txt"></td>
<td><input type="text" class="txt5" name="txt"></td>
</tr>
<tr>
<td>Type 9</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt1" name="txt"></td>
<td><input type="text" class="txt2" name="txt"></td>
<td><input type="text" class="txt3" name="txt"></td>
<td><input type="text" class="txt4" name="txt"></td>
<td><input type="text" class="txt5" name="txt"></td>
</tr>
<tr>
<td>Type 10</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt1" name="txt"></td>
<td><input type="text" class="txt2" name="txt"></td>
<td><input type="text" class="txt3" name="txt"></td>
<td><input type="text" class="txt4" name="txt"></td>
<td><input type="text" class="txt5" name="txt"></td>
</tr>
<tr style="border-top: 5px solid black">
<td>Quantity</td>
<td><span id="sum"></span></td>
<td><span id="sum1"></span></td>
<td><span id="sum2"></span></td>
<td><span id="sum3"></span></td>
<td><span id="sum4"></span></td>
<td><span id="sum5"></span></td>
</tr>
<td>Calculated</td>
<td><span id="calc"></span></td>
<td><span id="calc1"></span></td>
<td><span id="calc2"></span></td>
<td><span id="calc3"></span></td>
<td><span id="calc4"></span></td>
<td><span id="calc5"></span></td>
</tr>
</table>
您要遵循的模式称为“不要重复自己”或 DRY。它的核心原则是创建不包含标识符的可重用通用结构,但只包含处理所需的任何元数据。
在这种情况下,您可以为所有 input
元素提供通用 class 名称,而不是增量名称或 id
。然后在 JS 中,您可以使用 index()
确定用户正在与哪个列进行交互。从那里您可以使用 map()
构建该列中所有值的数组并对它们求和。最后,您可以将列价格存储在标题的 data
属性中,然后将数量乘以该数字得到计算出的总数。
实际上它看起来像下面这样。请注意,此 JS 将适用于无限数量的行和列,它所依赖的只是 th
上的 data
属性以提供单价。
jQuery($ => {
$('.add-column').on('click', e => {
console.log('addColumn() logic here...');
});
let $table = $('#tbl');
$('.txt').on('input', e => {
let tdIndex = $(e.target).closest('td').index();
let colQuantities = $table.find(`tbody td:nth-child(${tdIndex + 1})`).map((i, td) => parseFloat($(td).find('input').val()) || null).get();
let colSum = colQuantities.reduce((acc, cur) => acc + cur, 0);
let colPrice = $table.find(`thead th:nth-child(${tdIndex + 1})`).data('price');
$table.find(`tbody td:nth-child(${tdIndex + 1}) .sum`).text(colSum);
$table.find(`tbody td:nth-child(${tdIndex + 1}) .calc`).text((colSum * colPrice).toLocaleString('en-US', {
style: 'currency',
currency: 'USD'
}));
});
});
input {
width: 50px;
}
.quantity-row {
border-top: 5px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="button add-column">Add Column</button>
<table id="tbl" class="tftable" border="1">
<thead>
<tr>
<th>Types</th>
<th data-price="1">1 $</th>
<th data-price="2">2 $</th>
<th data-price="3">3 $</th>
<th data-price="5">5 $</th>
<th data-price="10">10 $</th>
<th data-price="20">20 $</th>
</tr>
</thead>
<tbody>
<tr>
<td>Type 1</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
</tr>
<tr>
<td>Type 2</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
</tr>
<tr>
<td>Type 3</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
</tr>
<tr>
<td>Type 4</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
</tr>
<tr>
<td>Type 5</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
</tr>
<tr>
<td>Type 6</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
</tr>
<tr>
<td>Type 7</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
</tr>
<tr>
<td>Type 8</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
</tr>
<tr>
<td>Type 9</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
</tr>
<tr>
<td>Type 10</td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
<td><input type="text" class="txt" name="txt"></td>
</tr>
<tr class="quantity-row">
<td>Quantity</td>
<td><span class="sum"></span></td>
<td><span class="sum"></span></td>
<td><span class="sum"></span></td>
<td><span class="sum"></span></td>
<td><span class="sum"></span></td>
<td><span class="sum"></span></td>
</tr>
<tr>
<td>Calculated</td>
<td><span class="calc"></span></td>
<td><span class="calc"></span></td>
<td><span class="calc"></span></td>
<td><span class="calc"></span></td>
<td><span class="calc"></span></td>
<td><span class="calc"></span></td>
</tr>
</tbody>
</table>
这里要注意的其他重要部分是您不需要为每个代码块重复 document.ready 个处理程序,您可以将依赖于它的所有逻辑放在一个处理程序中。
此外,您不应该使用 onclick
或其他 onX
属性,因为它们已经过时并且不再是好的做法。如上例所示,请改用不显眼的事件处理程序。
首先: $(document).ready()
侦听器只需要为输入声明事件侦听器。其余代码可以在外面。
计算
你有十次相同的事件侦听器和函数对。通过使用 $(this).parent().index()
获取包含单元格的输入的索引,您可以将其减少到只有一对。对于计算,您必须使用该索引作为参数调用函数 calculateSum()
。
在该函数中,您必须获取用于乘法的列的头部单元格的值。您可以通过 select 使用相同的索引 th
并将其 innerHTML
解析为数字来做到这一点。
let factor = parseFloat($("#tbl tr").first().find('th').eq(index).html());
最后你可以使用索引到 select 具有连接的列,例如:$("#sum" + index)
.
其余的就像您的代码一样。
添加一列
我建议不要在您的按钮中使用内联事件侦听器,而是在脚本中声明它。函数 addColumn()
将是监听器的匿名函数:
$('#add_column').click(function() {...});
在该函数中,您首先必须获取新头单元格的值(此处 price
)。函数的其余部分仅在值为真时执行(!!price
/转换为布尔值的双重否定),这意味着用户输入了一个值。
然后你必须得到每行输入的数量,例如从第二行:
const cell_count = $("#tbl tr").eq(2).find('input').length;
和 table 行数,减去最后两行“数量”和“计算”:
const row_count = $("#tbl tr").length - 2;
之后,您必须向每个 table 行添加一个新单元格。 table 行数用于迭代具有输入的行,每行输入数用于制作 id 和 类 串联。
最后,您需要重新声明输入的事件侦听器,以便考虑新的输入。为此,您首先必须删除旧的侦听器,然后重新声明它们。
$("#tbl input").off('keyup').on('keyup', function() {...});
工作示例:
因为没有使用输入的名称和 ID,为了简单起见,我删除了它们。我将过时的 var
更改为 let
和 const
.
function calculateSum(index) {
let factor = parseFloat($("#tbl tr").first().find('th').eq(index).html());
let sum = 0;
index = index == 1 ? '' : index - 1;
$(".txt" + index).each(function() {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$("#sum" + index).html(sum);
$("#calc" + index).html(sum * factor);
}
$(document).ready(function() {
$("#tbl input").on('keyup', function() {
calculateSum($(this).parent().index());
});
});
$('#add_column').click(function() {
const price = prompt('Add the price for the new column (only digits):', '30');
if (!!price) {
const cell_count = $("#tbl tr").eq(2).find('input').length;
const row_count = $("#tbl tr").length - 2;
for (let i = 1; i < row_count; i++) {
$("#tbl tr").eq(i).append(
$('<td></td>').append(
$('<input>').attr({
type: 'text'
}).addClass('txt' + cell_count)
)
);
}
$("#tbl tr").first().append(
$('<th></th>').html(price + ' $')
);
$("#tbl tr:nth-last-child(2)").append(
$('<td></td>').append(
$('<span></span>').attr({
id: ('sum' + cell_count)
})
)
);
$("#tbl tr:last-child").append(
$('<td></td>').append(
$('<span></span>').attr({
id: ('calc' + cell_count)
})
)
);
$("#tbl input").off('keyup').on('keyup', function() {
calculateSum($(this).parent().index());
});
}
});
.tftable {
font-size: 12px;
color: #333333;
width: 70%;
margin-right: 15%;
margin-left: 15%;
border-width: 1px;
border-color: #a9a9a9;
border-collapse: collapse;
}
.tftable th {
font-size: 12px;
background-color: #6382c59a;
border-width: 1px;
padding: 18px;
border-style: solid;
border-color: #474747;
text-align: left;
}
.tftable tr {
background-color: #ffffff;
}
.tftable td {
font-size: 12px;
border-width: 2px;
padding: 5px;
border-style: solid;
border-color: #a9a9a9;
}
.tftable td:nth-child(2n+2) {
background: #CCC;
}
.tftable tr td input {
height: 100%;
background: none;
}
.tftable tr th {
font-size: 20px;
font-family: Arial, Helvetica, sans-serif;
text-align: center;
}
.tftable tr td {
font-family: Arial, Helvetica, sans-serif;
text-align: center;
width: 15rem;
}
.tftable tr td input {
border: none;
text-align: center;
padding: 0.7rem;
width: 78%;
}
.button {
padding: 7px 15px;
text-align: center;
color: #fff;
background-color: #04AA6D;
border: none;
border-radius: 5px;
}
.button:hover {
background-color: #3e8e41;
}
.button:active {
background-color: #3e8e41;
transform: scale(1.03);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="add_column" class="button">Add Column</button>
<table id="tbl" class="tftable" border="1">
<tr>
<th>Types</th>
<th>1 $</th>
<th>2 $</th>
<th>3 $</th>
<th>5 $</th>
<th>10 $</th>
<th>20 $</th>
</tr>
<tr>
<td>Type 1</td>
<td><input type="text" class="txt"></td>
<td><input type="text" class="txt1"></td>
<td><input type="text" class="txt2"></td>
<td><input type="text" class="txt3"></td>
<td><input type="text" class="txt4"></td>
<td><input type="text" class="txt5"></td>
</tr>
<tr>
<td>Type 2</td>
<td><input type="text" class="txt"></td>
<td><input type="text" class="txt1"></td>
<td><input type="text" class="txt2"></td>
<td><input type="text" class="txt3"></td>
<td><input type="text" class="txt4"></td>
<td><input type="text" class="txt5"></td>
</tr>
<tr>
<td>Type 3</td>
<td><input type="text" class="txt"></td>
<td><input type="text" class="txt1"></td>
<td><input type="text" class="txt2"></td>
<td><input type="text" class="txt3"></td>
<td><input type="text" class="txt4"></td>
<td><input type="text" class="txt5"></td>
</tr>
<tr>
<td>Type 4</td>
<td><input type="text" class="txt"></td>
<td><input type="text" class="txt1"></td>
<td><input type="text" class="txt2"></td>
<td><input type="text" class="txt3"></td>
<td><input type="text" class="txt4"></td>
<td><input type="text" class="txt5"></td>
</tr>
<tr>
<td>Type 5</td>
<td><input type="text" class="txt"></td>
<td><input type="text" class="txt1"></td>
<td><input type="text" class="txt2"></td>
<td><input type="text" class="txt3"></td>
<td><input type="text" class="txt4"></td>
<td><input type="text" class="txt5"></td>
</tr>
<tr>
<td>Type 6</td>
<td><input type="text" class="txt"></td>
<td><input type="text" class="txt1"></td>
<td><input type="text" class="txt2"></td>
<td><input type="text" class="txt3"></td>
<td><input type="text" class="txt4"></td>
<td><input type="text" class="txt5"></td>
</tr>
<tr>
<td>Type 7</td>
<td><input type="text" class="txt"></td>
<td><input type="text" class="txt1"></td>
<td><input type="text" class="txt2"></td>
<td><input type="text" class="txt3"></td>
<td><input type="text" class="txt4"></td>
<td><input type="text" class="txt5"></td>
</tr>
<tr>
<td>Type 8</td>
<td><input type="text" class="txt"></td>
<td><input type="text" class="txt1"></td>
<td><input type="text" class="txt2"></td>
<td><input type="text" class="txt3"></td>
<td><input type="text" class="txt4"></td>
<td><input type="text" class="txt5"></td>
</tr>
<tr>
<td>Type 9</td>
<td><input type="text" class="txt"></td>
<td><input type="text" class="txt1"></td>
<td><input type="text" class="txt2"></td>
<td><input type="text" class="txt3"></td>
<td><input type="text" class="txt4"></td>
<td><input type="text" class="txt5"></td>
</tr>
<tr>
<td>Type 10</td>
<td><input type="text" class="txt"></td>
<td><input type="text" class="txt1"></td>
<td><input type="text" class="txt2"></td>
<td><input type="text" class="txt3"></td>
<td><input type="text" class="txt4"></td>
<td><input type="text" class="txt5"></td>
</tr>
<tr style="border-top: 5px solid black">
<td>Quantity</td>
<td><span id="sum"></span></td>
<td><span id="sum1"></span></td>
<td><span id="sum2"></span></td>
<td><span id="sum3"></span></td>
<td><span id="sum4"></span></td>
<td><span id="sum5"></span></td>
</tr>
<tr>
<td>Calculated</td>
<td><span id="calc"></span></td>
<td><span id="calc1"></span></td>
<td><span id="calc2"></span></td>
<td><span id="calc3"></span></td>
<td><span id="calc4"></span></td>
<td><span id="calc5"></span></td>
</tr>
</table>