Vanilla Javascript 在预算应用程序上添加 This.Title、值、费用表单金额

Vanilla Javascript Adding This.Title, Value, Amount for Expense Form on Budget App

提问人:Chelsea-exe 提问时间:1/28/2021 更新时间:1/28/2021 访问量:173

问:

您好,我正在按照 Coding Addict 的教程开发一个预算应用程序,我在代码的 submitExpenseForm 上遇到了问题。当用户提交多个“费用”时,它应该起作用,在第一个值“expense.title”和“expense.amount”被附加到 html 之后,应用程序费用形式的第 2+ 个条目一直显示为 undefined 和 NaN,过去两天它一直在破坏我的大脑重新观看视频, 研究并提出一些其他不起作用的代码。任何提示都会非常有帮助,非常感谢。

//JS tutorial from freecodecamp.org
// window.alert("javascript is loaded and ready!");
class UI {
    //setting variables
    constructor() {
        this.budgetFeedback = document.querySelector(".budget-feedback");
        this.expenseFeedback = document.querySelector(".expense-feedback");
        this.budgetForm = document.getElementById("budget-form");
        this.budgetInput = document.getElementById("budget-input");
        this.budgetAmount = document.getElementById("budget-amount");
        this.expenseAmount = document.getElementById("expense-amount");
        this.balance = document.getElementById("balance");
        this.balanceAmount = document.getElementById("balance-amount");
        this.expenseForm = document.getElementById("expense-form");
        this.expenseInput = document.getElementById("expense-input");
        this.amountInput = document.getElementById("amount-input");
        this.expenseList = document.getElementById("expense-list");
        this.itemList = [];
        this.itemID = 0;
    }
    //submit button budget, function will run the following code
    submitBudgetForm(){
        // console.log('hello from es6');
        const value = this.budgetInput.value;
        if(value === '' || value <0){
            this.budgetFeedback.classList.add('showItem');
            this.budgetFeedback.innerHTML = `<p>field can't be empty or negative.</p>`;
            console.log('error message will appear on DOM');
        }
        else{
            this.budgetAmount.textContent = value;
            this.budgetInput.value = "";
            this.showBalance();
        }
    }
    //show balance
    showBalance(){
        const expense = this.totalExpense();
        //parseInt would convert argument into a string (string of numbers with no [,]).
        const total = parseInt(this.budgetAmount.textContent) - expense;
        this.balanceAmount.textContent = total;
        if(total < 0){
            this.balance.classList.remove("showGreen", "showBlack");
            this.balance.classList.add("showRed")
        }
        else if(total > 0){
            this.balance.classList.remove("showRed", "showBlack");
            this.balance.classList.add("showGreen");
        }
        else if(total === 0){
            this.balance.classList.remove("showRed", "showGreen");
            this.balance.classList.add("showBlack");
        }
        // console.log(`hey I'm getting a hold of 'this' keyword`);
    }
    //submit expense form function
    submitExpenseForm(){
        const expenseValue = this.expenseInput.value;
        const amountValue = this.amountInput.value;
        if(expenseValue === '' || amountValue === '' || amountValue < 0)
        {
            this.expenseFeedback.classList.add('showItem');
            this.expenseFeedback.innerHTML = `<p>field can't be empty or negative.</p>`
        }
        else {
            let amount = parseInt(amountValue);
            this.expenseInput = "";
            this.amountInput = "";

            let expense = {
                id:this.itemID,
                title:expenseValue,
                amount:amount,

            }
            this.itemID++;
            this.itemList.push(expense);
            this.addExpense(expense);
            this.showBalance();
            //show balance
        }
    }

    //add expense

