动态创建的文本框中的值的总和

时间:2015-05-29 09:48:40

标签: javascript

我正在使用java脚本动态创建行中的文本框(它们的id有一个数字来表示行号,对于创建的每一行,该行号加1,以便区分输入)。并使用函数

计算要在静态文本框中显示的所有动态文本框值的总和
function updateAmount(row_num) 
     {
        TOTAL = document.getElementById('garage_total');
        var COST = document.getElementById('cost'+ row_num).value;

        var i;
        sum = 0;
        for(i=0;i <= row_num; i++)
        {
           sum = parseInt(sum) + parseInt(document.getElementById('cost'+ i).value); 
        }
        TOTAL.value = sum
     }

在文本框keyup事件上调用。我的问题是它只在错误计算的总文本框值中正确显示第一个文本框的值,并且当编辑现有输入的值时,它也会被错误计算

2 个答案:

答案 0 :(得分:1)

您无需提供行id。通过组合map,filter和reduce;您可以获取每个字段,对其进行验证,然后将其添加到总和中。

function updateAmount(row_num) {
  document.getElementById('garage_total').value = []
    .slice.call(
      document.getElementsByClassName('cost_field') // NodeList to Array
    )
    .map(function(costField) {
      return parseInt(costField.value, 10);         // String to Integer
    })
    .filter(function(value) {
      return !Number.isNaN(value);                  // Validate
    })
    .reduce(function(sum, value) {
      return sum + value;                           // Add to sum.
    }, 0);
}

updateAmount();
input { display: block; }
<input type="text" class="cost_field" value="5" />
<input type="text" class="cost_field" value="4" />
<input type="text" class="cost_field" value="3" />
<input type="text" class="cost_field" value="2" />
<input type="text" class="cost_field" value="1" />
<input type="text" id="garage_total" value="" />

你也可以用以下方法替换过滤器功能:

.filter(isFinite)

此功能的签名将作为过滤器中的回调。

在以下示例中:您可以为每个输入提供要查询的类名,或者您可以找到输入的父级,然后查找其子级。

const NUMBER_FIELDS = document.getElementById('number-fields');

// Main
addField(NUMBER_FIELDS);

function updateSum(childNodes, findNumFields) {
  var sum = calculateSum((function(children) {
    return findNumFields ? children.map(function(child) {
      return child.firstChild;
    }) : children;
  }([].slice.call(childNodes))));
  
  document.getElementById('sum-val').innerHTML = sum;
}

function calculateSum(items) {
  return items
    .map(function(item) {
      return parseNumber(item.value);
    })
    .filter(function(val) {
      return !Number.isNaN(val);
    })
    .reduce(function(sum, val) {
      return sum + val;
    }, 0);
}

function addField(targetEl) {
  var children = [];
  var wrapper = createElement('div', {
    className: 'number-field-wrapper'
  });
  children.push(addEvent(createElement('input', {
    type: 'number',
    class: 'num-val',
    value: ''
  }), 'change', function(e) {
    // FIND CHILDREN BY PARENT SELECTOR
    updateSum(findParent(e.target, '#number-fields').childNodes, true);
  }));
  children.push(createElement('input', {
    type: 'button',
    class: 'add-btn',
    value: '+'
  }, {
    'click': function(e) {
      addField(NUMBER_FIELDS);
    }
  }));

  if (targetEl.hasChildNodes()) {
    children.push(createElement('input', {
      type: 'button',
      class: 'add-btn',
      value: '-'
    }, {
      'click': function(e) {
        removeElement(e.target);
        // FIND CHILDREN BY CLASS NAME
        updateSum(document.getElementsByClassName('num-val'), false);
      }
    }));
  }
  return appendChildren(targetEl, appendChildren(wrapper, children));
}

function createElement(tagName, options, listeners) {
  var el = document.createElement(tagName), i;
  if (options) {
    var attrs = Object.keys(options);
    for (i = 0; i < attrs.length; i++) {
      el.setAttribute(attrs[i], options[attrs[i]]);
    }
  }
  if (listeners) {
    var events = Object.keys(listeners);
    for (i = 0; i < events.length; i++) {
      addEvent(el, events[i], listeners[events[i]]);
    }
  }
  return el;
}

function appendChildren(targetEl, childElements) {
  if (arguments.length == 2 && !Array.isArray(childElements)) {
    childElements = [childElements];
  } else if (arguments.length > 2) {
    childElements = [].slice.call(arguments, 1);
  }
  for (var i = 0; i < childElements.length; i++) {
    targetEl.appendChild(childElements[i]);
  }
  return targetEl;
}

function removeElement(targetEl) {
  targetEl.parentElement.parentElement.removeChild(targetEl.parentElement);
}

function findParent(el, selector) {
  while (el.parentNode) {
    if (el.id) {
      if ('#' + el.id === selector) {
        return el;
      }
    } else {
      if (el == el.ownerDocument.documentElement) {
        if (el.tagName === selector) {
          return el;
        }
      } else {
        for (var c = 1, e = el; e.previousElementSibling; e = e.previousElementSibling, c++);
        if (el.tagName + ":nth-child(" + c + ")" === el) {
          return el;
        }
      }
      el = el.parentNode;
    }
  }
  return null;
}

// Cross-Browser: Add event
function addEvent(el, evt, fn) {
  if (el.addEventListener) {
    el.addEventListener(evt, fn, false);
  } else {
    el.attachEvent("on" + evt, function() {
      // set the this pointer same as addEventListener when fn is called
      return (fn.call(el, window.event));
    });
  }
  return el;
}

function parseNumber(str, radix) {
  return str.indexOf('.') > -1 ? parseFloat(str) : parseInt(str, radix || 10);
}
<h2>Number Summation</h2>
<form id="summation-form">
  <div id="number-fields"></div>
  <div id="summation-field">
    <label>Total:</label>
    <span id="sum-val">0</span>
  </div>
</form>

答案 1 :(得分:0)

而不是keyup我会建议onchange事件。你遇到的问题是你不循环。

function updateAmount(row_num) {
    var cost, i, sum = 0;
    for (i = 0; i <= row_num; i++) {
        cost = document.getElementById('cost' + i).value;
        if (!isNaN(cost)) {
            sum += cost;
        }
    }
    document.getElementById('garage_total').value = sum;
}