부트캠프/TIL

코드스테이츠 프론트엔드 부트캠프 Day 18 - Coz' Mini Hackathon (3) 데이터 불러오기

하이고니 2023. 1. 9. 14:42

이제 form__container 내에 이름, 타이틀, 질문을 입력하고 submit 버튼을 눌렀을 때,

discussion__container가 페이지 상에 추가될 수 있도록 해보겠다. 

 

기본적으로 (1)에서 설명했던 요소 추가 방식과 비슷하지만,

 

1. submit 버튼을 눌렀을 때 동작한다는 점

2. agoraStatesDiscussions 에 요소가 추가된 후에 HTML에도 업데이트한다는 점

 

에서 차이가 있다.

 

논리 구조를 적어보겠다.

 

1. querySelector를 이용해 "#submitBtn" 을 불러와서 변수에 저장한다.

2. addEventListener 함수에다가 버튼이 클릭됐을 때 실행될 내용을 작성한다.

2-1. querySelector를 이용해 #name, #title, #story 의 value를 불러오고 각각을 변수에 저장한다.

2-2. newDiscussion 이라고 하는 새로운 객체를 만든다. 이 객체는 agoraStatesDiscussions에 들어있는 요소처럼 프로퍼티를 넣어줘야 한다. 그래야 똑바로 불러옴.

2-3. agoraStatesDiscussions에 newDiscussion을 unshift 해준다. (가장 최근 질문이 배열의 가장 처음으로 오도록 하는 구조인데, 반대를 원한다면 push 써도 된다.)

2-4. convertToDiscussion 함수의 내용과 동일하게 HTML 요소를 추가하고 append 한다.

2-5. ul에다가 만들어진 li를 prepend한다. (prepend 하는 이유: 제일 위에 보여야 하니까)

 

아래는 코드다.

 

const dataSubmit = document.querySelector('#submitBtn');

dataSubmit.addEventListener('click', () => {
  console.log("일단 드렁왔어요");
  const name = document.querySelector('#name').value;
  const title = document.querySelector('#title').value;
  const story = document.querySelector('#story').value;

  console.log(name, title, story);
  const newDiscussion = {
    title: title,
    author: name,
    createdAt: new Date().toISOString(),
    avatarUrl: 'https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fly6ZE%2FbtrVA0j9QpV%2FTVhGhX6yZbk04FlsfK1Zkk%2Fimg.jpg',
    url: '#',
    story: story
  };
  console.log(newDiscussion)
  agoraStatesDiscussions.push(newDiscussion);
  console.log(agoraStatesDiscussions)

  // Create the discussion element
  const li = document.createElement("li");
  li.className = "discussion__container";

  // Create the avatar wrapper and image elements
  const avatarWrapper = document.createElement("div");

  avatarWrapper.className = "discussion__avatar--wrapper";
  const avatarImg = document.createElement('img');
  avatarImg.src = newDiscussion.avatarUrl;
  avatarImg.alt = 'avatar of ' + newDiscussion.author;
  avatarWrapper.append(avatarImg);

  // Create the discussion content elements
  const discussionContent = document.createElement("div");
  discussionContent.className = "discussion__content";
  
  const discussionTitle = document.createElement("h2");
  discussionTitle.className = "discussion__title";
  discussionContent.append(discussionTitle);

  const titleLink = document.createElement("a");
  titleLink.setAttribute("href", newDiscussion.url); 
  titleLink.setAttribute("target", "_blank");
  titleLink.textContent = newDiscussion.title;
  discussionTitle.append(titleLink);

  const discussionInfo = document.createElement("div");
  discussionInfo.className = "discussion__information";
  discussionInfo.textContent = newDiscussion.author + " / " + newDiscussion.createdAt;
  discussionContent.append(discussionInfo);

  // Create the discussion answered element
  const discussionAnswered = document.createElement("div");

  discussionAnswered.className = "discussion__answered";
  const answeredP = document.createElement("p");
  answeredP.textContent = "☐";
  discussionAnswered.append(answeredP);

  // Append all the elements to the discussion element
  li.append(avatarWrapper);
  li.append(discussionContent);
  li.append(discussionAnswered);

  // Append the discussion element to the discussion list
  const ul = document.querySelector("ul.discussions__container");
  ul.prepend(li);

});

 

이제 form__container 에 원하는 내용을 입력하고 submit 하면 discussion이 페이지 내에 추가된다.

 

 

왠지 converToDiscussion 함수와 합칠 수 있을 것 같은데 내 머리로는 떠오르지가 않는다..

일단 완성하고 다시 고민해보겠다.

클린코드를 향한 길...

 

 

2023년 1월 10일 더 깔끔한 방식을 찾았다.

const form = document = document.querySelector("form.form");
const author = form.querySelector("div.form__input--name > input");
const title = form.querySelector("div.form__input--title > input");
const story = form.querySelector("div.form__textbox > textarea");

form.addEventListener("submit", (event) => {
  
  event.preventDefault();
  formContainer.classList.toggle('hidden');

  const newData = {
    title: title.value,
    author: author.value,
    createdAt: new Date().toISOString(),
    avatarUrl: 'https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fly6ZE%2FbtrVA0j9QpV%2FTVhGhX6yZbk04FlsfK1Zkk%2Fimg.jpg',
    url: '#',
    story: story.value
  }

  agoraStatesDiscussions.unshift(newData);

  while(ul.firstChild) {
    ul.removeChild(ul.firstChild);
  }
  render(ul);

  author.value = '';
  title.value = '';
  story.value = '';

})

아예 ul의 모든 요소를 다 지운 후에 새로 렌더링하는 것!

이렇게 하면 위에서 HTML요소를 하나하나 append 했던 것에 비하면 훨씬 코드를 경제적으로 작성할 수 있다.

그리고 기존에 submit을 button 타입으로 실행했던 것을(새로고침 방지)

event.preventDefault(); 한 줄 넣음으로써 해결할 수 있었다.

 

맨밑에 author.value, title.value, story.value에 빈 문자열을 할당함으로써

submit 이후 입력됐던 값들이 리셋되게 해줬다.