    addExpense(expense){
        const div = document.createElement('div');
        div.classList.add('expense');
        div.innerHTML = `<div class="expense-item d-flex justify-content-between align-items-baseline">
        <h6 class="expense-title mb-0 text-uppercase list-item">-${expense.title}</h6>
        <h5 class="expense-amount mb-0 list-item">${expense.amount}</h5>
        <div class="expense-icons list-item">
         <a href="#" class="edit-icon mx-2" data-id="${expense.id}">
          <i class="fas fa-edit"></i>
         </a>
         <a href="#" class="delete-icon" data-id="${expense.id}">
          <i class="fas fa-trash"></i>
         </a>
        </div>
       </div>
      </div>`;
      this.expenseList.appendChild(div);
    }
    //total expense
    totalExpense(){
        let total = 0;
        if(this.itemList.length > 0){
            console.log(this.itemList);
        }
        this.expenseAmount.textContent = total;

        return total;
    }
}

function eventListeners(){
    const budgetForm = document.getElementById('budget-form');
    const expenseForm = document.getElementById('expense-form');
    const expenseList = document.getElementById('expense-list');

    //new UI Class
    const ui = new UI()

    //budget form submit
    budgetForm.addEventListener('submit', function(event){
        event.preventDefault();
        ui.submitBudgetForm();

    });

    //expense form submit
    expenseForm.addEventListener('submit', function(event){
        event.preventDefault();
        ui.submitExpenseForm();

    })

    //expense click (expense value & title edit and trash)
    expenseList.addEventListener('click', function(){
        
    })

}

