在动态表中汇总单元格

时间:2015-06-26 10:37:14

标签: javascript html-table add

我使用javascript设置了table。请注意,为了方便起见,我已将行数减少到只有一行。加载后,用户将在单元格中输入值。每行有3个单元格。在cell1或cell2中键入值时,应自动更新cell3。公式是

  

cell1(在列中:Score1)+ cell2(在列中:Score2)= cell3(列:   总)

然而这不起作用。我一直在cell3中获得NaN。任何人都可以帮我这个吗?

<!DOCTYPE html>
<html>
<head>
<title>MP</title>

<style type="text/css">
th {font-weight: bold; text-align: left; font-size: 14px; border: 1px; 
border-style: solid; margin: 0px; border-colapse: colapse; 
border-spacing: 0px;}
td {font-weight: Normal; font-size: 14px; border: 1px; border-style: solid; 
margin: 0px; border-colapse: colapse;}
.sn {text-align: right;}
.fin {text-align: right;}

</style>

</head>
<body>

<table id="pr">
<tbody>
<tr class="thd">
<th>Score A</th>
<th>Score B</th>
<th>Total</th>
</tr>

<tr>
<td><input type="text" class="fin" onkeyup="update();" /></td>
<td><input type="text" class="fin" onkeyup="update();" /></td>
<td input type="text" class="fin" name="totdeduction"></td>
</tr>

</tbody>
</table>
<br />
<br />

<script>
function update() {
var j = document.getElementById("pr").rows[1].cells[0].innerHTML;
var k = parseInt(j);
var l = document.getElementById("pr").rows[1].cells[1].innerHTML;
var m = parseInt(l);
var n = (k + m);

if (j ="") {k = 0;}
else if (l ="") {m = 0;}
document.getElementById("pr").rows[1].cells[2].innerHTML = n;
}
</script>
</body>
</html>

3 个答案:

答案 0 :(得分:1)

尝试在此处查看已修复的脚本:http://jsfiddle.net/9p19nngr/

Sheet2!A1

您假设Sheet2包含数字,但function update() { var j = document.getElementById("pr").rows[1].cells[0].getElementsByTagName("input")[0].value; var k = parseInt(j); if (isNaN(k)) {k=0} var l = document.getElementById("pr").rows[1].cells[1].getElementsByTagName("input")[0].value; var m = parseInt(l); if (isNaN(m)) {m=0} var n = (k + m); document.getElementById("pr").rows[1].cells[2].innerHTML = n; } 已分配给var j表格单元格包含的输入的DOM对象。相反,您应该分配输入值:j = document.getElementById("pr").rows[1].cells[0].innerHTML

答案 1 :(得分:1)

由于您已经有多行要执行相同的操作,因此您只需要与仅存在一行的情况略有不同。

最简单的方法可能是在触发keyup事件时简单地遍历表中的所有行,并更新每一行。显然,这是低效的 - 想象有1,000,000行!单次击键将导致重新计算所有1,000,000个击键。 :伊克:

另一种方法是使用一个函数来计算任何1行的结果。然后,您可以在键盘事件发生时调用此函数,但在这种情况下,您一次只能计算1行。这种方法显然优于前者,但它的代价是使用更先进的技术。也就是说,使用.addEventListener函数以及内联javascript的存储桶加载或对this关键字的理解。我个人的偏好是.addEventListener / this关键字组合。

首先,这里有一个替换你已经拥有的函数的函数 - 这将计算每行中第三个单元格的行数不限。

function update()
{
    var tableElem = document.getElementById('pr');
    var rowElems = tableElem.getElementsByTagName('tr');
    var i, nRows;

    nRows = rowElems.length;
    for (i=1; i<nRows; i++)     // start at 1, since the first row (index 0) contains the table's header
    {
        var curRowInputs = rowElems[i].getElementsByTagName('input');

        var firstVal = parseInt(curRowInputs[0].value);
        var secondVal = parseInt(curRowInputs[1].value);

        if (isNaN(firstVal) == true)
            firstVal = 0;

        if (isNaN(secondVal) == true)
            secondVal = 0;

        var result = firstVal + secondVal;
        curRowInputs[2].value = result;
    }
}

通过使用isNaN函数,我们确保输入的文本实际上是一个数字。如果不是,我们只需将输入视为0。

----------------------------------------------- -------------

现在进行第二种方法。我会为这个使用不同的html,因为我不需要(或想要!)任何内联javascript。我们还需要在使用之前初始化事件处理程序。

