코드스테이츠 프론트엔드 부트캠프-Section1 My Agora States 제작(2)

그래도 아무튼 개발자·2023년 3월 13일
0

Front_End

목록 보기
5/12
post-thumbnail

뒷배경을 추가하였고, 5개씩 나눠서 페이지가 나오게끔 구현에 성공하였다!!💪💪

console.log(agoraStatesDiscussions);

// convertToDiscussion은 아고라 스테이츠 데이터를 DOM으로 바꿔줍니다.
const convertToDiscussion = (obj) => {
  const li = document.createElement("li"); // li 요소 생성
  li.className = "discussion__container"; // 클래스 이름 지정

  const avatarWrapper = document.createElement("div");
  avatarWrapper.className = "discussion__avatar--wrapper";
  const discussionContent = document.createElement("div");
  discussionContent.className = "discussion__content";
  const discussionAnswered = document.createElement("div");
  discussionAnswered.className = "discussion__answered";

  // TODO: 객체 하나에 담긴 정보를 DOM에 적절히 넣어주세요.
  const avatarImg = document.createElement('img');
  avatarImg.src = obj.avatarUrl;
  avatarImg.alt = 'avatar of ' + obj.author;
  avatarWrapper.append(avatarImg);

  const contentTitle = document.createElement('h2'); 
  contentTitle.className = "discussion__title"; 
  discussionContent.append(contentTitle);

  const contentLink = document.createElement('a');
  contentLink.href = obj.url; 
  contentLink.textContent = obj.title; 
  contentTitle.append(contentLink); 

  const createdAtDate = new Date(obj.createdAt).toLocaleString();  //날짜 재정비(?)
  const contentInfo = document.createElement('div'); 
  contentInfo.className = "discussion__information"; 
  contentInfo.textContent = `${obj.author}/ ${createdAtDate}`
  discussionContent.append(contentInfo); 

  const contentAnswered = document.createElement('p');
  contentAnswered.className = "discussion__answered"; 

  if (obj.answer === null) {
    contentAnswered.textContent = '👨‍💻검토중'
  } else {
    contentAnswered.textContent = '❤️답변 완료'
  }
  discussionAnswered.append(contentAnswered); 

  li.append(avatarWrapper, discussionContent, discussionAnswered);
  return li;
};

// ul 요소에 agoraStatesDiscussions 배열의 모든 데이터를 화면에 렌더링합니다.
const ul = document.querySelector("ul.discussions__container");

const pages = document.querySelector(".page");
const showContent = 5; //한페이지 최대 글 개수
const showButton = 5; // 한페이지 페이지버튼 개수
let page = 1; // 첫페이지

const makeButton=(id) => {
  const button = document.createElement("button");
  button.classList.add("button");
  button.dataset.num = id;
  button.innerText = id;
  button.addEventListener("click", (e) => {
    //버튼 클릭시 class 조정
    //e.preventDefault();
    Array.prototype.forEach.call(pages.children, (button) => {
      if (button.dataset.num) button.classList.remove("active");
    });
    e.target.classList.add("active");
    renderContent(parseInt(e.target.dataset.num));
  });
  return button;
}
const renderContent = (page) => {
  // 목록 리스트 초기화
  while (ul.hasChildNodes()) {
    ul.removeChild(ul.lastChild);
  }

  // 5개의 글이 보이게
  for (
    let id = (page - 1) * showContent + 1;
    id <= page * showContent && id <= agoraStatesDiscussions.length;
    id++
  ) {
    ul.appendChild(convertToDiscussion(agoraStatesDiscussions[id - 1]));
  }
};

// 페이지이동
const goPrevPage = () => {
  page -= showButton;
  render1(page);
};

const goNextPage = () => {
  page += showButton;
  render1(page);
};
// 이전 다음 버튼 생성
const prev = document.createElement("button");
prev.classList.add("button", "prev");
prev.innerHTML = "<<";
prev.addEventListener("click", goPrevPage);

const next = document.createElement("button");
next.classList.add("button", "next");
next.innerHTML = ">>";
next.addEventListener("click", goNextPage);

const renderButton = (page) => {
  const maxPage = Math.ceil(agoraStatesDiscussions.length / showContent); //최대 페이지 수
  // 버튼 리스트 초기화
  while (pages.hasChildNodes()) {
    pages.removeChild(pages.lastChild);
  }
  // showButton 만큼 페이지버튼이 보이게
  for (let id = page; id < page + showButton && id <= maxPage; id++) {
    pages.appendChild(makeButton(id));
  }
  // active 옵션
  pages.children[0].classList.add("active");

  pages.prepend(prev);
  pages.append(next);

  // 이전, 다음 페이지 버튼이 필요한지 체크
  if (page - showButton < 1) pages.removeChild(prev);
  if (page + showButton > maxPage) pages.removeChild(next);
};

// 종합 랜더링
const render1 = (page) => {
  renderContent(page);
  renderButton(page);
};
render1(page);

//이제 입력이 가능하게 구현

const inputform = document.querySelector("form.form") //입력창 전체
const inputName = document.querySelector("#name") // 작성자
const inputTitle = document.querySelector("#title") // 제목
const inputStory = document.querySelector("#story") // 내용

inputform.addEventListener("submit", (event) => {
  event.preventDefault(); // 업로드를 하였을 때 새로고침되는 증상 방지
  const newDiscussions = { 
    id: 'id', 
    createdAt: new Date(),
    title: inputTitle.value,
    url: "http://www.naver.com",
    author: inputName.value,
    answer: null,
    bodyHTML: inputStory.value,
    avatarUrl: "unknown.png",
  };
  agoraStatesDiscussions.unshift(newDiscussions); 
  const discussion = convertToDiscussion(newDiscussions); 
  ul.prepend(discussion); 

  inputName.value = '';
  inputTitle.value = '';
  inputStory.value = '';

  render1(page);   //입력되고 나서 맨 끝 게시물은 다음 페이지로 넘어가게
});

주어진 index.html파일의 하단부에 <div class="page"></div>를 생성한 뒤, script.js파일에서 페이징을 할 수 있는 코드를 삽입하였다.

.page {
  justify-content: center;
  align-items: center;
  text-align: center;
}
.button {
  width:40px;
  height:50px;
  padding:5px;
  margin-right: 5px;
  margin-bottom:5px;
  font-size : 1.2rem;
  background-color: #ffd45c;
  border:none;
  border-radius:10px;
  color:white;
  box-shadow: 0 2px 2px 0 rgba(45, 54, 65, 0.75);
}
.button:hover {
  background-color:#ff9148;
}
.active {
  box-shadow:inset 0 4px 4px 0 rgba(45, 54, 65, 0.75);
  background-color: #ffcd45;
}

stylesheet에는 page클라스와 button클라스, hover와 active시의 효과를 나타내는 코드를 추가로 삽입하였다. button클라스는 DOM객체를 통해 script.js에서 생성을 하였고, 페이지가 나뉘었을 때 하단부에 뜨는 페이지 번호 버튼을 의미한다😊

이렇게 Section1의 사실상 마지막 프로젝트가 무난하게 마무리되었다.
+여기에 이제 로컬 스토리지 기능을 추가하여 새로고침을 하여도 저장했던 리스트가 사라지지 않는 기능을 추후에 추가할 예정이다💪
화이팅~

0개의 댓글