document.addEventListener('DOMContentLoaded', function(){
    eventListeners();
})
:root {
    --mainWhite: #f5f5f5f5;
    --mainDark: #333333;
    --mainGreen: #317b22;
    --mainRed: #b80c09;
    --mainBlue: #05668d;
    --mainYellow: yellow;
  }
  
  body {
    background: var(--mainWhite);
    color: var(--mainDark);
  }
  .budget-feedback,
  .expense-feedback {
    display: none;
  }
  
  .budget-form {
    border: 0.15rem solid var(--mainGreen);
    padding: 1rem;
    border-radius: 0.25rem;
  }
  .expense-form {
    border: 0.15rem solid var(--mainRed);
    padding: 1rem;
    border-radius: 0.25rem;
  }
  .budget-submit {
    background: transparent;
    border: 0.1rem solid var(--mainGreen);
    color: var(--mainGreen);
  }
  .expense-submit {
    background: transparent;
    border: 0.1rem solid var(--mainRed);
    color: var(--mainRed);
  }
  .expense-submit:hover {
    background: var(--mainRed);
    color: var(--mainWhite);
  }
  .budget-submit:hover {
    background: var(--mainGreen);
    color: var(--mainDark);
  }
  
  .budget-input {
    border: 0.05rem solid var(--mainGreen) !important;
    margin-bottom: 10px;
  }
  .expense-input {
    border: 0.05rem solid var(--mainRed) !important;
  }
  .expense-group {
      margin-bottom: 10px;
  }
  .expense-amount,
  .expense-title {
    color: var(--mainRed);
  }
  .edit-icon {
    color: var(--mainBlue);
    cursor: pointer;
    font-size: 1rem;
    text-decoration: none !important;
  }
  .delete-icon {
    color: var(--mainRed);
    cursor: pointer;
    font-size: 1rem;
    text-decoration: none !important;
  }
  .edit-icon:hover {
    color: var(--mainBlue);
  }
  .delete-icon:hover {
    color: var(--mainRed);
  }
  .showItem {
    display: block;
  }
  .info-title {
    font-size: 1.5rem;
  }
  .budget {
    font-size: 1.6rem;
    color: var(--mainGreen);
  }
  .expense {
    font-size: 1.6rem;
    color: var(--mainRed);
  }
  .balance {
    font-size: 1.6rem;
  }
  .budget-icon,
  .expense-icon,
  .balance-icon {
    font-size: 2.5rem;
    color: var(--mainBlue);
  }
  .showRed {
    color: var(--mainRed);
  }
  .showGreen {
    color: var(--mainGreen);
  }
  .showBlack {
    color: var(--mainDark);
  }
  @media screen and (min-width: 992px) {
    .budget {
      font-size: 2.6rem;
      color: var(--mainGreen);
    }
    .expense {
      font-size: 2.6rem;
      color: var(--mainRed);
    }
    .balance {
      font-size: 2.6rem;
    }
    .budget-icon,
    .expense-icon,
    .balance-icon {
      font-size: 3.5rem;
      color: var(--mainBlue);
    }
  }
  .list-item {
    flex: 0 0 33.33%;
    text-align: center;
  }
  .expense-item {
    height: 2rem;
  }
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<link rel="stylesheet" href="./fontawesome-free-5.15.2-web/css/all.css">
<link rel="stylesheet" href="./style.css">
<title>UPPERclassman</title>
</head>
<body>
    <div class="container-fluid">
        <div class="row">
            <!--title of app-->
            <div class="col-11 mx-auto p-3">
                <h3 class="UPPERclassman">UPPERclassman</h3> 
            </div>
            <div class="row">
                <div class="col-md-5 my-3">
                    <!--budget alert message-->
                    <div class="budget-feedback alert alert-danger text-capitalize">budget feedback</div>
                    <!---budget form-->
                    <form id="budget-form" class="budget-form">
                        <h5>Please enter your budget</h5>
                        <div class="form-group">
                            <input type="number" class="form-control budget-input" id="budget-input">
                        </div>
                        <!--submit button-->
                        <button type="submit" class="btn text-capitalize budget-submit" id="budget-submit">calculate</button>
                    </form>
                </div>
                <div class="col-md-7">
                    <div class="row my-3">
                        <div class="col-4 text-center mb-2">
                            <h6 class="info-title">Budget</h6>
                            <span class="budget-icon"><i class="fas fa-money-bill-wave fa-2x"></i></span>
                            <h4 class="mt-2 budget" id="budget"><span>$</span><span id="budget-amount">0</span></h4>
                        </div>
                        <div class="col-4 text-center">
                            <h6 class="info-title">Expense</h6>
                            <span class="expense-icon"><i class="far fa-credit-card fa-2x"></i></span>
                            <h4 class="mt-2 expense" id="expense"><span>$</span><span id="expense-amount">0</span></h4>
                        </div>
                        <div class="col-4 text-center">
                            <h6 class="info-title">Balance</h6>
                            <span class="balance-icon"><i class="fas fa-hand-holding-usd fa-2x"></i></span>
                            <h4 class="mt-2 balance" id="balance"><span>$</span><span id="balance-amount">0</span></h4>
                        </div>
                    </div>
                </div>
                <div class="row">
                    <div class="col-md-5 my-3">
                        <div class="expense-feedback alert alert-danger text-capitalize">expense feedback</div>
                        <form id="expense-form" class="expense-form">
                            <h5 class="text-capitalize">please enter your expense</h5>
                            <div class="form-group expense-group">
                                <input type="text" class="form-control expense-input" id="expense-input">
                            </div>
                            <div class="form-group expense-group">
                                <input type="number" class="form-control expense-input" id="amount-input">
                            </div>
                            <button type="submit" class="btn text-capitalize expense-submit" id="expense-submit">add expense</button>
                        </form>
                    </div>
                    <div class="col-md-7 my-3">
                        <div class="expense-list" id="expense-list">
                            <div class="expense-list__info d-flex justify-content-between text-capitalize">
                            <h5 class="list-item">expense title</h5>
                            <h5 class="list-item">expense value</h5>
                            <h5 class="list-item"></h5>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
      </div>
     <!-- jquery -->
 <!-- <script src="js/jquery-3.3.1.min.js"></script> -->
 <!-- bootstrap js -->
 <!-- <script src="js/bootstrap.bundle.min.js"></script> -->
 <!-- script js -->
 <script src="budget.js"></script>
</body>
</html>

JavaScript ecmascript-6 构造函数 这个 ES6 类

评论


答:

0赞 Neil W 1/28/2021 #1

这两条线:

        this.expenseInput = "";
        this.amountInput = "";

正在清除对控件的引用。

也许他们应该是:

        this.expenseInput.value = "";
        this.amountInput.value = "";