Table_exaple 你好,
我需要一些帮助。
我的问题是我不知道如何做到这一点。我的简单项目的重点是创建一个只包含输入文本框的表格,其中只添加整数,我只需要对列求和。
作为数量总和,我的意思是计算整列,通过计算总和,我需要计算标题的数量 * 值。
例如:第 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>
答案 0 :(得分:2)
您希望遵循的模式称为“不要重复自己”或 DRY。它的核心原则是创建可重用的通用结构,这些结构不包含标识符,而只包含处理所需的任何元数据。
在这种情况下,您可以为所有 input
元素提供通用类名,而不是增量类名或 id
。然后在 JS 中,您可以使用 index()
确定用户正在与哪一列交互。从那里您可以使用 map()
构建该列中所有值的数组并将它们相加。最后,您可以将列价格存储在标题的 data
属性中,然后将数量乘以该数字,得出计算所得的总数。
在实践中,它看起来像下面这样。请注意,此 JS 将适用于无限数量的行和列,它仅依赖于 data
上的 th
属性以提供单价。
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
属性,因为它们已过时且不再是良好做法。改用不显眼的事件处理程序,如上例所示。
答案 1 :(得分:1)
首先: $(document).ready()
侦听器仅用于为输入声明事件侦听器。其余的代码可以在外面。
您拥有十倍相同的事件侦听器和函数对。通过使用 $(this).parent().index()
获取包含单元格的输入的索引,您可以将其减少到只有一对。对于计算,您必须使用该索引作为参数调用函数 calculateSum()
。
在函数中,您必须获取乘法列的头单元格的值。您可以通过选择具有相同索引的 th
并将其 innerHTML
解析为数字来执行此操作。
let factor = parseFloat($("#tbl tr").first().find('th').eq(index).html());
最后您可以使用索引选择带有串联的列,例如:$("#sum" + index)
。
其余部分与您的代码一样。
我建议不要在按钮中使用内联事件侦听器,而是在脚本中声明它。函数 addColumn()
将是侦听器的匿名函数:
$('#add_column').click(function() {...});
在该函数中,您首先必须获得新头部单元格的值(此处为 price
)。该函数的其余部分仅在值为 true(!!price
/ 转换为布尔值的双重否定)时才执行,这意味着用户输入了一个值。
然后您必须获得每行的输入数,例如从第二行:
const cell_count = $("#tbl tr").eq(2).find('input').length;
以及表格行数,减去最后两行“Quantity”和“Calculated”:
const row_count = $("#tbl tr").length - 2;
之后,您必须向每个表格行添加一个新单元格。表行数用于迭代具有输入的行,每行输入数用于制作具有串联的 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>