위코드 개강 전 마지막 미니 프로젝트인 'Expense Tracker'를 진행했다. 이번 프로젝트에서는 local storage를 활용해 작성한 데이터를 저장해 페이지를 reload하더라도 입력했던 데이터가 다시 표시 될 수 있도록 하는 것이 중점 이었다.
미니 프로젝트 게이트 페이지 바로가기>
let dataListArr =[]; // 입력한 입출금 내역을 할당할 빈 배열
// 1. 페이지 로드 시 로컬 스토리지에 저장 된 데이터 표시
reLoad(); // 페이지 로드 시 함수 실행
function reLoad() {
const savedData = JSON.parse(localStorage.getItem('data'));
// 로컬 스토리지에 저장된 입출금 내역 배열을 가져옴
if (savedData !== null) { // 로컬 스토리지에 내역이 있다면 기록 표시
savedData.forEach((data) => {
const newDiv = document.createElement('Div');
const delBtn = document.createElement('span');
const content = data.content;
const money = data.money;
const index = dataListArr.length; // 가져온 데이터를 표시 할 새 요소를 만듦
historyList.appendChild(newDiv);
newDiv.appendChild(delBtn);
newDiv.innerHTML = `${content} ₩ ${money} `;
delBtn.innerHTML = ` X`
newDiv.appendChild(delBtn); // 데이터 내용(내역, 금액)과 X 버튼 표시
delBtn.addEventListener('click',removeData); // X버튼 클릭 시 데이터를 지우는 함수 실행
newDiv.index = index; // 표시되는 목록(div)에 데이터 배열과 같은 인덱스 번호 할당
const newData = {index, content, money}
dataListArr.push(newData); // 로컬스토리지에서 가져온 데이터를 입출금내역 배열에 할당
})
}
}
// 2. '항목추가'클릭 시 내용, 금액 유효성 검사
addBtn.addEventListener('click', function() {
if(item.value !== '' && amount.value !== '') { // 내역과 금액 모두 빈 값이 아니라면
showList(); // 리스트 표시함수 실행
item.value = ''; // 내역 input 값 초기화
amount.value = ''; // 금액 input 값 초기화
} else if(item.value === '') {
alert ('내용을 입력해 주세요.');
} else {
alert ('금액을 입력해 주세요.');
}
})
// 3. 기록 누적하여 리스트 표시
function showList() {
const newDiv = document.createElement('div');
const delBtn = document.createElement('span');
const content = item.value;
const money = amount.value;
const index = dataListArr.length; // 입력한 데이터를 표시 할 새 요소를 만듦
historyList.appendChild(newDiv);
newDiv.appendChild(delBtn);
newDiv.innerHTML = `${content} ₩ ${money} `;
delBtn.innerHTML = ` X`
newDiv.appendChild(delBtn); // 데이터 내용(내역, 금액)과 X 버튼 표시
delBtn.addEventListener('click',removeData); // X버튼 클릭 시 데이터를 지우는 함수 실행
newDiv.index = index; // 표시되는 목록(div)에 데이터 배열과 같은 인덱스 번호 할당
const newData = {index, content, money}
dataListArr.push(newData); // 새로 입력한 데이터를 입출금내역 배열에 할당
saveData(); // 새로 입력한 데이터를 로컬스토리지에 저장하는 함수 실행
}
// 4. 입력한 데이터를 로컬스토리지에 저장
function saveData() {
localStorage.setItem('data', JSON.stringify(dataListArr));
// dataListArr 배열의 데이터를 문자열 형태로 저장
calcAmount(); // 현재 잔액, 수입, 지출 계산 함수 실행
}
// 5. 현재 잔액, 수입, 지출 계산 및 표시
function calcAmount() {
if(dataListArr !== null) {
const amounts = JSON.parse(localStorage.getItem('data'));
// 로컬스토리지에 저장되어 있는 데이터를 다시 배열 형태로 가져옴
let balance = 0;
let income = 0;
let expense = 0;
// 현재 잔액, 수입액, 지출액 0으로 초기화
amounts.forEach((data) => {
if (data.money > 0) {
income += parseInt(data.money);
} else {
expense += parseInt(data.money);
}
}); // 데이터의 수입액과 지출액 각각 누적하여 계산
balance = income + expense; // 계산한 수입액과 지출액을 더해 현재 잔액 계산
balance > 0 ? moneyBalance.innerHTML = `<font color='blue'> ₩ ${balance}</font>`
: moneyBalance.innerHTML = `<font color='red'> ₩ ${balance}</font>`
// 현재 잔액이 양수일 경우 파란색, 음수일 경우 빨간색으로 표시
incomeValue.innerHTML = `<font color='blue'> ₩ ${income}</font>`;
// 수입액 파란색으로 표시
expenseValue.innerHTML = `<font color='red'> ₩ ${expense * -1}</font>`;
// 지출액에 -1을 곱해 양수로 만들어 빨간색으로 표시
}
}
// 6. 데이터 삭제
function removeData(btn) {
const removeBtn = btn.target;
historyList.removeChild(removeBtn.parentNode);
// 클릭하여 접근한 버튼의 부모요소의 부모요소에 접근하여 버튼의 부모요소인 내역 삭제
let filtered = dataListArr.filter((data) => data.index !== removeBtn.parentNode.index);
dataListArr = filtered;
// 삭제한 기록의 인덱스와 배열 인덱스가 같은 경우를 제외하고
// 즉, 삭제하지 않은 데이터들만 추출해 새로운 배열만 만들어 데이터 배열에 새로 할당
saveData();
// 변경된 배열로 다시 로컬스토리지에 저장
}