코드스테이츠 프론트엔드 부트캠프 Day 18 - Coz' Mini Hackathon (3) 데이터 불러오기
이제 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 이후 입력됐던 값들이 리셋되게 해줬다.