显示动态输入的总和

时间:2018-08-13 23:11:22

标签: javascript html5 dom dynamic user-input

我正在尝试计算不同类别的动态div的总和,然后将该值放在div中。我不明白的是如何根据不同类别来确定总数。这是我在谈论https://www.screencast.com/t/js8LBNfXo9sa时的屏幕录像。这也是指向我的代码笔的链接,其中包含我的代码https://codepen.io/nfinsand/project/full/ZLNEon/

var addListItem = document.getElementById("add-more");

addListItem.addEventListener("click", function() {
  createNewItem();
});

//Display Month and Day
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth() + 1;

today = mm + "/" + dd;
document.getElementById("current-date").innerHTML = today;

//Creates new elements
function createNewItem() {
  var u = document.getElementById("full-item-list");
  var l = document.createElement("li");
  var elinput = document.createElement('input');
  var expenseName = document.createElement('input');
  var icon = document.createElement('img');
  var optionsArray = [{
      'itemText': 'Category',
      'itemDisabled': true,
      'itemSelected': true
    },
    'Auto & Transport',
    'Health & Fitness',
    'Home',
    'Personal Care',
    'Pets',
    'Shopping',
    'Entertainment',
    'Investments'
  ];

  var selectElem = document.createElement('select');
  selectElem.setAttribute('name', 'selectThis');
  // iterate through the array of options
  optionsArray.forEach(function(item) {
    var text = (typeof(item) === 'string') ? item : item.itemText;
    var option = document.createElement('option');
    var optionText = document.createTextNode(text);
    option.appendChild(optionText);
    if (typeof(item) === 'object') {
      // handle custom attributes
      Object.keys(item).forEach(function(key) {
        switch (key) {
          case 'itemDisabled':
            if (item[key]) {
              option.setAttribute('disabled', true);
            }
            break;
          case 'itemSelected':
            if (item[key]) {
              option.setAttribute('selected', true);
            }
            break;
          default:
            break;
        }
      });
    }
    selectElem.appendChild(option);
  });

  expenseName.setAttribute('type', 'text');
  expenseName.setAttribute('placeholder', 'Expense name');
  expenseName.setAttribute('class', 'expense-input-name')
  expenseName.setAttribute('name', 'totalExpense');

  elinput.setAttribute('type', 'number');
  elinput.setAttribute('class', 'li-input');
  elinput.setAttribute('placeholder', 'Enter amount');
  elinput.setAttribute('name', 'qty');

  l.setAttribute('class', 'list-item');
  l.setAttribute('name', 'li-name');
  icon.setAttribute('class', 'remove-icon');
  icon.setAttribute('src', 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/375261/System_Delete.ico');
  icon.setAttribute("id", "icon-id");
  icon.addEventListener('click', function(e) {
    thaticon(e);
  }, false);
  l.appendChild(selectElem);
  l.appendChild(expenseName);
  l.appendChild(elinput);
  l.appendChild(icon);
  u.appendChild(l);
}

//Deletes elements
function thaticon(e) {
  console.log("test");
  var el = e.target;
  var elListItem = el.parentNode;
  elFullList = elListItem.parentNode;
  elFullList.removeChild(elListItem);
}

//Calculates and displays results
function displayResult() {
  var arr = document.getElementsByName("qty");
  var wage = document.getElementById("inputWage").value;
  var jumboDiv = document.getElementById("jumbo-results").style.display = "block";
  var tot = 0;
  for (var i = 0; i < arr.length; i++) {
    if (parseFloat(arr[i].value)) tot += parseFloat(arr[i].value);
  }
  document.getElementById("result").innerHTML = "Total Expenses: $" + tot.toFixed(2);
  document.getElementById("left").innerHTML = "Left Over: $" + ((wage - tot).toFixed(2));
}

//Resets and clears entire entry
function resetForm() {
  var jumboDiv = document.getElementById("jumbo-results").style.display = "none";
  document.getElementById("full-item-list").innerHTML = "";
  document.getElementById("inputWage").value = "";
  document.getElementById("result").innerHTML = "";
  document.getElementById("left").innerHTML = "";
  document.getElementById("number-display").innerHTML = "";
}

//Displays the selected categories by user with the total sum for each one
function displayCategory() {

}
//Capture screen shots
/*function captureScreen() {
  html2canvas(document.querySelector("#capture")).then(canvas => {
      document.body.appendChild(canvas)
  });
}*/
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Expense Tracker</title>
  <link rel="stylesheet" href="css/style.css">
  <link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css'>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <link href="https://fonts.googleapis.com/css?family=Raleway:300" rel="stylesheet">
</head>

<body>
  <div id="capture" class="container-fluid">
    <div class="centerDiv">
      <p class="mainHeading">Expense Calculator</p>
      <p id="current-date"></p>
      <div class="jumbotron jumbo2">
        <h4>Categories</h4>
        <div id="category-display"><br>
          <div class="flex-container">
            <div id="color-1"></div>
            <div class="categoryItem">Auto & Transport</div>
            <div class="well">$0.00</div>
          </div>
          <div class="flex-container">
            <div id="color-2"></div>
            <div class="categoryItem">Health & Fitness</div>
            <div class="well">$0.00</div>
          </div>
          <div class="flex-container">
            <div id="color-3"></div>
            <div class="categoryItem">Home</div>
            <div class="well">$0.00</div>
          </div>
          <div class="flex-container">
            <div id="color-4"></div>
            <div class="categoryItem">Personal Care</div>
            <div class="well">$0.00</div>
          </div>
          <div class="flex-container">
            <div id="color-5"></div>
            <div class="categoryItem">Pets</div>
            <div class="well">$0.00</div>
          </div>
          <div class="flex-container">
            <div id="color-6"></div>
            <div class="categoryItem">Shopping</div>
            <div class="well">$0.00</div>
          </div>
          <div class="flex-container">
            <div id="color-7"></div>
            <div class="categoryItem">Entertainment</div>
            <div class="well">$0.00</div>
          </div>
          <div class="flex-container">
            <div id="color-8"></div>
            <div class="categoryItem">Investments</div>
            <div class="well">$0.00</div>
          </div>
        </div>
      </div>
      <div class="jumbotron">
        <label class="expenseLabel">Income:</label><br>
        <input id="inputWage" type="number" placeholder="Paycheck Amount"><br><br><br>
        <label>Expenses:</label>
        <ul id="full-item-list"></ul>
        <div class="listItem">
          <button id="add-more" class='btn btn-warning addExpenseBtn'>Add Expense</button>
          <button class="btn btn-warning submitExpenseBtn" type="button" onclick="displayResult(); displayCategory()">Submit</button>
          <button class="btn btn-warning resetExpenseBtn" type="button" onclick="resetForm()">Reset</button>
        </div>
      </div>
      <div id="jumbo-results" class="jumbotron">
        <p id="result"></p><br>
        <p id="left"></p>
      </div>
      <button class="btn btn-warning captureBtn" onclick="captureScreen()">Save Me</button>
    </div>
  </div>
  <footer>
    <small>&copy; Copyright 2018, Noble Finsand</small>
  </footer>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/js/bootstrap.min.js'></script>
  <script src="js/index.js"></script>
  <script src="js/html2canvas.js"></script>
  <script src="js/html2canvas.min.js"></script>
</body>

</html>

1 个答案:

答案 0 :(得分:0)

为了基于类别计算总数,您将需要创建一个对象列表,其中包含用户输入的所有数据。

从代码卫生的角度来看,创建列表并对其进行计算应该是单独的任务。

类似于您遍历用户在qty中输入的所有displayResult字段的方式,您可以构建费用清单,然后处理该最终结果。由于每个部分都是不同的字段并且不能保证具有有效的数据,因此处理每个部分的验证将具有挑战性。

像Angular这样的事情可以使这变得容易得多,因为将输入字段绑定到模型的困难部分已由您解决。

无论您如何创建按类别计算总数的列表,都很简单。

假设您创建这样的列表

var myExpenses = [
    {'category': 'Home', name: 'rent', 'amount': 500},
    {'category': 'Pets', name: 'cat food', 'amount': 45},
    {'category': 'Home', name: 'utilities', 'amount': 200},
    {'category': 'Pets', name: 'vet', 'amount': 42},
    {'category': 'Home', name: 'trash', 'amount': 50},
    {'category': 'Entertainment', name: 'date night', 'amount': 80}
];

然后,这些功能将能够返回所有费用的总和,并根据您的类别返回每个费用。

function totalExpenses (expenses) {
    return expenses.reduce(function (total, expense) {
        return total + expense.amount;
    }, 0);
}

function totalExpenseByCategory(categories, expenses) {
    var categorizedExpenses = [];
    categories.map(function (category) {
        var currentExpenses = expenses.filter(function (expense) {
            return expense.category === category;
        });
        var total = totalExpenses(currentExpenses);
        categorizedExpenses.push({'category': category, 'amount': total})
    });
    return categorizedExpenses;
}

这些函数在数组上使用Filter,Map和Reduce来计算总数。您可以在此处了解有关它们的更多信息。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce