기초공사 (html,css,javascript)

과제-board.html- 수정까지 되었지만 - 등록이 하나만 되는 코드 본문

academy/JavaScript

과제-board.html- 수정까지 되었지만 - 등록이 하나만 되는 코드

에스프레소라떼 2024. 5. 10. 13:26

html

C:\hee\.academy\lesson\javascript\day10\board-self

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script defer src="./js/board-self.js"></script>
    <style>
      .board-list {
        width: 920px;
        margin: 0 auto;
      }

      .board-list > article {
        background-color: #000;
        color: #fff;
        margin: 16px;
      }

      .board-list > article > div {
        border: 1px solid #fff;
      }
      /*h3,div*/
      .flex-center {
        display: flex;
        justify-content: center;
        align-items: center;
      }
      .board-detail p {
        border: 1px solid rgb(97, 67, 28);
      }
      .board-detail div {
        border: 1px solid rgb(43, 12, 182);
      }
    </style>
  </head>
  <body>
    <div class="wrapper">
      <!-- board form -->
      <form>
        <lable for="writeTitle">제목</lable>
        <input type="text" id="writeTitle" />
        <label>내용</label>
        <textarea class="content"></textarea>
        <button class="write-btn">등록하기</button>
      </form>
      <!-- <div>
        <p>제목: <input class="title" /></p>
        <label>내용</label>
        <textarea class="content"></textarea>
        <button class="write-btn">등록하기</button>
      </div> -->

      <!-- board list -->
      <div class="board-list">
        <article class="board-card">
          <h3 class="flex-center">
            exmple-title
            <button>삭제</button>
          </h3>
          <div class="flex-center">example-content</div>
        </article>
      </div>

      <!-- board detail -->
      <div class="board-detail">
        <button id="listmodify">수정</button>
        <p>example-title</p>
        <div>exmaple-content</div>
      </div>
    </div>
  </body>
</html>

 

js  전체코드

// *******************1. 고차함수로 생성하기***************************
// 고차함수로 join으로 문자열로 만들고 DOM요소로 변환하기 위한 innerHTML을 해준다해도, addEventListener는 사용하지를 못한다.
// 사용하기 위해서는 NodeList로 만들어줘야한다.

// board-list안에 2개의 배열로 만들어보자.
// array와 map이용해서 배열추가. 문자열로 만들기join("")

//***writetitle저장하기 클릭하면 list에 추가된다.*/
const $writeBtn = document.querySelector(".write-btn");
const $writetitle = document.querySelector("#writeTitle");
const $writeContent = document.querySelector(".content");

// writetitle.value = "dkdsl";

let $postH3 = document.createElement("h3"); // 쓰임이 많으니 전역변수로 뺴자.
$postH3.className = "flex-center";

let $postContent = document.createElement("div");
$postContent.className = "flex-center";

const generateMockPosts = (n) => Array(n).fill().map((_, i) => 
	({
      id: i + 1,
      // title: `title-${i + 1}`,
      title: $writetitle.value,
      // content: `cotent-${i + 1}`,
      content: $writeContent.value,
    }));

const mockPosts = generateMockPosts(1);
console.log(mockPosts);

console.log(mockPosts[0].title);

// board list에 만들어보기.
// boardlist 안에 들어가게 innerHTML을 입력해서 코드까지 붙인다.--XX아니다
// 위의 배열--문자열-- DOM요소로 만든다.
const $boardList = document.querySelector(".board-list");

const mockHTML = mockPosts
  .map((el) =>`<article class="board-card">
    <h3 class="flex-center">
     ${el.title}
      <button>삭제</button>
    </h3>
    <div class="flex-center">${el.content}</div>
  </article>`
  ).join("\n");

// console.log(mockHTML); // 배열로 나옴 -- join 하기 전
// 문자열로 바꾸자
console.log(mockHTML); // 문자열로 나옴 -- join 한 후.

// 이것을 HTML 안에 넣는다.
$boardList.innerHTML = mockHTML; // HTML에 나옴
//*********************************************************** */

//요소 만드는 함수 만들기
function createAdd() {
  for (const post of mockPosts) {
    const $postArticle = document.createElement("article");
    $postArticle.className = "board-card";
    console.log($postArticle); // 클래스 생김 확인

    //h3을 만들고 class를 flex-center 만들기- 전역변수로 뺌
    // 등록하기 제목란에 연결
    $postH3.textContent = $writetitle.value;
    console.log($postH3);

    // button만들기
    // $postH3의 자식으로 button 만들면 될거같은데

    // h3밑에 삭제버튼 연결하기
    const $postDeleteBtn = document.createElement("button");
    $postDeleteBtn.textContent = "삭제";

    $postH3.appendChild($postDeleteBtn); // h3과 삭제버튼 연결
    console.log($postH3);

    // content article 마지막 자식요소 div class=flex-center 전역변수로 올리고.
    // 등록하기 내용란에 연결
    $postContent.textContent = $writeContent.value;
    console.log($postContent);

    // article에 h3과 $postContent 연결
    $postArticle.append($postH3, $postContent);
    console.log($postArticle);

    // boardlist에 연결
    $boardList.appendChild($postArticle);
    console.log($boardList);

    $postDeleteBtn.addEventListener("click", (e) => {
      // const target = e.currentTarget;
      $postArticle.remove(); // 현재 게시물을 삭제
    });

    //수정하는 함수
    boardDetail($postArticle);

    //
    $writetitle.value = "";
    $writeContent.value = "";
  }
}

// 등록하는 버튼을 클릭하면
$writeBtn.addEventListener("click", (e) => {
  e.preventDefault();

  if ($writeContent.value == "") {
    alert("내용을 입력해주세요.");
    $writeContent.focus();
    return;
  }
  // 요소만드는 함수를 호출한다.
  createAdd();
});

// 수정목록 하는 구간.-- list에서 클릭시 해당 title 나오게 하기
//const $postArticle = document.createElement("article");
// board-detail위치에 나와야하므로.

// 수정할떄, list에서 나온 $writetitle.value 의 값을 가져와서 board-detail에 보여준다.
const $boardDetail = document.querySelector(".board-detail");
const $boardDetailTitle = document.querySelector(".board-detail > p");
const $boardDetailContent = document.querySelector(".board-detail > div");
const $modifyBtn = document.querySelector("#listmodify");

// $boardDetail.append($boardDetailTitle, $boardDetailContent);

// 1.기존 내용을 불러오기
// 2.불러온 내용으로 업데이트하고 저장하기

// 기존내용 불러오는거 어떻게 연결?
// -- $postArticle클릭하면 board-detail에 나오므로 그게 기존 값 인것이다.
// -- const $titleInput = $boardDetailTitle.textContent
// -- const $contentTextarea = $boardDetailContent.textContext

function boardDetail($postArticle) {
  $postArticle.addEventListener("click", (event) => {
    event.preventDefault();
    const target = event.currentTarget;
    console.log(target);
    console.log(target.children);

    // 수정목록에 나타내기
    for (const child of target.children) {
      if (child.matches("h3")) {
        $boardDetailTitle.innerText = child.childNodes[0].textContent;
        continue;
        console.log($boardDetailTitle.innerText);
      }
      if (child.matches("div")) {
        $boardDetailContent.innerText = child.innerText;
      }
    }
    console.log($boardDetailTitle); // $postArticle클릭하면 list에 나오므로 그게 기존 값인것이다.
    console.log($boardDetailContent);
  });

  // 수정버튼을 클릭했을때 이벤트
  //1.---> html에 p태그가 있찌만. 수정버튼 클릭시 요소를 만들어서 p태그안에 찍힌 title의 내용을 새로만든 input.value에 넣어놓으면 될거같다.
  // --> input.value를 어떻게 만드나 --> input의 요소를 만들어서 --> $listTitle.value = $boardDetailTitle.textContent
  // --> contentTextarea도 마찬가지로 --> $listTextarea.value = $boardDetailContent.textContent

  // 2. 적용된것을 list에 옮긴다.

  $modifyBtn.addEventListener("click", () => {
    // p태그와 div태그 받을 input요소를 만든다.
    // 수정버튼 클릭시 입력필드로 변환한다.
    const $listTitle = document.createElement("input");
    const $listTextarea = document.createElement("textarea");
    const $applyBtn = document.createElement("button");

    // $boardDetail 자식요소로 만들기?????
    // $boardDetail.append($boardDetailTitle, $boardDetailContent);

    /* 수정*/
    // 기존 제목과 내용을 불러온다 -input과 textarea의 값으로 설정

    $listTitle.value = $boardDetailTitle.innerText; // textContent 대신 innerText 사용-기존제목불러오기
    $listTextarea.value = $boardDetailContent.innerText; // textContent 대신 innerText 사용

    // 적용 버튼 설정
    $applyBtn.textContent = "적용";

    // 기존 내용을 입력 필드로 교체
    $boardDetail.replaceChild($listTitle, $boardDetailTitle); //---> 오류가 계쏙 남..그래서 등록하기가 한번밖에 안되나..
    $boardDetail.replaceChild($listTextarea, $boardDetailContent);
    $boardDetail.appendChild($applyBtn); // 적용 버튼 추가

    $boardDetail.append($listTitle, $listTextarea, $applyBtn);
    // 2. 적용버튼을 클릭시 새로운 변수에 저장
    $applyBtn.addEventListener("click", () => {
      // 입력 필드와 텍스트 영역에서 값을 가져옵니다.
      const $newTitle = $listTitle.value;
      const $newContent = $listTextarea.value;
      console.log($newTitle); // 적용됨.
      console.log($newContent);

      // 새로운 제목과 내용으로 업데이트
      $boardDetailTitle.innerText = $newTitle;
      $boardDetailContent.innerText = $newContent;

      // 입력 필드와 텍스트 영역을 다시 원래의 요소로 교체합니다.
      $boardDetail.replaceChild($boardDetailTitle, $listTitle);
      $boardDetail.replaceChild($boardDetailContent, $listTextarea);
      $applyBtn.remove(); // 적용 버튼 제거

      $postH3.innerText = $boardDetailTitle.innerText;
      $postContent.innerText = $boardDetailContent.innerText;

      //  $postContent.textContent = $writeContent.value;

      // list에 있는 $postH3에 수정된 것을 넣어야한다.
      // 이런부분이 어렵다. 다른함수에 지정된변수를 어떻게 쓰지?..함수를 또 만들어줘야하나 
      // -- 전역변수로 지정함.
    });

  });

}

q

 

// 분석

    // 수정목록에 나타내기
    for (const child of target.children) {
      if (child.matches("h3")) {
        $boardDetailTitle.innerText = child.childNodes[0].textContent;
        continue;
        console.log($boardDetailTitle.innerText);
      }
      if (child.matches("div")) {
        $boardDetailContent.innerText = child.innerText;
      }
    }

    console.log($boardDetailTitle); // $postArticle클릭하면 list에 나오므로 그게 기존 값인것이다.
    console.log($boardDetailContent);
  });

child 변수는 처리 중인 자식 요소를 가리키며,
childNodes는 해당 요소의 모든 자식 노드를 배열 형태로 반환한다.
childNodes[0]은 그 배열의 첫 번째 요소, 즉 현재 처리 중인 자식 요소의 첫번째 자식노드를 가리킨다.
이 경우, child가 h3요소라면 그  첫번째 자식 노드는 보통 텍스트 노드가 될 것이다.

 

// 분석2. 

--> 얘가 없으니까 수정한번 클릭하고 적용버튼이 안생긴다.

// 입력 필드와 텍스트 영역을 다시 원래의 요소로 교체합니다.
      $boardDetail.replaceChild($boardDetailTitle, $listTitle);
      $boardDetail.replaceChild($boardDetailContent, $listTextarea);
      $applyBtn.remove(); // 적용 버튼 제거

이 코드가 없으면 $boardDetailTitle이 생기고 그 밑에 input으로 만든 필드가 또 생긴다.

그래서 교체를 하는것이군!

'academy > JavaScript' 카테고리의 다른 글

과제-타이머만들기-setInterval  (0) 2024.05.12
과제중- replaceChild 예제  (0) 2024.05.10
복습-board.html - Array-fill-map  (0) 2024.05.06
예제 -DOM2 - 하나의 tr에 td 여러개(append)  (0) 2024.05.02
백틱과 ${ }  (0) 2024.04.30