首先,表格的新html,与您的相同,但有一些例外情况。

  1. 现在有2行可以执行计算。
  2. 内联JS消失了。
  3. 为了简短起见,name属性已被删除 示例
  4. 第三个单元格中的输入应用了readonly属性。我们 不希望用户输入他们自己的结果 - 我们希望确保 它是计算好的。
  5. HTML

    <table id="pr">
        <tbody>
            <tr class="thd">
                <th>Score A</th>
                <th>Score B</th>
                <th>Total</th>
            </tr>
            <tr>
                <td><input type='text' class='fin'/></td>
                <td><input type='text' class='fin'/></td>
                <td><input type='text' class='fin' readonly /></td>
            </tr>
            <tr>
                <td><input type='text' class='fin'/></td>
                <td><input type='text' class='fin'/></td>
                <td><input type='text' class='fin' readonly /></td>
            </tr>
        </tbody>
    </table>
    

    接下来我们需要一个能为我们初始化所有事件处理程序的函数。

    function addTableEventHandlers()
    {
        var tableElem = document.getElementById('pr');
        var rowElems = tableElem.getElementsByTagName('tr');
        var i, nRows;
    
        nRows = rowElems.length;
        for (i=1; i<nRows; i++)     // start at 1, since the first row (index 0) contains the table's header
        {
            var curRowInputs = rowElems[i].getElementsByTagName('input');
            curRowInputs[0].addEventListener('keyup', myOnKeyupFunc, false);
            curRowInputs[1].addEventListener('keyup', myOnKeyupFunc, false);
        }
    }
    

    在此之后,我们需要一个能够执行实际计算的函数。

    function myOnKeyupFunc(evt)
    {
        var inputThatFiredTheEvent = this;
        var containingCell = inputThatFiredTheEvent.parentNode;
        var containingRow = containingCell.parentNode;
        var inputsInRow = containingRow.getElementsByTagName('input');
    
        var firstVal = parseInt(inputsInRow[0].value);
        var secondVal = parseInt(inputsInRow[1].value);
    
        if (isNaN(firstVal) == true)
            firstVal = 0;
    
        if (isNaN(secondVal) == true)
            secondVal = 0;
    
        var result = firstVal + secondVal;
        inputsInRow[2].value = result;  
    }
    

    最后,我们需要一种方法来调用初始化表的函数。在我们知道文档已经完成加载并且所有必需元素都存在并且已经被解析之后,这是一个好时机。一个很好的候选者是onload对象的window事件。

    这将导致在发生这种情况时调用函数:

    window.addEventListener('load', onDocLoaded, false);
    

    然后,在我们稍后定义的onDocLoaded函数中,我们只需调用addTableEventHandlers

    function onDocLoaded(evt)
    {
        addTableEventHandlers();
    }
    

    唷!希望你能和我在一起。将它们结合在一起,我们最终得到以下完整代码:

    <!DOCTYPE html>
    <html>
    <head>
    <title>MP</title>
    <script>
    window.addEventListener('load', onDocLoaded, false);
    
    function onDocLoaded(evt)
    {
        addTableEventHandlers();
    }
    
    function addTableEventHandlers()
    {
        var tableElem = document.getElementById('pr');
        var rowElems = tableElem.getElementsByTagName('tr');
        var i, nRows;
    
        nRows = rowElems.length;
        for (i=1; i<nRows; i++)     // start at 1, since the first row (index 0) contains the table's header
        {
            var curRowInputs = rowElems[i].getElementsByTagName('input');
            curRowInputs[0].addEventListener('keyup', myOnKeyupFunc, false);
            curRowInputs[1].addEventListener('keyup', myOnKeyupFunc, false);
        }
    }
    
    function myOnKeyupFunc(evt)
    {
        var inputThatFiredTheEvent = this;
        var containingCell = inputThatFiredTheEvent.parentNode;
        var containingRow = containingCell.parentNode;
        var inputsInRow = containingRow.getElementsByTagName('input');
    
        var firstVal = parseInt(inputsInRow[0].value);
        var secondVal = parseInt(inputsInRow[1].value);
    
        if (isNaN(firstVal) == true)
            firstVal = 0;
    
        if (isNaN(secondVal) == true)
            secondVal = 0;
    
        var result = firstVal + secondVal;
        inputsInRow[2].value = result;  
    }
    </script>
    
    <style type="text/css">
    th {font-weight: bold; text-align: left; font-size: 14px; border: 1px; 
    border-style: solid; margin: 0px; border-colapse: colapse; 
    border-spacing: 0px;}
    td {font-weight: Normal; font-size: 14px; border: 1px; border-style: solid; 
    margin: 0px; border-colapse: colapse;}
    .sn {text-align: right;}
    .fin {text-align: right;}
    </style>
    </head>
    <body>
    <table id="pr">
        <tbody>
            <tr class="thd">
                <th>Score A</th>
                <th>Score B</th>
                <th>Total</th>
            </tr>
            <tr>
                <td><input type='text' class='fin'/></td>
                <td><input type='text' class='fin'/></td>
                <td><input type='text' class='fin' readonly /></td>
            </tr>
            <tr>
                <td><input type='text' class='fin'/></td>
                <td><input type='text' class='fin'/></td>
                <td><input type='text' class='fin' readonly /></td>
            </tr>
        </tbody>
    </table>
    <br/>
    <br/>
    </body>
    </html>
    

答案 2 :(得分:0)

首先,您的订购有点错误。看看下面。 此外,我们现在需要确保这适用于任何行而不是将其绑定到具有indexes的特定行,因此我们将this关键字传递到函数中,以便我们可以引用父行,因此它是孩子无论哪一排。

所以你的HTML看起来像这样

<table id="pr">
    <tbody>
        <tr class="thd">
            <th>Score A</th>
            <th>Score B</th>
            <th>Total</th>
        </tr>
        <tr>
            <td>
                <input type="text" class="fin" onkeyup="update(this);" />
            </td>
            <td>
                <input type="text" class="fin" onkeyup="update(this);" />
            </td>
            <td>
                <input type="text" class="fin" name="totdeduction" />
            </td>
        </tr>
    </tbody>
</table>

你的JS是这样的:

function isNumber(n) {
    return !isNaN(parseFloat(n)) && isFinite(n);
}

function update(element) {
    rob = element;
    var j = element.parentElement.parentElement.children[0].children[0].value;
    var l = element.parentElement.parentElement.children[1].children[0].value;
    console.log(j, l);

    if (j === "" || !isNumber(j)) {
        j = 0;
    }
    if (l === "" || !isNumber(l)) {
        l = 0;
    }

    var k = parseInt(j, 10);
    var m = parseInt(l, 10);
    var n = (k + m);

    element.parentElement.parentElement.children[2].children[0].value = n;
}

其中包括确保文本不影响公式的功能。

演示:http://jsfiddle.net/47xs738w/