Dandy Now!
  • [개발자의품격][부트캠프][1기][12차시] JavaScript 주요 포인트 #17 | DOM 패턴 - 생성, 우편번호 서비스 API 적용
    2022년 02월 21일 21시 12분 03초에 업로드 된 글입니다.
    작성자: DandyNow
    728x90
    반응형

    JavaScript 주요 포인트 #17

    생성

    생성 1

    값을 입력받는다.

    [그림 1] 최초

     

    <!-- dom_create.html -->
    <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>
        * {
          box-sizing: border-box;
        }
    
        .row {
          display: flex;
          flex-wrap: wrap;
        }
    
        .col-4 {
          flex: 33.3333%;
          padding: 5px;
        }
    
        .col-8 {
          flex: 66.6666%;
          padding: 5px;
        }
    
        input.form-control {
          width: 100%;
          padding: 5px 10px;
        }
    
        .text-center {
          text-align: center;
        }
    
        .alert {
          color: red;
        }
    
        /* 반응형 - 700px 이하이면 컴럼 요소 줄 바꿈 */
        @media screen and (max-width: 700px) {
          .row {
            flex-direction: column;
          }
        }
      </style>
    </head>
    <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" />
        </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" />
        </div>
        <div class="col-4">
          <label for="phone">Phone</label>
        </div>
        <div class="col-8">
          <input type="tel" name="" id="phone" class="form-control" />
        </div>
        <div class="col-4">
          <label for="address">Address</label>
        </div>
        <div class="col-8">
          <input type="tel" name="" id="address" class="form-control" />
        </div>
      </div>
      <div class="text-center">
        <button onclick="doCreate();">저장</button>
      </div>
      <script>
        function doCreate() {
          const name = document.querySelector("#name").value;
          const gender = document.querySelector("[name=gender]:checked").value;
          const company = document.querySelector("#company").value;
          const email = document.querySelector("#email").value;
          const phone = document.querySelector("#phone").value;
          const address = document.querySelector("#address").value;
    
          console.log(name);
          console.log(gender);
          console.log(company);
          console.log(email);
          console.log(phone);
          console.log(address);
        }
      </script>
    </body>

     


     

    생성 2

    입력된 값을 서버로 보낸다.

    <!-- dom_create.html -->
    <script>
      // 데이터 저장하기 위해 async...await 추가
      async function doCreate() {
        const name = document.querySelector("#name").value;
        const gender = document.querySelector("[name=gender]:checked").value;
        const company = document.querySelector("#company").value;
        const email = document.querySelector("#email").value;
        const phone = document.querySelector("#phone").value;
        const address = document.querySelector("#address").value;
    
        console.log(name);
        console.log(gender);
        console.log(company);
        console.log(email);
        console.log(phone);
        console.log(address);
    
        // 필수 입력 처리
        if (name === "") {
          return alert("Name을 입력하세요."); // return하는 이유는 다음 코드가 실행되지 못하게 하기 위함
        }
    
        if (company === "") {
          return alert("Company을 입력하세요.");
        }
    
        if (email === "") {
          return alert("Email을 입력하세요.");
        }
    
        if (phone === "") {
          return alert("Phone을 입력하세요.");
        }
    
        if (address === "") {
          return alert("Address을 입력하세요.");
        }
    
        if (confirm("정말 저장하시겠습니까?")) {
          const res = await fetch("http://localhost:3000/customers", {
            method: "POST",
            body: JSON.stringify({
              // name: name,
              // gender: gender,
              // company: company,
              // email: email,
              // phone: phone,
              // address: address,
    
              // 키명과 변수명이 같으면 변수명을 생략할 수 있다.
              name,
              gender,
              company,
              email,
              phone,
              address,
            }),
            headers: {
              "content-type": "application/json;charset=UTF-8",
            },
          });
        }
      }
    </script>

     


     

    생성 3

    입력 형식을 지정한다.

    [그림 2] 지정된 입력 형식과 맞지 않을 경우

     

    <!-- dom_create.html -->
    <script>
      async function doCreate() {
        const name = document.querySelector("#name").value;
        const gender = document.querySelector("[name=gender]:checked").value;
        const company = document.querySelector("#company").value;
        const email = document.querySelector("#email").value;
        const phone = document.querySelector("#phone").value;
        const address = document.querySelector("#address").value;
    
        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을 입력하세요.");
        }
    
        // 정규식으로 Email 입력 형식 지정
        const regexpEmail = /^([a-z]+\d*)+(\.?[a-z]*)+@[a-z]+(\.[a-z]{2,3})+$/;
        if (!regexpEmail.test(email)) {
          return alert("올바른 형식의 Email을 입력하세요.");
        }
    
        // 정규식으로 phone 입력 형식 지정
        const regexpPhone = /^010-\d{3,4}-\d{4}$/;
        if (!regexpPhone.test(phone)) {
          return alert("올바른 형식의 Phone을 입력하세요.");
        }
    
        if (address === "") {
          return alert("Address을 입력하세요.");
        }
    
        if (confirm("정말 저장하시겠습니까?")) {
          const res = await fetch("http://localhost:3000/customers", {
            method: "POST",
            body: JSON.stringify({
              name,
              gender,
              company,
              email,
              phone,
              address,
            }),
            headers: {
              "content-type": "application/json;charset=UTF-8",
            },
          });
        }
      }
    </script>

     


     

    생성 4

    정규식 등을 이용해 Email, Phone 입력 형식을 체크한다.

    [그림 3] 입력 형식 체크

     

    <!-- dom_create.html -->
    <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" />
        </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>
        <!-- Email 입력 받을때 입력 형식 체크 -->
        <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>
        <!-- Phone 입력 받을때 입력 형식 체크 -->
        <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">
          <input type="tel" name="" id="address" class="form-control" />
        </div>
      </div>
      <div class="text-center">
        <button onclick="doCreate();">저장</button>
      </div>
      <script>
        async function doCreate() {
          const name = document.querySelector("#name").value.trim(); // 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을 입력하세요.");
          }
    
          if (confirm("정말 저장하시겠습니까?")) {
            const res = await fetch("http://localhost:3000/customers", {
              method: "POST",
              body: JSON.stringify({
                name,
                gender,
                company,
                email,
                phone,
                address,
              }),
              headers: {
                "content-type": "application/json;charset=UTF-8",
              },
            });
          }
        }
        // Email 입력 받을때 입력 형식 체크
        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";
          }
        }
        // Phone 입력 받을때 입력 형식 체크
        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";
          }
        }
      </script>
    </body>

     


     

    생성 5

    주소 찾기 기능을 추가했다. 다음 우편번호 서비스 API(https://postcode.map.daum.net/guide)를 사용한다. 그 밖의 기능들을 추가했고 주석을 달았다.

    [그림 4] 최종

     

    <!-- dom_create.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>
          * {
            box-sizing: border-box;
          }
    
          .row {
            display: flex;
            flex-wrap: wrap;
          }
    
          .col-4 {
            flex: 33.3333%;
            padding: 5px;
          }
    
          .col-8 {
            flex: 66.6666%;
            padding: 5px;
          }
    
          input.form-control {
            width: 100%;
            padding: 5px 10px;
          }
    
          .text-center {
            text-align: center;
          }
    
          .alert {
            color: red;
          }
    
          @media screen and (max-width: 700px) {
            .row {
              flex-direction: column;
            }
          }
        </style>
      </head>
      <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" />
          </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>
          <!-- checkEnter은 엔터 입력시 다음 id로 커서 이동  -->
          <div class="col-8">
            <input
              type="text"
              name=""
              id="company"
              class="form-control"
              onkeyup="checkEnter(event, 'email');"
            />
          </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();"
              onkeyup="checkEnter(event, 'phone');"
            />
            <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();"
              onkeyup="checkEnterForPhone(event);"
            />
            <div id="phoneMsg" class="alert" style="display: none">
              올바른 형식의 연락처를 입력하세요.
            </div>
          </div>
          <div class="col-4">
            <label for="address">Address</label>
          </div>
          <!-- 외부 API 주소 찾기  -->
          <div class="col-8">
            <button onclick="openDaumAPI();">주소찾기</button>
            <!-- 우편번호 / readonly는 사용자가 직접 입력하지 못하게 함 -->
            <input type="text" name="" id="zonecode" style="width: 80px" readonly />
            <!-- 주소 -->
            <input type="text" name="" id="address" class="form-control" readonly />
          </div>
        </div>
        <div class="text-center">
          <button onclick="doCreate();">저장</button>
          <!-- 목록으로 돌아가기 -->
          <button onclick="goToList();">목록</button>
          <!-- 입력 초기화 -->
          <button onclick="doReset();">초기화</button>
        </div>
        <!-- 다음 우편번호 서비스 API -->
        <script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
        <script>
          async function doCreate() {
            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을 입력하세요.");
            }
    
            if (confirm("정말 저장하시겠습니까?")) {
              const res = await fetch("http://localhost:3000/customers", {
                method: "POST",
                body: JSON.stringify({
                  name,
                  gender,
                  company,
                  email,
                  phone,
                  address,
                }),
                headers: {
                  "content-type": "application/json;charset=UTF-8",
                },
              });
              // 저장 후 처리
              if (res.status === 201) {
                alert("정상적으로 생성되었습니다.");
                document.location.href = "dom.html"; // 목록으로 돌아가기
              } 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.location.reload(); // 화면 refresh
    
            document.querySelector("#name").value = "";
            document.querySelector("#company").value = "";
            document.querySelector("#email").value = "";
            document.querySelector("#phone").value = "";
            document.querySelector("#address").value = "";
          }
    
          // 엔터 입력시 다음 id로 이동
          function checkEnter(e, id) {
            if (e.keyCode === 13) {
              document.querySelector("#" + id).focus(); // focus를 주면 커서가 이동
            }
          }
    
          // 엔터 입력시 주소찾기 창 팝업
          function checkEnterForPhone(e) {
            if (e.keyCode === 13) {
              openDaumAPI();
            }
          }
        </script>
      </body>
    </html>
    728x90
    반응형
    댓글