Project - 4

Project 4: Expense Tracker

Build a simple expense tracker that stores income and expenses, shows the current balance, and lists each transaction.

Your challenge: Add transactions to an array, update the balance, and display every transaction on the page.

✦ HTML + CSS + JS Editor
▶ Live Output

Store each transaction

Each transaction can be an object containing a description, amount, and type: { desc, amount, type }

Add it to the array with transactions.push().

Calculate the balance

Loop through the transactions. Add income amounts and subtract expense amounts.

Use toFixed(2) when displaying the balance so it always shows two decimal places.

Display the transactions

Clear the old list, then create a new <li> for each transaction.

Use textContent to place the transaction information inside the list item.

Try it: Add one income transaction and several expenses and watch the balance change.

Good JavaScript habit: Keep the transaction data in the array, then use separate functions to calculate and display it.

👀 Show Full Working Solution
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Expense Tracker</title>

  <style>
    body {
      background: #000;
      color: #8A8A8A;
      font-family: 'Courier New', monospace;
      padding: 40px;
      margin: 0;
      text-align: center;
    }

    .balance {
      font-size: 2rem;
      color: #fff;
      margin: 20px 0;
    }

    input,
    select,
    button {
      padding: 10px;
      margin: 5px;
      font-size: 15px;
    }

    button {
      cursor: pointer;
    }

    button:focus-visible,
    input:focus-visible,
    select:focus-visible {
      outline: 3px solid #fff;
      outline-offset: 3px;
    }

    ul {
      list-style: none;
      padding: 0;
      max-width: 500px;
      margin: 25px auto;
    }

    li {
      background: #111;
      color: #fff;
      padding: 12px;
      margin: 8px 0;
      border-radius: 6px;
      text-align: left;
    }
  </style>
</head>

<body>

  <h2>Expense Tracker</h2>

  <p class="balance">
    Balance: $<span id="balance">0.00</span>
  </p>

  <input
    id="desc"
    type="text"
    placeholder="Description"
  >

  <input
    id="amount"
    type="number"
    min="0"
    step="0.01"
    placeholder="Amount"
  >

  <select id="type">
    <option value="income">Income</option>
    <option value="expense">Expense</option>
  </select>

  <button id="addBtn" type="button">Add</button>

  <ul id="transactions"></ul>

  <script>
    let transactions = [];

    const descInput =
      document.getElementById("desc");

    const amountInput =
      document.getElementById("amount");

    const typeInput =
      document.getElementById("type");

    const addBtn =
      document.getElementById("addBtn");

    const balanceDisplay =
      document.getElementById("balance");

    const transactionList =
      document.getElementById("transactions");

    function updateBalance() {
      let balance = 0;

      transactions.forEach(function(transaction) {
        if (transaction.type === "income") {
          balance += transaction.amount;
        } else {
          balance -= transaction.amount;
        }
      });

      balanceDisplay.textContent =
        balance.toFixed(2);
    }

    function renderTransactions() {
      transactionList.textContent = "";

      transactions.forEach(function(transaction) {
        const li =
          document.createElement("li");

        const sign =
          transaction.type === "income"
            ? "+"
            : "-";

        li.textContent =
          transaction.desc +
          " - " +
          sign +
          "$" +
          transaction.amount.toFixed(2);

        transactionList.appendChild(li);
      });
    }

    addBtn.addEventListener("click", function() {
      const desc =
        descInput.value.trim();

      const amount =
        Number(amountInput.value);

      const type =
        typeInput.value;

      if (
        desc === "" ||
        !Number.isFinite(amount) ||
        amount <= 0
      ) {
        return;
      }

      transactions.push({
        desc: desc,
        amount: amount,
        type: type
      });

      renderTransactions();
      updateBalance();

      descInput.value = "";
      amountInput.value = "";
      descInput.focus();
    });
  </script>

</body>
</html>