Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ 2주차 기본/심화(to be continue..) ] 가계부 💸 #5

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

nayujin-dev
Copy link
Member

@nayujin-dev nayujin-dev commented Oct 27, 2023

✨ 구현 기능 명세

  • 기본 과제 ✅
  1. 최초 데이터

    1. 상수로 INIT_BALANCE, HISTORY_LIST 데이터를 가집니다. (상수명은 자유)

      • INIT_BALANCE = 0
      • HISTORY_LIST : 입출금 내역 리스트 (4개)
    2. 최초 실행시 위 상수 데이터들 이용해 렌더링합니다. (즉, html에 직접 박아놓는 하드코딩 ❌) ✅

      → 나의 자산은 INIT_BALANCE로부터 4개의 입출금 내역 리스트를 반영하여 보여줍니다.

  2. 총수입 / 총지출

    1. 마찬가지로 최초에 HISTORY_LIST에 있는 수입 내역과 지출 내역을 계산해서 총수입, 총지출을 보여줍니다. ✅
  3. 수입/지출 필터링

    1. 수입, 지출 선택에 따라 내역 리스트가 필터링됩니다. ✅
  4. 리스트 삭제

    1. 각 리스트의 X 버튼을 누르면 해당 리스트가 삭제됩니다. ✅
    2. 리스트 삭제시 나의 자산에 반영됩니다. ✅
    3. 리스트 삭제시 총 수입 / 총 지출에 반영됩니다. ✅
  5. 리스트 추가

    하단 footer의 + 버튼을 누르면 리스트 추가 모달이 나타납니다.

    1. 수입 지출 버튼 ✅
      • default ⇒ 수입
      • 하나를 선택하면 다른 항목은 자동으로 선택이 풀립니다.
    2. 카테고리를 선택 ✅
      • 수입을 선택하면 수입 관련된 항목들이, 지출을 선택하면 종류에 지출 관련된 항목들이 나옵니다.
      • 카테고리는 수입, 지출 각각 2개 이상씩 있습니다.
    3. 금액내용 입력 input ✅
    4. 저장하기 버튼 ✅
      • 저장하기 버튼 클릭시 입력한 내용들로 이뤄진 리스트가 추가됩니다.
      • 이에 따라 나의 자산(잔액), 총수입, 총지출도 알맞게 변경됩니다.
      • 저장 성공시 alert 메시지를 띄웁니다.
      • 저장하기를 눌러도 모달이 닫히지 않습니다.
    5. 닫기 버튼 ✅
      • 클릭하면 모달이 사라집니다.

  • 심화과제 🔺
  1. ** 리스트 삭제 모달 ** ✅

    1. x 버튼 클릭시 삭제 모달이 나타납니다. ✅
     → `예` 클릭시 삭제를 진행합니다.
     
     → `취소` 클릭시 모달이 사라집니다.
    
  2. 리스트 추가

    1. 카테고리, 금액, 내용 중 입력하지 않은 항목이 있는데 저장하기를 누른 경우, alert를 띄워 막습니다. ✅
    2. 금액에 숫자가 아닌 문자를 입력시 alert를 띄워 막습니다. ✅
  3. 모달 백그라운드 & 애니메이션 (삭제, 추가)

    1. 백그라운드 : 모달 외부 부분을 어둡게 처리합니다. ✅
    2. 애니메이션 : + 클릭시 추가 모달이 아래에서 위로 올라옵니다.
  4. 카테고리 추가

    **localStorage**를 활용합니다.

    1. 상수로 최초 카테고리를 저장한 후, 렌더링시 추가 모달의 드롭다운 option들을 동적으로 렌더링합니다.
    2. 우측 하단 버튼을 누르면 <카테고리 관리> 페이지로 이동합니다.
    3. 수입 카테고리와 지출 카테고리에 현재 카테고리들이 있습니다.
    4. input 작성 후 Enter키를 누르면 카테고리가 추가됩니다.
    5. 다시 home으로 돌아가서 내역 추가 모달을 키면 option에 새로운 카테고리가 추가되어 있습니다.
    6. 새로고침을 해도 카테고리는 계속해서 유지됩니다.
  5. 금액

    1. 모든 금액에 세개 단위로 , 로 표시됩니다. (나의 자산, 총수입/지출, 내역 리스트, 리스트 추가 input)

💎 PR Point

  • 수입/지출 필터링
    • 아래 함수를 이용해서 필터링된 배열을 새로 만들고, 그 후 다시 해당 배열에 대해 html에 반영되게했습니다.
function doFilter(){
    detaillist.replaceChildren();
    if(clickedIncome && clickedOutcome)
        filteredList=history_list;
    else if(clickedIncome)
        filteredList=history_list.filter((each)=>each.amount>0);
    else if(clickedOutcome)
        filteredList=history_list.filter((each)=>each.amount<0);
    else
        filteredList=[];    

    makeHistoryList();
}
  • 리스트 추가
    • 다 아래처럼 뭔가 노가다 식으로 했는데 어떻게 다르게 하는지 잘 모르겠어요..
c_in.addEventListener("change",function(event){
    console.log(event.target.value);
    inputCategory=event.target.value;
})
c_out.addEventListener("change",function(event){
    inputCategory=event.target.value;
    console.log(event.target.value);
})
m_input.addEventListener("change",function(event){
    console.log(event.target.value);
    inputAmount=event.target.value;
})
m_content.addEventListener("change",function(event){
    console.log(event.target.value);
    inputContent=event.target.value;
})

  • 리스트 삭제, 삭제 확인 모달
    • 정말 삭제할건지에 대한 모달을 띄우고, 확인을 클릭하면 해당 리스트를 삭제합니다. 삭제한 리스트들을 다시 화면에 보여주는 과정이 제 생각에는 너무 투박한 코드인거같은데 다른분들은 어떻게 했는지 궁금해요! 전 삭제하면 다시 필터링 함수를 또 돌게끔해서 ,, 효율적이지 못한것같아요
function deleteHistory(event){
    closeModal.style.display="block";
    let yes = document.querySelector('#closeYes');
    let no = document.querySelector('#closeNo');
    
    yes.addEventListener("click",(e)=>{
        if(e.target.value){
            detaillist.removeChild(event.target.parentNode);
            const idx= history_list.findIndex(each => each.detail ===event.target.previousElementSibling.previousElementSibling.innerText)
            history_list.splice(idx,1);
            closeModal.style.display="none";
            doFilter()
            calculateHistory();
        }
    })

    no.addEventListener("click",(e)=>{
        e.target.value && (closeModal.style.display="none")
    })
    
}   

🥺 소요 시간, 어려웠던 점

  • 6h +2h(심화 보충)
  • 헝 이거 너무 오래걸렸어요 특히 필터링
  • 바닐라는 정말 어렵네용 ,,

🌈 구현 결과물

https://www.notion.so/dosopt/2-cdada8f4d1c944c09f54d3646b7108c8?pvs=4

@nayujin-dev nayujin-dev self-assigned this Oct 27, 2023
@nayujin-dev nayujin-dev changed the title [ 2주차 기본 ] 가계부 💸 [ 2주차 기본/심화(to be continue..) ] 가계부 💸 Nov 4, 2023
Copy link
Member

@SooY2 SooY2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

바닐라 자스..... 넘 어렵다.. 수고해써🫶🏻

inputAmount=event.target.value;
}
})
m_content.addEventListener("change",function(event){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

전역에 두지말고 함수로 묶으면 더 좋을거같오..!!

}

function submitList(){
if(inputCategory=="" || inputAmount==""|| inputContent==""){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

위에서 전역으로 eventlistener 선언했을 때 하나는 event가 발생하고 다른건 안발생하면 어떻게 되는거지? 하고 궁금했는데 여기서 처리를 해주는건가???

})
}

function deleteHistory(event){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

내가 삭제 모달 구현할 때 [fillter로 삭제][함수 모달띄우기]로 나눠서 구현하니까 이벤트리스너가 중복되어서 이전에 아니요 눌렀던 애들까지 다 삭제되는 이슈가 있어서.. 포기하고 코드리뷰 하러 왔는데
언니처럼 함수를 나누지 않고 한 함수안에서 구현하니까 이벤트리스너가 중복되지 않는구나!! 함수를 나누는 과정에서 뭔가 문제라는걸 알아냈어...뭐가 문제인진 더 생각해봐야겠당

const idx= history_list.findIndex(each => each.detail ===event.target.previousElementSibling.previousElementSibling.innerText)
history_list.splice(idx,1);
closeModal.style.display="none";
doFilter()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

나도 삭제하거나 추가할 때 계산하고 fillter해서 보여주는 함수 계속 중복해서 썼어!

Copy link

@Yeonseo-Jo Yeonseo-Jo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

바닐라 자스가 진짜 제일 어려운데... 너무 너무 수고해써!!!

추가적으로 함수 구현할 때 기능별로 독립적으로 구현하도록 만들기, 캡슐화 하기 등에 대해 더 고민해보면 좋을것 같습니댜!
다음주도 화이팅구🖤

Comment on lines +48 to +54
<section id="detaillist">
</section>
<section id="bottom">
<div>+</div>
</section>
<section class="modalWrap">
<div class="modalBody">

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

전체적으로 class명, id명을 혼합해서 사용하는것 같아요!
css 스타일링 할 때, js로 요소를 가져올 때 일정한 규칙 없이 클래스, id를 사용하면 개발 할 때도 어렵고 유지보수 및 가독성 측면에서도 단점이 될 수 있습니댜!
이전에 알려주었던 bem 방식 등을 참고해서,
id, class 중 어떤 것을 사용해야 할지 / 클래스명이나 id 명을 짓는 일정한 규칙 등에 대해 더 고민해보면 좋을것 같아!!

let clickedIncome=true, clickedOutcome=true;

const total=document.querySelector("#totalMoney");
let detaillist=document.querySelector("#detaillist");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

detaillist는 변경되지 않는 요소인것 같은데..!
const가 아닌 let으로 선언한 이유가 있을까용? 궁금합니다!!

Comment on lines +99 to +103
const eachlist = document.createElement('div');
const category = document.createElement('div');
const detail = document.createElement('div');
const amount = document.createElement('div');
const xbtn = document.createElement('div');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

js로 element를 create 할 때도! div보다 section, article, button 등의 시맨틱 태그들을 사용해주면 더 좋을것 같아용

eachlist.classList.add('eachlist');
detaillist.appendChild(eachlist);

each.amount<0 ? amount.classList.add('out') : amount.classList.add('in')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

삼항연산자 너무 적절히 잘 썼다 !!!🔥

}

function submitList(){
if(inputCategory=="" || inputAmount==""|| inputContent==""){

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

논리연산자로 조건문 구현한거 넘 완벽해..👍

Comment on lines +137 to +141
closeModal.style.display="none";
doFilter()
calculateHistory();
}
})

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리스트 삭제 시 필터링 함수가 실행되어야 하는 이유에 대해 궁금합니다!!
doFilter()를 여기서 실행하지 않으면 결과 값이 어떻게 되나요 ?!

Comment on lines +1 to +18
let history_list=[
{
category:"과외비",
detail:"10월 월급",
amount: 500000
},{
category:"식비",
detail:"서브웨이",
amount:-30000
},{
category:"용돈",
detail:"10월 용돈",
amount:100000
},{
category:"식비",
detail:"수육국밥",
amount:-10000
}];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

컨벤션을 어떻게 정하냐에 따라 달라지겠지만,
보통 상수값은 대문자로 표시해줘서 이 값은 상수값이다!라는 점을 한 눈에 알아볼수 있게 해주는 것이 좋아요!

Suggested change
let history_list=[
{
category:"과외비",
detail:"10월 월급",
amount: 500000
},{
category:"식비",
detail:"서브웨이",
amount:-30000
},{
category:"용돈",
detail:"10월 용돈",
amount:100000
},{
category:"식비",
detail:"수육국밥",
amount:-10000
}];
let HISTORY_LIST=[
{
category:"과외비",
detail:"10월 월급",
amount: 500000
},{
category:"식비",
detail:"서브웨이",
amount:-30000
},{
category:"용돈",
detail:"10월 용돈",
amount:100000
},{
category:"식비",
detail:"수육국밥",
amount:-10000
}];

Comment on lines +150 to +152
let init_balance=0;
let income_total=0;
let outcome_total=0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기도 magic number, 수치값 등을 나타내는 상수는 대문자로 바꿔주면 더 좋을것 같습니당!

Suggested change
let init_balance=0;
let income_total=0;
let outcome_total=0;
let INIT_BALANCE=0;
let INCOME_TOTAL=0;
let OUTCOME_TOTAL=0;

이런식으로 나타내면 단순 변수인지, 상수화해서 나타낸 값인지 한 눈에 비교하기 쉽습니댱

for(var i=0 ; i < radio.length ; i++){
radio[i].addEventListener('click', function () {
if(this.id === "add-in"){
console.log("in");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

console.log는 꼬옥 지워주기 !!

document.getElementById('add-category-in').style.display="block";
document.getElementById('add-category-out').style.display="none";
}else{
console.log("out");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요기도 ~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants