영광의 시대!/2022 개발자의 품격 부트캠프 1기

[개발자의품격][부트캠프][1기][13차시] JavaScript 주요 포인트 #19 | DOM 패턴 - 모달과 고객정보 수정

DandyNow 2022. 2. 23. 00:09
728x90
반응형

JavaScript 주요 포인트 #19

DOM 패턴 - 모달과 고객정보 수정

Step 1

[그림 1] 고객정보 수정 모달창

 

 

<!-- dom_modal.html-->
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .normal-table {
        border: 1px solid black;
        border-collapse: collapse;
        width: 100%;
      }

      .normal-table th,
      .normal-table td {
        border: 1px solid black;
        padding: 5px 10px;
      }

      .normal-table thead tr {
        background-color: yellow;
      }
      
      .striped tbody tr:nth-child(odd) {
        background-color: grey;
      }

      .hover tbody tr:hover {
        background-color: yellow;
      }
    </style>
    <!-- 모달 스타일 연결 / openModal 함수 호출전에는 모달창이 화면에 보이지 않는다. -->
    <link rel="stylesheet" href="css/modal.css" />
  </head>
  <body>
    <select name="" id="gender">
      <option value="">전체</option>
      <option value="male">남자</option>
      <option value="female">여자</option>
    </select>
    <input
      type="search"
      name=""
      id="searchName"
      placeholder="Name"
      onkeyup="checkEnter(event);"
    />
    <button onclick="doSearch();">조회</button>
    <button onclick="goToCreate();">생성</button>
    <button onclick="doDelete();" id="btnDelete" disabled>삭제</button>
    <table class="normal-table striped">
      <thead>
        <tr>
          <th><input type="checkbox" id="chks" onchange="checkAll()" /></th>
          <th>Name</th>
          <th>Company</th>
          <th>Gender</th>
          <th>Email</th>
          <th>Phone</th>
          <th>Addres</th>
        </tr>
      </thead>
      <tbody id="tbBody"></tbody>
    </table>
    <!-- 고객정보 수정 모달 -->
    <!-- modal-mask는 모달창 바깥 어두운 영역 -->
    <div class="modal-mask">
      <div class="modal-wrapper">
        <!-- modal-container는 모달창 영역 -->
        <div class="modal-container" style="width: 600px">
          <div class="modal-header">
            <h3>고객정보 수정</h3>
          </div>
          <div class="modal-body">
            <div class="row">
              <div class="col-4">
                <label for="name">Name</label>
              </div>
              <div class="col-8">
                <input type="text" name="" id="name" class="form-control" />
                <input type="hidden" id="selectedId" value="" />
              </div>
              <div class="col-4">
                <label for="name">Gender</label>
              </div>
              <div class="col-8">
                <input
                  type="radio"
                  name="gender"
                  id="male"
                  value="male"
                  checked
                />
                <label for="male">남자</label>
                <input type="radio" name="gender" id="female" value="female" />
                <label for="female">여자</label>
              </div>
              <div class="col-4">
                <label for="company">Company</label>
              </div>
              <div class="col-8">
                <input type="text" name="" id="company" class="form-control" />
              </div>
              <div class="col-4">
                <label for="email">Email</label>
              </div>
              <div class="col-8">
                <input
                  type="email"
                  name=""
                  id="email"
                  class="form-control"
                  onblur="checkEmail();"
                />
                <div id="emailMsg" class="alert" style="display: none">
                  올바른 형식의 이메일을 입력하세요.
                </div>
              </div>
              <div class="col-4">
                <label for="phone">Phone</label>
              </div>
              <div class="col-8">
                <input
                  type="tel"
                  name=""
                  id="phone"
                  class="form-control"
                  placeholder="010-0000-0000"
                  onblur="checkPhone();"
                />
                <div id="phoneMsg" class="alert" style="display: none">
                  올바른 형식의 연락처를 입력하세요.
                </div>
              </div>
              <div class="col-4">
                <label for="address">Address</label>
              </div>
              <div class="col-8">
                <button onclick="openDaumAPI();">주소찾기</button>
                <input
                  type="text"
                  name=""
                  id="zonecode"
                  style="width: 80px"
                  readonly
                />
                <input
                  type="text"
                  name=""
                  id="address"
                  class="form-control"
                  readonly
                />
              </div>
            </div>
          </div>
          <div class="modal-footer">
            <button onclick="doSave();">저장</button>
            <button onclick="closeModal();">닫기</button>
          </div>
        </div>
      </div>
    </div>
    <script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
    <script>
      async function doSearch() {
        const gender = document.querySelector("#gender").value;
        const name = document.querySelector("#searchName").value;

        let resource = "http://localhost:3000/customers";
        if (gender === "") {
          if (name !== "") {
            resource = `http://localhost:3000/customers?name_like=${name}`;
          }
        } else {
          if (name === "") {
            resource = `http://localhost:3000/customers?gender=${gender}`;
          } else {
            resource = `http://localhost:3000/customers?gender=${gender}&name_like=${name}`;
          }
        }

        const res = await fetch(resource);
        const resJson = await res.json();
        console.log(resJson);
        renderTable(resJson);
      }

      function renderTable(data) {
        customerData = data;
        const h = [];
        for (const item of data) {
          h.push("<tr>");
          h.push(
            `<td><input type="checkbox" value="${item.id}" name="chk" onchange="isChecked();" /></td>`
          );
          h.push(
            `<td><a href="javascript:openModal('${item.id}');">${item.name}</a></td>` // 이름에 정보 수정용 모달창을 띄우기 위한 링크 달기
          );
          h.push(`<td>${item.company}</td>`);
          h.push(`<td>${item.gender}</td>`);
          h.push(`<td>${item.email}</td>`);
          h.push(`<td>${item.phone}</td>`);
          h.push(`<td>${item.address}</td>`);
          h.push("</tr>");
        }

        document.querySelector("#tbBody").innerHTML = h.join("");
      }

      // 이름의 링크 클릭시 호출되는 openModal 함수
      function openModal(id) {
        console.log(id);
        document.querySelector(".modal-mask").className =
          "modal-mask modal-show";
      }

      // 닫기 버튼 클릭시 모달창 닫기
      function closeModal() {
        selectedId = "";
        document.querySelector(".modal-show").className = "modal-mask";
      }

      async function doDelete() {
        const chks = document.querySelectorAll("[name=chk]:checked");

        if (chks.length > 0) {
          if (confirm("정말 삭제하시겠습니까?")) {
            for (const chk of chks) {
              await fetch(`http://localhost:3000/customers/${chks[0].value}`, {
                method: "DELETE",
              });
            }

            alert("데이터가 정상작으로 삭제 되었습니다.");
            await doSearch();
          }
        } else {
          alert("삭제할 아이템을 선택하세요.");
        }
      }

      function checkAll() {
        const checkValue = document.querySelector("#chks").checked;
        const chks = document.querySelectorAll("[name=chk]");
        for (const chk of chks) {
          chk.checked = checkValue;
        }

        isChecked();
      }

      function isChecked() {
        const chks = document.querySelectorAll("[name=chk]:checked");
        if (chks.length > 0) {
          document.querySelector("#btnDelete").disabled = false;
        } else {
          document.querySelector("#btnDelete").disabled = true;
        }
      }

      function goToCreate() {
        document.location.href = "dom_create.html";
      }

      function checkEnter(e) {
        // console.log(e);
        if (e.keyCode === 13) {
          doSearch();
        }
      }

      // 수정
      async function doSave() {
        const name = document.querySelector("#name").value.trim();
        const gender = document.querySelector("[name=gender]:checked").value;
        const company = document.querySelector("#company").value.trim();
        const email = document.querySelector("#email").value.trim();
        const phone = document.querySelector("#phone").value.trim();
        const address = document.querySelector("#address").value.trim();

        console.log(name);
        console.log(gender);
        console.log(company);
        console.log(email);
        console.log(phone);
        console.log(address);

        if (name === "") {
          return alert("Name을 입력하세요.");
        }

        if (company === "") {
          return alert("Company을 입력하세요.");
        }

        const regexpEmail = /^([a-z]+\d*)+(\.?[a-z]*)+@[a-z]+(\.[a-z]{2,3})+$/;
        if (!regexpEmail.test(email)) {
          return alert("올바른 형식의 Email을 입력하세요.");
        }

        const regexpPhone = /^010-\d{3,4}-\d{4}$/;
        if (!regexpPhone.test(phone)) {
          return alert("올바른 형식의 Phone을 입력하세요.");
        }

        if (address === "") {
          return alert("Address을 입력하세요.");
        }

        const selectedId = document.querySelector("#selectedId").value;

        if (confirm("정말 저장하시겠습니까?")) {
          const res = await fetch(
            `http://localhost:3000/customers/${selectedId}`,
            {
              method: "PUT", // 수정할때는 PUT
              body: JSON.stringify({
                name,
                gender,
                company,
                email,
                phone,
                address,
              }),
              headers: {
                "content-type": "application/json;charset=UTF-8",
              },
            }
          );

          if (res.status === 200) {
            closeModal();
            alert("정상적으로 저장되었습니다.");
          } else {
            alert("고객 정보를 저장하지 못했습니다. 다시 시도하세요.");
          }
        }
      }

      function checkEmail() {
        const email = document.querySelector("#email").value;
        if (email !== "") {
          const regexpEmail =
            /^([a-z]+\d*)+(\.?[a-z]*)+@[a-z]+(\.[a-z]{2,3})+$/;
          if (!regexpEmail.test(email)) {
            document.querySelector("#emailMsg").style.display = "block";
          } else {
            document.querySelector("#emailMsg").style.display = "none";
          }
        } else {
          document.querySelector("#emailMsg").style.display = "none";
        }
      }

      function checkPhone() {
        const phone = document.querySelector("#phone").value;
        if (phone !== "") {
          const regexpPhone = /^010-\d{3,4}-\d{4}$/;
          if (!regexpPhone.test(phone)) {
            document.querySelector("#phoneMsg").style.display = "block";
          } else {
            document.querySelector("#phoneMsg").style.display = "none";
          }
        } else {
          document.querySelector("#phoneMsg").style.display = "none";
        }
      }

      function openDaumAPI() {
        new daum.Postcode({
          oncomplete: function (data) {
            // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분입니다.
            // 예제를 참고하여 다양한 활용법을 확인해 보세요.
            console.log(data);
            document.querySelector("#address").value = data.address;
            document.querySelector("#zonecode").value = data.zonecode;
          },
        }).open();
      }

      function goToList() {
        document.location.href = "dom.html";
      }

      function doReset() {
        document.querySelector("#name").value = "";
        document.querySelector("#company").value = "";
        document.querySelector("#email").value = "";
        document.querySelector("#phone").value = "";
        document.querySelector("#address").value = "";
      }
    </script>
  </body>
</html>

 


 

Step 2

[그림 2] 모달에 표시된 수정 대상의 정보

 

<!-- dom_modal.html -->
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .normal-table {
        border: 1px solid black;
        border-collapse: collapse;
        width: 100%;
      }

      .normal-table th,
      .normal-table td {
        border: 1px solid black;
        padding: 5px 10px;
      }

      .normal-table thead tr {
        background-color: yellow;
      }
      .striped tbody tr:nth-child(odd) {
        background-color: grey;
      }

      .hover tbody tr:hover {
        background-color: yellow;
      }
    </style>
    <link rel="stylesheet" href="css/modal.css" />
  </head>
  <body>
    <select name="" id="gender">
      <option value="">전체</option>
      <option value="male">남자</option>
      <option value="female">여자</option>
    </select>
    <input
      type="search"
      name=""
      id="searchName"
      placeholder="Name"
      onkeyup="checkEnter(event);"
    />
    <button onclick="doSearch();">조회</button>
    <button onclick="goToCreate();">생성</button>
    <button onclick="doDelete();" id="btnDelete" disabled>삭제</button>
    <table class="normal-table striped">
      <thead>
        <tr>
          <th><input type="checkbox" id="chks" onchange="checkAll()" /></th>
          <th>Name</th>
          <th>Company</th>
          <th>Gender</th>
          <th>Email</th>
          <th>Phone</th>
          <th>Addres</th>
        </tr>
      </thead>
      <tbody id="tbBody"></tbody>
    </table>
    <div class="modal-mask">
      <div class="modal-wrapper">
        <div class="modal-container" style="width: 600px">
          <div class="modal-header">
            <h3>고객정보 수정</h3>
          </div>
          <div class="modal-body">
            <div class="row">
              <div class="col-4">
                <label for="name">Name</label>
              </div>
              <div class="col-8">
                <input type="text" name="" id="name" class="form-control" />
                <input type="hidden" id="selectedId" value="" />
              </div>
              <div class="col-4">
                <label for="name">Gender</label>
              </div>
              <div class="col-8">
                <input
                  type="radio"
                  name="gender"
                  id="male"
                  value="male"
                  checked
                />
                <label for="male">남자</label>
                <input type="radio" name="gender" id="female" value="female" />
                <label for="female">여자</label>
              </div>
              <div class="col-4">
                <label for="company">Company</label>
              </div>
              <div class="col-8">
                <input type="text" name="" id="company" class="form-control" />
              </div>
              <div class="col-4">
                <label for="email">Email</label>
              </div>
              <div class="col-8">
                <input
                  type="email"
                  name=""
                  id="email"
                  class="form-control"
                  onblur="checkEmail();"
                />
                <div id="emailMsg" class="alert" style="display: none">
                  올바른 형식의 이메일을 입력하세요.
                </div>
              </div>
              <div class="col-4">
                <label for="phone">Phone</label>
              </div>
              <div class="col-8">
                <input
                  type="tel"
                  name=""
                  id="phone"
                  class="form-control"
                  placeholder="010-0000-0000"
                  onblur="checkPhone();"
                />
                <div id="phoneMsg" class="alert" style="display: none">
                  올바른 형식의 연락처를 입력하세요.
                </div>
              </div>
              <div class="col-4">
                <label for="address">Address</label>
              </div>
              <div class="col-8">
                <button onclick="openDaumAPI();">주소찾기</button>
                <input
                  type="text"
                  name=""
                  id="zonecode"
                  style="width: 80px"
                  readonly
                />
                <input
                  type="text"
                  name=""
                  id="address"
                  class="form-control"
                  readonly
                />
              </div>
            </div>
          </div>
          <div class="modal-footer">
            <button onclick="doSave();">저장</button>
            <button onclick="closeModal();">닫기</button>
          </div>
        </div>
      </div>
    </div>
    <script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
    <script>
      async function doSearch() {
        const gender = document.querySelector("#gender").value;
        const name = document.querySelector("#searchName").value;

        let resource = "http://localhost:3000/customers";
        if (gender === "") {
          if (name !== "") {
            resource = `http://localhost:3000/customers?name_like=${name}`;
          }
        } else {
          if (name === "") {
            resource = `http://localhost:3000/customers?gender=${gender}`;
          } else {
            resource = `http://localhost:3000/customers?gender=${gender}&name_like=${name}`;
          }
        }

        const res = await fetch(resource);
        const resJson = await res.json();
        console.log(resJson);
        renderTable(resJson);
      }

      let customerData = []; // 모달에 기본 정보 표시를 배열

      function renderTable(data) {
        customerData = data;
        const h = [];
        for (const item of data) {
          h.push("<tr>");
          h.push(
            `<td><input type="checkbox" value="${item.id}" name="chk" onchange="isChecked();" /></td>`
          );
          h.push(
            `<td><a href="javascript:openModal('${item.id}');">${item.name}</a></td>`
          );
          h.push(`<td>${item.company}</td>`);
          h.push(`<td>${item.gender}</td>`);
          h.push(`<td>${item.email}</td>`);
          h.push(`<td>${item.phone}</td>`);
          h.push(`<td>${item.address}</td>`);
          h.push("</tr>");
        }

        document.querySelector("#tbBody").innerHTML = h.join("");
      }

      let selectedId = ""; // 수정할 id

      // 모달에 기본 정보 표시
      function openModal(id) {
        console.log(id);
        // selectedId = id;
        selectedId = id; // 수정할 id
        let customer = customerData.filter((c) => c.id === id)[0];
        document.querySelector("#name").value = customer.name;
        document.querySelector("#company").value = customer.company;
        document.querySelector("#" + customer.gender).checked = true;
        document.querySelector("#email").value = customer.email;
        document.querySelector("#phone").value = customer.phone;
        document.querySelector("#address").value = customer.address;

        document.querySelector(".modal-mask").className =
          "modal-mask modal-show";
      }

      function closeModal() {
        selectedId = "";
        document.querySelector(".modal-show").className = "modal-mask";
      }

      async function doDelete() {
        const chks = document.querySelectorAll("[name=chk]:checked");

        if (chks.length > 0) {
          if (confirm("정말 삭제하시겠습니까?")) {
            for (const chk of chks) {
              await fetch(`http://localhost:3000/customers/${chks[0].value}`, {
                method: "DELETE",
              });
            }

            alert("데이터가 정상작으로 삭제 되었습니다.");
            await doSearch();
          }
        } else {
          alert("삭제할 아이템을 선택하세요.");
        }
      }

      function checkAll() {
        const checkValue = document.querySelector("#chks").checked;
        const chks = document.querySelectorAll("[name=chk]");
        for (const chk of chks) {
          chk.checked = checkValue;
        }

        isChecked();
      }

      function isChecked() {
        const chks = document.querySelectorAll("[name=chk]:checked");
        if (chks.length > 0) {
          document.querySelector("#btnDelete").disabled = false;
        } else {
          document.querySelector("#btnDelete").disabled = true;
        }
      }

      function goToCreate() {
        document.location.href = "dom_create.html";
      }

      function checkEnter(e) {
        // console.log(e);
        if (e.keyCode === 13) {
          doSearch();
        }
      }

      async function doSave() {
        const name = document.querySelector("#name").value.trim();
        const gender = document.querySelector("[name=gender]:checked").value;
        const company = document.querySelector("#company").value.trim();
        const email = document.querySelector("#email").value.trim();
        const phone = document.querySelector("#phone").value.trim();
        const address = document.querySelector("#address").value.trim();

        console.log(name);
        console.log(gender);
        console.log(company);
        console.log(email);
        console.log(phone);
        console.log(address);

        if (name === "") {
          return alert("Name을 입력하세요.");
        }

        if (company === "") {
          return alert("Company을 입력하세요.");
        }

        const regexpEmail = /^([a-z]+\d*)+(\.?[a-z]*)+@[a-z]+(\.[a-z]{2,3})+$/;
        if (!regexpEmail.test(email)) {
          return alert("올바른 형식의 Email을 입력하세요.");
        }

        const regexpPhone = /^010-\d{3,4}-\d{4}$/;
        if (!regexpPhone.test(phone)) {
          return alert("올바른 형식의 Phone을 입력하세요.");
        }

        if (address === "") {
          return alert("Address을 입력하세요.");
        }

        const selectedId = document.querySelector("#selectedId").value;

        if (confirm("정말 저장하시겠습니까?")) {
          const res = await fetch(
            `http://localhost:3000/customers/${selectedId}`, // ID 값 찾아 수정
            {
              method: "PUT",
              body: JSON.stringify({
                name,
                gender,
                company,
                email,
                phone,
                address,
              }),
              headers: {
                "content-type": "application/json;charset=UTF-8",
              },
            }
          );

          if (res.status === 200) {
            // 수정은 200번
            closeModal(); // 저장했으면 모달창을 닫는다.
            alert("정상적으로 저장되었습니다.");
          } else {
            alert("고객 정보를 저장하지 못했습니다. 다시 시도하세요.");
          }
        }
      }

      function checkEmail() {
        const email = document.querySelector("#email").value;
        if (email !== "") {
          const regexpEmail =
            /^([a-z]+\d*)+(\.?[a-z]*)+@[a-z]+(\.[a-z]{2,3})+$/;
          if (!regexpEmail.test(email)) {
            document.querySelector("#emailMsg").style.display = "block";
          } else {
            document.querySelector("#emailMsg").style.display = "none";
          }
        } else {
          document.querySelector("#emailMsg").style.display = "none";
        }
      }

      function checkPhone() {
        const phone = document.querySelector("#phone").value;
        if (phone !== "") {
          const regexpPhone = /^010-\d{3,4}-\d{4}$/;
          if (!regexpPhone.test(phone)) {
            document.querySelector("#phoneMsg").style.display = "block";
          } else {
            document.querySelector("#phoneMsg").style.display = "none";
          }
        } else {
          document.querySelector("#phoneMsg").style.display = "none";
        }
      }

      function openDaumAPI() {
        new daum.Postcode({
          oncomplete: function (data) {
            // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분입니다.
            // 예제를 참고하여 다양한 활용법을 확인해 보세요.
            console.log(data);
            document.querySelector("#address").value = data.address;
            document.querySelector("#zonecode").value = data.zonecode;
          },
        }).open();
      }

      function goToList() {
        document.location.href = "dom.html";
      }

      function doReset() {
        document.querySelector("#name").value = "";
        document.querySelector("#company").value = "";
        document.querySelector("#email").value = "";
        document.querySelector("#phone").value = "";
        document.querySelector("#address").value = "";
      }
    </script>
  </body>
</html>

 


 

Step 3

input type="hidden" 으로 수정할 ID를 지정한다.

<!-- dom_modal.html -->
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .normal-table {
        border: 1px solid black;
        border-collapse: collapse;
        width: 100%;
      }

      .normal-table th,
      .normal-table td {
        border: 1px solid black;
        padding: 5px 10px;
      }

      .normal-table thead tr {
        background-color: yellow;
      }
      .striped tbody tr:nth-child(odd) {
        background-color: grey;
      }

      .hover tbody tr:hover {
        background-color: yellow;
      }
    </style>
    <link rel="stylesheet" href="css/modal.css" />
  </head>
  <body>
    <select name="" id="gender">
      <option value="">전체</option>
      <option value="male">남자</option>
      <option value="female">여자</option>
    </select>
    <input
      type="search"
      name=""
      id="searchName"
      placeholder="Name"
      onkeyup="checkEnter(event);"
    />
    <button onclick="doSearch();">조회</button>
    <button onclick="goToCreate();">생성</button>
    <button onclick="doDelete();" id="btnDelete" disabled>삭제</button>
    <table class="normal-table striped">
      <thead>
        <tr>
          <th><input type="checkbox" id="chks" onchange="checkAll()" /></th>
          <th>Name</th>
          <th>Company</th>
          <th>Gender</th>
          <th>Email</th>
          <th>Phone</th>
          <th>Addres</th>
        </tr>
      </thead>
      <tbody id="tbBody"></tbody>
    </table>
    <div class="modal-mask">
      <div class="modal-wrapper">
        <div class="modal-container" style="width: 600px">
          <div class="modal-header">
            <h3>고객정보 수정</h3>
          </div>
          <div class="modal-body">
            <div class="row">
              <div class="col-4">
                <label for="name">Name</label>
              </div>
              <div class="col-8">
                <input type="text" name="" id="name" class="form-control" />
                <!-- 사용자에게는 보이지 않는 숨겨진 입력 필드를 정의 -->
                <input type="hidden" id="selectedId" value="" />
              </div>
              <div class="col-4">
                <label for="name">Gender</label>
              </div>
              <div class="col-8">
                <input
                  type="radio"
                  name="gender"
                  id="male"
                  value="male"
                  checked
                />
                <label for="male">남자</label>
                <input type="radio" name="gender" id="female" value="female" />
                <label for="female">여자</label>
              </div>
              <div class="col-4">
                <label for="company">Company</label>
              </div>
              <div class="col-8">
                <input type="text" name="" id="company" class="form-control" />
              </div>
              <div class="col-4">
                <label for="email">Email</label>
              </div>
              <div class="col-8">
                <input
                  type="email"
                  name=""
                  id="email"
                  class="form-control"
                  onblur="checkEmail();"
                />
                <div id="emailMsg" class="alert" style="display: none">
                  올바른 형식의 이메일을 입력하세요.
                </div>
              </div>
              <div class="col-4">
                <label for="phone">Phone</label>
              </div>
              <div class="col-8">
                <input
                  type="tel"
                  name=""
                  id="phone"
                  class="form-control"
                  placeholder="010-0000-0000"
                  onblur="checkPhone();"
                />
                <div id="phoneMsg" class="alert" style="display: none">
                  올바른 형식의 연락처를 입력하세요.
                </div>
              </div>
              <div class="col-4">
                <label for="address">Address</label>
              </div>
              <div class="col-8">
                <button onclick="openDaumAPI();">주소찾기</button>
                <input
                  type="text"
                  name=""
                  id="zonecode"
                  style="width: 80px"
                  readonly
                />
                <input
                  type="text"
                  name=""
                  id="address"
                  class="form-control"
                  readonly
                />
              </div>
            </div>
          </div>
          <div class="modal-footer">
            <button onclick="doSave();">저장</button>
            <button onclick="closeModal();">닫기</button>
          </div>
        </div>
      </div>
    </div>
    <script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
    <script>
      async function doSearch() {
        const gender = document.querySelector("#gender").value;
        const name = document.querySelector("#searchName").value;

        let resource = "http://localhost:3000/customers";
        if (gender === "") {
          if (name !== "") {
            resource = `http://localhost:3000/customers?name_like=${name}`;
          }
        } else {
          if (name === "") {
            resource = `http://localhost:3000/customers?gender=${gender}`;
          } else {
            resource = `http://localhost:3000/customers?gender=${gender}&name_like=${name}`;
          }
        }

        const res = await fetch(resource);
        const resJson = await res.json();
        console.log(resJson);
        renderTable(resJson);
      }

      let customerData = [];

      function renderTable(data) {
        customerData = data;
        const h = [];
        for (const item of data) {
          h.push("<tr>");
          h.push(
            `<td><input type="checkbox" value="${item.id}" name="chk" onchange="isChecked();" /></td>`
          );
          h.push(
            `<td><a href="javascript:openModal('${item.id}');">${item.name}</a></td>`
          );
          h.push(`<td>${item.company}</td>`);
          h.push(`<td>${item.gender}</td>`);
          h.push(`<td>${item.email}</td>`);
          h.push(`<td>${item.phone}</td>`);
          h.push(`<td>${item.address}</td>`);
          h.push("</tr>");
        }

        document.querySelector("#tbBody").innerHTML = h.join("");
      }

      function openModal(id) {
        console.log(id);
        document.querySelector("#selectedId").value = id; // id 값을 input type hidden에 넣어 놓음
        let customer = customerData.filter((c) => c.id === id)[0];
        document.querySelector("#name").value = customer.name;
        document.querySelector("#company").value = customer.company;
        document.querySelector("#" + customer.gender).checked = true;
        document.querySelector("#email").value = customer.email;
        document.querySelector("#phone").value = customer.phone;
        document.querySelector("#address").value = customer.address;

        document.querySelector(".modal-mask").className =
          "modal-mask modal-show";
      }

      function closeModal() {
        selectedId = "";
        document.querySelector(".modal-show").className = "modal-mask";
      }

      async function doDelete() {
        const chks = document.querySelectorAll("[name=chk]:checked");

        if (chks.length > 0) {
          if (confirm("정말 삭제하시겠습니까?")) {
            for (const chk of chks) {
              await fetch(`http://localhost:3000/customers/${chks[0].value}`, {
                method: "DELETE",
              });
            }

            alert("데이터가 정상작으로 삭제 되었습니다.");
            await doSearch();
          }
        } else {
          alert("삭제할 아이템을 선택하세요.");
        }
      }

      function checkAll() {
        const checkValue = document.querySelector("#chks").checked;
        const chks = document.querySelectorAll("[name=chk]");
        for (const chk of chks) {
          chk.checked = checkValue;
        }

        isChecked();
      }

      function isChecked() {
        const chks = document.querySelectorAll("[name=chk]:checked");
        if (chks.length > 0) {
          document.querySelector("#btnDelete").disabled = false;
        } else {
          document.querySelector("#btnDelete").disabled = true;
        }
      }

      function goToCreate() {
        document.location.href = "dom_create.html";
      }

      function checkEnter(e) {
        // console.log(e);
        if (e.keyCode === 13) {
          doSearch();
        }
      }

      async function doSave() {
        const name = document.querySelector("#name").value.trim();
        const gender = document.querySelector("[name=gender]:checked").value;
        const company = document.querySelector("#company").value.trim();
        const email = document.querySelector("#email").value.trim();
        const phone = document.querySelector("#phone").value.trim();
        const address = document.querySelector("#address").value.trim();

        console.log(name);
        console.log(gender);
        console.log(company);
        console.log(email);
        console.log(phone);
        console.log(address);

        if (name === "") {
          return alert("Name을 입력하세요.");
        }

        if (company === "") {
          return alert("Company을 입력하세요.");
        }

        const regexpEmail = /^([a-z]+\d*)+(\.?[a-z]*)+@[a-z]+(\.[a-z]{2,3})+$/;
        if (!regexpEmail.test(email)) {
          return alert("올바른 형식의 Email을 입력하세요.");
        }

        const regexpPhone = /^010-\d{3,4}-\d{4}$/;
        if (!regexpPhone.test(phone)) {
          return alert("올바른 형식의 Phone을 입력하세요.");
        }

        if (address === "") {
          return alert("Address을 입력하세요.");
        }

        const selectedId = document.querySelector("#selectedId").value; // 수정할 #selectedId를 selectedID에 넣음. input type hidden은 수정할 Id를 지정하기 위해 사용하는 것이다.

        if (confirm("정말 저장하시겠습니까?")) {
          const res = await fetch(
            `http://localhost:3000/customers/${selectedId}`,
            {
              method: "PUT",
              body: JSON.stringify({
                name,
                gender,
                company,
                email,
                phone,
                address,
              }),
              headers: {
                "content-type": "application/json;charset=UTF-8",
              },
            }
          );

          if (res.status === 200) {
            closeModal();
            alert("정상적으로 저장되었습니다.");
          } else {
            alert("고객 정보를 저장하지 못했습니다. 다시 시도하세요.");
          }
        }
      }

      function checkEmail() {
        const email = document.querySelector("#email").value;
        if (email !== "") {
          const regexpEmail =
            /^([a-z]+\d*)+(\.?[a-z]*)+@[a-z]+(\.[a-z]{2,3})+$/;
          if (!regexpEmail.test(email)) {
            document.querySelector("#emailMsg").style.display = "block";
          } else {
            document.querySelector("#emailMsg").style.display = "none";
          }
        } else {
          document.querySelector("#emailMsg").style.display = "none";
        }
      }

      function checkPhone() {
        const phone = document.querySelector("#phone").value;
        if (phone !== "") {
          const regexpPhone = /^010-\d{3,4}-\d{4}$/;
          if (!regexpPhone.test(phone)) {
            document.querySelector("#phoneMsg").style.display = "block";
          } else {
            document.querySelector("#phoneMsg").style.display = "none";
          }
        } else {
          document.querySelector("#phoneMsg").style.display = "none";
        }
      }

      function openDaumAPI() {
        new daum.Postcode({
          oncomplete: function (data) {
            // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분입니다.
            // 예제를 참고하여 다양한 활용법을 확인해 보세요.
            console.log(data);
            document.querySelector("#address").value = data.address;
            document.querySelector("#zonecode").value = data.zonecode;
          },
        }).open();
      }

      function goToList() {
        document.location.href = "dom.html";
      }

      function doReset() {
        document.querySelector("#name").value = "";
        document.querySelector("#company").value = "";
        document.querySelector("#email").value = "";
        document.querySelector("#phone").value = "";
        document.querySelector("#address").value = "";
      }
    </script>
  </body>
</html>

 

728x90
반응형