jQuery 对行和列的值求和的脚本
jQuery script to sum values on rows and columns
我有以下 table 结构:
<table width="960" border="1" align="center" id="activity_table">
<tr>
<td width="192">Activity</td>
<td width="192" align="center">Option 1</td>
<td width="192" align="center">Option 2</td>
<td width="192" align="center">Total</td>
</tr>
<tr>
<td>Activity 1</td>
<td align="center">
<input type="text" name="activity_1_option_1" id="activity_1_option_1" value="0" class="col1" size="10" />
</td>
<td align="center">
<input type="text" name="activity_1_option_2" id="activity_1_option_2" value="0" class="col2" size="10" />
</td>
<td align="center">
<input type="text" name="activity_1_total" id="activity_1_total" value="0" class="" size="10" readonly />
</td>
</tr>
<tr>
<td>Activity 2</td>
<td align="center">
<input type="text" name="activity_2_option_1" id="activity_2_option_1" value="0" class="col1" size="10" />
</td>
<td align="center">
<input type="text" name="activity_2_option_2" id="activity_2_option_2" value="0" class="col2" size="10" />
</td>
<td align="center">
<input type="text" name="activity_2_total" id="activity_2_total" value="0" class="" size="10" readonly />
</td>
</tr>
<tr>
<td>Activity 3</td>
<td align="center">
<input type="text" name="activity_3_option_1" id="activity_3_option_1" value="0" class="col1" size="10" />
</td>
<td align="center">
<input type="text" name="activity_3_option_2" id="activity_3_option_2" value="0" class="col2" size="10" />
</td>
<td align="center">
<input type="text" name="activity_3_total" id="activity_3_total" value="0" class="" size="10" readonly />
</td>
</tr>
<tr class="total">
<td>Total</td>
<td align="center">
<input type="text" name="total_activity_1" id="total_activity_1" value="0" class="" size="10" readonly />
</td>
<td align="center">
<input type="text" name="total_activity_2" id="total_activity_2" value="0" class="" size="10" readonly />
</td>
<td align="center">
<input type="text" name="grand_total" id="grand_total" value="0" class="" size="10" readonly />
</td>
</tr>
我想做的是自动计算每一列和每一行的总和。
我设法编写了一个 jQuery 脚本来计算每列的总和,方法是添加 colX(其中 X 是列的编号)作为我想要的列的 class总和,但我不知道该怎么做才能为行工作。
这是我的脚本:
$('#activity_table tr:not(.total) input:text').bind('keyup change', function() {
var $table = $(this).closest('table');
var total = 0;
var thisNumber = $(this).attr('class').match(/(\d+)/)[1];
$table.find('tr:not(.total) .col'+thisNumber).each(function() {
total += +$(this).val();
});
thisNumber++;
$table.find('.total td:nth-child('+thisNumber+') input').val(total);
});
我对你的 HTML 做了一些调整。总共 row/column 有 classes 可以让你一次 select 它们。避免使用正则表达式 selecting 元素,因为这会非常慢。如有必要,您可以使用两个 class,例如 column column123
,它允许您 select 组或单个项目 class 名称。为了快速访问元素的索引,我使用 data-
属性。如果元素是由 jQuery 代码生成的,您还可以使用 JavaScript 数据对象 ("hashes") 或 jQuery 的 .data()
.
<html>
<head>
<script src="jquery.js"></script>
<script>
var rows = 3;
var cols = 2;
$( function() {
var grand_total = 0;
var row_totals = {};
var col_totals = {};
// I think there should be better approaches on initializing these
for( var row = 1; row <= rows; row++ ) { row_totals[ row ] = 0 }
for( var col = 1; col <= cols; col++ ) { col_totals[ col ] = 0 }
$('input').each( function() {
var $this = $(this);
var val = $this.val() * 1; // the multiplication is to prevent string concatenation
row_totals[ $this.attr('data-row') ] += val;
col_totals[ $this.attr('data-col') ] += val;
grand_total += val;
} );
$('.total.row').each( function() {
var $this = $(this);
$this.text( row_totals[ $this.attr('data-row') ] );
} );
$('.total.col').each( function() {
var $this = $(this);
$this.text( col_totals[ $this.attr('data-col') ] );
} );
$('.grand_total').text = grand_total;
} );
</script>
</head>
<body>
<table>
<tr>
<td class="total row" data-row="1"></td>
<td><input data-row="1" data-col="1" type="text" value="1">
<td><input data-row="1" data-col="2" type="text" value="2">
</tr>
<tr>
<td class="total row" data-row="2"></td>
<td><input data-row="2" data-col="1" type="text" value="3">
<td><input data-row="2" data-col="2" type="text" value="4">
</tr>
<tr>
<td class="total row" data-row="3"></td>
<td><input data-row="3" data-col="1" type="text" value="5">
<td><input data-row="3" data-col="2" type="text" value="6">
</tr>
<tr>
<td class="grand_total"></td>
<td class="total col" data-col="1"></td>
<td class="total col" data-col="2"></td>
</tr>
</table>
</body>
</html>
您可以在不引用 table.
中的任何 类、名称或 ID 的情况下执行此操作
下面的代码获取每列的总数。
它通过获取第 2 行 (tr:eq(1)
) 中每个 td
的 cellIndex
来工作, 不是 第一个或最后一列。然后,它会过滤除第一行以外的所有行上具有匹配 cellIndex
的 td
。如果有一个 input
元素,它的值将添加到 运行 总数中。否则,我们位于列中的最后一个单元格,它获取总值。
$('td:not(:first-child):not(:last-child)',
'#activity_table tr:eq(1)').each(function() {
var ci= this.cellIndex;
var total = 0;
$('td',
'#activity_table tr:gt(0)')
.filter(function() {
return this.cellIndex === ci;
})
.each(function() {
var inp= $('input', this);
if(inp.length) {
if(!$(this).closest('tr').is(':last-child')) {
total+= $('input', this).val()*1;
}
else {
$('input', this).val(total);
}
}
});
});
下面的代码获取每一行的总数。
它遍历每一行,总计其 input
个元素。
$('#activity_table tr:gt(0)').each(function() {
var total = 0;
$('td:not(:first-child):not(:last-child)',
this).each(function() {
total+= $('input', this).val()*1;
});
$('input', this).last().val(total);
});
请注意 on
is now preferred over bind
。如果您从总计列和总计行中删除 input
,您的事件处理程序将简化为:
$('#activity_table input').on('keyup change',...
我建议将所有样式移动到一个样式表中。我已经在 Fiddle:
中这样做了
我有以下 table 结构:
<table width="960" border="1" align="center" id="activity_table">
<tr>
<td width="192">Activity</td>
<td width="192" align="center">Option 1</td>
<td width="192" align="center">Option 2</td>
<td width="192" align="center">Total</td>
</tr>
<tr>
<td>Activity 1</td>
<td align="center">
<input type="text" name="activity_1_option_1" id="activity_1_option_1" value="0" class="col1" size="10" />
</td>
<td align="center">
<input type="text" name="activity_1_option_2" id="activity_1_option_2" value="0" class="col2" size="10" />
</td>
<td align="center">
<input type="text" name="activity_1_total" id="activity_1_total" value="0" class="" size="10" readonly />
</td>
</tr>
<tr>
<td>Activity 2</td>
<td align="center">
<input type="text" name="activity_2_option_1" id="activity_2_option_1" value="0" class="col1" size="10" />
</td>
<td align="center">
<input type="text" name="activity_2_option_2" id="activity_2_option_2" value="0" class="col2" size="10" />
</td>
<td align="center">
<input type="text" name="activity_2_total" id="activity_2_total" value="0" class="" size="10" readonly />
</td>
</tr>
<tr>
<td>Activity 3</td>
<td align="center">
<input type="text" name="activity_3_option_1" id="activity_3_option_1" value="0" class="col1" size="10" />
</td>
<td align="center">
<input type="text" name="activity_3_option_2" id="activity_3_option_2" value="0" class="col2" size="10" />
</td>
<td align="center">
<input type="text" name="activity_3_total" id="activity_3_total" value="0" class="" size="10" readonly />
</td>
</tr>
<tr class="total">
<td>Total</td>
<td align="center">
<input type="text" name="total_activity_1" id="total_activity_1" value="0" class="" size="10" readonly />
</td>
<td align="center">
<input type="text" name="total_activity_2" id="total_activity_2" value="0" class="" size="10" readonly />
</td>
<td align="center">
<input type="text" name="grand_total" id="grand_total" value="0" class="" size="10" readonly />
</td>
</tr>
我想做的是自动计算每一列和每一行的总和。
我设法编写了一个 jQuery 脚本来计算每列的总和,方法是添加 colX(其中 X 是列的编号)作为我想要的列的 class总和,但我不知道该怎么做才能为行工作。
这是我的脚本:
$('#activity_table tr:not(.total) input:text').bind('keyup change', function() {
var $table = $(this).closest('table');
var total = 0;
var thisNumber = $(this).attr('class').match(/(\d+)/)[1];
$table.find('tr:not(.total) .col'+thisNumber).each(function() {
total += +$(this).val();
});
thisNumber++;
$table.find('.total td:nth-child('+thisNumber+') input').val(total);
});
我对你的 HTML 做了一些调整。总共 row/column 有 classes 可以让你一次 select 它们。避免使用正则表达式 selecting 元素,因为这会非常慢。如有必要,您可以使用两个 class,例如 column column123
,它允许您 select 组或单个项目 class 名称。为了快速访问元素的索引,我使用 data-
属性。如果元素是由 jQuery 代码生成的,您还可以使用 JavaScript 数据对象 ("hashes") 或 jQuery 的 .data()
.
<html>
<head>
<script src="jquery.js"></script>
<script>
var rows = 3;
var cols = 2;
$( function() {
var grand_total = 0;
var row_totals = {};
var col_totals = {};
// I think there should be better approaches on initializing these
for( var row = 1; row <= rows; row++ ) { row_totals[ row ] = 0 }
for( var col = 1; col <= cols; col++ ) { col_totals[ col ] = 0 }
$('input').each( function() {
var $this = $(this);
var val = $this.val() * 1; // the multiplication is to prevent string concatenation
row_totals[ $this.attr('data-row') ] += val;
col_totals[ $this.attr('data-col') ] += val;
grand_total += val;
} );
$('.total.row').each( function() {
var $this = $(this);
$this.text( row_totals[ $this.attr('data-row') ] );
} );
$('.total.col').each( function() {
var $this = $(this);
$this.text( col_totals[ $this.attr('data-col') ] );
} );
$('.grand_total').text = grand_total;
} );
</script>
</head>
<body>
<table>
<tr>
<td class="total row" data-row="1"></td>
<td><input data-row="1" data-col="1" type="text" value="1">
<td><input data-row="1" data-col="2" type="text" value="2">
</tr>
<tr>
<td class="total row" data-row="2"></td>
<td><input data-row="2" data-col="1" type="text" value="3">
<td><input data-row="2" data-col="2" type="text" value="4">
</tr>
<tr>
<td class="total row" data-row="3"></td>
<td><input data-row="3" data-col="1" type="text" value="5">
<td><input data-row="3" data-col="2" type="text" value="6">
</tr>
<tr>
<td class="grand_total"></td>
<td class="total col" data-col="1"></td>
<td class="total col" data-col="2"></td>
</tr>
</table>
</body>
</html>
您可以在不引用 table.
中的任何 类、名称或 ID 的情况下执行此操作下面的代码获取每列的总数。
它通过获取第 2 行 (tr:eq(1)
) 中每个 td
的 cellIndex
来工作, 不是 第一个或最后一列。然后,它会过滤除第一行以外的所有行上具有匹配 cellIndex
的 td
。如果有一个 input
元素,它的值将添加到 运行 总数中。否则,我们位于列中的最后一个单元格,它获取总值。
$('td:not(:first-child):not(:last-child)',
'#activity_table tr:eq(1)').each(function() {
var ci= this.cellIndex;
var total = 0;
$('td',
'#activity_table tr:gt(0)')
.filter(function() {
return this.cellIndex === ci;
})
.each(function() {
var inp= $('input', this);
if(inp.length) {
if(!$(this).closest('tr').is(':last-child')) {
total+= $('input', this).val()*1;
}
else {
$('input', this).val(total);
}
}
});
});
下面的代码获取每一行的总数。
它遍历每一行,总计其 input
个元素。
$('#activity_table tr:gt(0)').each(function() {
var total = 0;
$('td:not(:first-child):not(:last-child)',
this).each(function() {
total+= $('input', this).val()*1;
});
$('input', this).last().val(total);
});
请注意
on
is now preferred over bind
。如果您从总计列和总计行中删除 input
,您的事件处理程序将简化为:
$('#activity_table input').on('keyup change',...
我建议将所有样式移动到一个样式表中。我已经在 Fiddle:
中这样做了