유데미에서 Brad Traversy의 20 Web Projects With Vanilla JavaScript
를 하나씩 직접 코딩해보면서 정리하기 위한 글이다.
데모 페이지
vanillawebprojects.com/projects/expense-tracker/
코드 링크
github.com/rshak8912/20-Web-Projects
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css">
<title>Expense Tracker</title>
</head>
<body>
<h2>Expense Tracker</h2>
<div class="container">
<h4>잔고</h4>
<h1 id="balance">$0.00</h1>
<div class="inc-exp-container">
<div>
<h4>수입</h4>
<p id="money-plus" class="money plus">+$0.00</p>
</div>
<div>
<h4>지출</h4>
<p id="money-minus" class="money minus">-$0.00</p>
</div>
</div>
<h3>내역</h3>
<ul id="list" class="list"></ul>
<h3>Add new transaction</h3>
<form action="" id="form">
<div class="form-control">
<label for="text">Text</label>
<input type="text" id="text" placeholder="Enter text...">
</div>
<div class="form-control">
<label for="amount">Amount <br>(negative - expense, positive - income)</label>
<input type="number" id="amount" placeholder="Enter amount...">
</div>
<button class="btn">Add transaction</button>
</form>
</div>
<script src="script.js"></script>
</body>
</html>
style.css
@import url('https://fonts.googleapis.com/css?family=Lato&display=swap');
:root {
--box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
}
* {
box-sizing: border-box;
}
body {
background-color: #f7f7f7;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
margin: 0;
font-family: 'Lato', sans-serif;
}
.container {
margin: 30px auto;
width: 350px;
}
h1 {
letter-spacing: 1px;
margin: 0;
}
h3 {
border-bottom: 1px solid #bbb;
padding-bottom: 10px;
margin: 40px 0 1px;
}
h4 {
margin: 0;
text-transform: uppercase;
}
.inc-exp-container {
background-color: #fff;
box-shadow: var(--box-shadow);
padding: 20px;
display: flex;
justify-content: space-between;
margin: 20px 0;
}
.inc-exp-container > div {
flex: 1;
text-align: center;
}
.inc-exp-container > div:first-of-type {
border-right: 1px solid #dedede;
}
.money {
font-size: 20px;
letter-spacing: 1px;
margin: 5px 0;
}
.money.plus {
color: #2ecc71;
}
.money.minus {
color:#c0392b;
}
label {
display: inline-block;
margin: 10px 0;
}
input[type='text'],
input[type='number'] {
border: 1px solid #dedede;
border-radius: 2px;
display: block;
font-size: 16px;
padding: 10px;
width: 100%;
}
.btn {
cursor: pointer;
background-color: #9c88ff;
box-shadow: var(--box-shadow);
color: #ffffff;
border: 0;
display: block;
font-size: 16px;
margin: 10px 0 30px;
padding: 10px;
width: 100%;
}
.btn:focus,
.delete-btn:focus {
outline: 0;
}
.list {
list-style-type: none;
padding: 0;
margin-bottom: 40px;
}
.list li {
background-color: #fff;
box-shadow: var(--box-shadow);
color: #333;
display: flex;
justify-content: space-between;
position: relative;
padding: 10px;
margin: 10px 0;
}
.list li.plus {
border-right: 5px solid #c0392b;
}
.list li.minus {
border-right: 5px solid #c0392b;
}
.delete-btn {
cursor: pointer;
background-color: #e74c3c;
border: 0;
color: #fff;
font-size: 20px;
line-height: 20px;
padding: 2px 5px;
position: absolute;
top:50%;
left: 0;
transform: translate(-100%, -50%);
opacity: 0;
transition: opacity 0.3s ease;
}
.list li:hover .delete-btn {
opacity: 1;
}
script.js
const balance = document.getElementById('balance');
const money_plus = document.getElementById('money-plus');
const money_minus = document.getElementById('money-minus');
const list = document.getElementById('list');
const form = document.getElementById('form');
const text = document.getElementById('text');
const amount = document.getElementById('amount');
/*
const dummyTransactions = [
{ id: 1, text: 'Flower', amount: -20 },
{ id: 2, text: 'Salary', amount: 300 },
{ id: 3, text: 'Book', amount: -10 },
{ id: 4, text: 'Camera', amount: 150 }
];
*/
const localStorageTransactions = JSON.parse(
localStorage.getItem('transactions')
);
let transactions = localStorage.getItem('transactions') !== null ? localStorageTransactions : [];
const addTransaction = (e) => {
e.preventDefault();
if (text.value.trim() === '' || amount.value.trim() === '') {
alert('Please add a text and amount');
} else {
const transaction = {
id: generateID(),
text: text.value,
amount: +amount.value
};
transactions.push(transaction);
addTransactionDOM(transaction);
updateValues();
updateLocalStorage();
text.value = '';
amount.value = '';
}
}
const generateID = () => Math.floor(Math.random() * 100000000);
const addTransactionDOM = (transaction) => {
const sign = transaction.amount < 0 ? '-' : '+';
const item = document.createElement('li');
item.classList.add(transaction.amount < 0 ? 'minus' : 'plus');
item.innerHTML = `
${transaction.text} <span>${sign}${Math.abs(
transaction.amount
)}</span> <button class="delete-btn" onclick="removeTransaction(${
transaction.id
})">x</button>
`;
list.appendChild(item);
}
// Update the balance
const updateValues = () => {
const amounts = transactions.map(transaction =>
transaction.amount);
const total = amounts.reduce((acc, item) => (acc += item), 0).toFixed(2);
const income = amounts
.filter(item => item > 0)
.reduce((acc, item) => (acc += item), 0)
.toFixed(2);
const expense = (
amounts.filter(item => item < 0).reduce((acc, item) => (acc += item), 0) *
-1
).toFixed(2);
balance.innerText = `$${total}`;
money_plus.innerText = `$${income}`;
money_minus.innerText = `$${expense}`;
}
const removeTransaction = (id) => {
transactions = transactions.filter(transaction => transaction.id !== id);
updateLocalStorage();
init();
}
const updateLocalStorage = () => localStorage.setItem('transactions', JSON.stringify(transactions));
const init = () => {
list.innerHTML = '';
transactions.forEach(addTransactionDOM);
updateValues();
}
init();
form.addEventListener('submit', addTransaction);
강의를 통해 배운 점(생각, 내용 정리)
- localstorage를 사용하여 브라우저 상에서의 데이터 보관 방법을 익힐 수 있었음
'HTML&CSS&Javascript' 카테고리의 다른 글
[Udemy]20 Web Projects With Vanilla JavaScript -Project#11 (0) | 2020.12.30 |
---|---|
[Udemy]20 Web Projects With Vanilla JavaScript -Project#10 (0) | 2020.12.30 |
[Udemy]20 Web Projects With Vanilla JavaScript -Project#8 (0) | 2020.12.13 |
[Udemy]20 Web Projects With Vanilla JavaScript -Project#7 (0) | 2020.12.11 |
[Udemy]20 Web Projects With Vanilla JavaScript -Project#6 (0) | 2020.12.11 |