<!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>회원가입 화면 샘플 - Bootstrap</title>

  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" crossorigin="anonymous">

  <style>
    body {
      min-height: 100vh;
      background: linear-gradient(to top right, #92b5db 0%, #1d466c 100%);
    }
    .input-form {
      max-width: 680px;
      margin-top: 80px;
      padding: 32px;
      background: #fff;
      border-radius: 10px;
      box-shadow: 0 8px 20px 0 rgba(0, 0, 0, 0.15);
    }
    #wrap {
      display: none;
      border: 1px solid;
      width: 100%;
      height: 300px;
      margin: 5px 0;
      position: relative;
    }
    #btnFoldWrap {
      cursor: pointer;
      position: absolute;
      right: 0px;
      top: -1px;
      z-index: 1;
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="input-form-background row">
      <div class="input-form col-md-12 mx-auto">
        <h4 class="mb-3">회원가입</h4>

        <!-- Django 메시지 표시 -->
        {% if messages %}
          <div class="alert alert-danger">
            {% for message in messages %}
              <p>{{ message }}</p>
            {% endfor %}
          </div>
        {% endif %}

        <form method="post" class="validation-form" novalidate>
          {% csrf_token %}
          <!-- 아이디 입력 필드 -->
          <div class="mb-3">
            <label for="username">아이디</label>
            <input type="text" class="form-control" id="username" name="username" placeholder="아이디를 입력하세요" required>
            <div class="invalid-feedback">아이디를 입력해주세요.</div>
          </div>

          <!-- 닉네임 입력 필드 -->
          <div class="mb-3">
            <label for="nickname">닉네임</label>
            <input type="text" class="form-control" id="nickname" name="nickname" placeholder="닉네임을 입력하세요" required>
            <div class="invalid-feedback">닉네임을 입력해주세요.</div>
          </div>

          <!-- 비밀번호 입력 필드 -->
          <div class="mb-3">
            <label for="password">비밀번호</label>
            <input type="password" class="form-control" id="password" name="password" placeholder="비밀번호" required>
            <div class="invalid-feedback">비밀번호를 입력해주세요.</div>
          </div>

          <!-- 비밀번호 확인 입력 필드 -->
          <div class="mb-3">
            <label for="password_confirm">비밀번호 확인</label>
            <input type="password" class="form-control" id="password_confirm" name="password_confirm" placeholder="비밀번호 확인" required>
            <div class="invalid-feedback">비밀번호를 다시 입력해주세요.</div>
          </div>

          <!-- 전화번호 입력 필드 -->
          <div class="mb-3">
            <label for="phone">전화번호</label>
            <input type="tel" class="form-control" id="phone" name="phone" placeholder="010-1234-5678" required>
            <div class="invalid-feedback">전화번호를 입력해주세요.</div>
          </div>

          <!-- 우편번호 입력 필드 -->
          <div class="mb-3">
            <label for="sample3_postcode">우편번호</label>
            <input type="text" id="sample3_postcode" name="sample3_postcode" class="form-control" placeholder="우편번호" readonly>
            <input type="button" class="btn btn-outline-secondary mt-2" onclick="sample3_execDaumPostcode()" value="우편번호 찾기">
          </div>

          <!-- 주소 입력 필드 -->
          <div class="mb-3">
            <label for="sample3_address">주소</label>
            <input type="text" id="sample3_address" name="sample3_address" class="form-control" placeholder="주소" readonly>
          </div>

          <!-- 상세주소 입력 필드 -->
          <div class="mb-3">
            <label for="sample3_detailAddress">상세주소<span class="text-muted">&nbsp;(필수 아님)</span></label>
            <input type="text" id="sample3_detailAddress" name="sample3_detailAddress" class="form-control" placeholder="상세주소를 입력해주세요.">
          </div>

          <!-- 참고항목 입력 필드 (숨김 처리) -->
          <input type="text" id="sample3_extraAddress" name="sample3_extraAddress" class="form-control" placeholder="참고항목" style="display:none;">

          <hr class="mb-4">
          <div class="custom-control custom-checkbox">
            <input type="checkbox" class="custom-control-input" id="agreement" required>
            <label class="custom-control-label" for="agreement">개인정보 수집 및 이용에 동의합니다.</label>
          </div>
          <div class="mb-4"></div>
          <button class="btn btn-primary btn-lg btn-block" type="submit">가입 완료</button>
        </form>
      </div>
    </div>
  </div>

  <!-- 우편번호 찾기 iframe -->
  <div id="wrap">
    <img src="//t1.daumcdn.net/postcode/resource/images/close.png" id="btnFoldWrap" onclick="foldDaumPostcode()" alt="접기 버튼">
  </div>

  <script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
  <script>
    var element_wrap = document.getElementById('wrap');

    function foldDaumPostcode() {
      element_wrap.style.display = 'none';
    }

    function sample3_execDaumPostcode() {
      var currentScroll = Math.max(document.body.scrollTop, document.documentElement.scrollTop);
      new daum.Postcode({
        oncomplete: function(data) {
          var addr = '';
          var extraAddr = '';

          if (data.userSelectedType === 'R') {
            addr = data.roadAddress;
          } else {
            addr = data.jibunAddress;
          }

          if (data.userSelectedType === 'R') {
            if (data.bname !== '' && /[동|로|가]$/g.test(data.bname)) {
              extraAddr += data.bname;
            }
            if (data.buildingName !== '' && data.apartment === 'Y') {
              extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
            }
            if (extraAddr !== '') {
              extraAddr = ' (' + extraAddr + ')';
            }
            document.getElementById("sample3_extraAddress").value = extraAddr;
          } else {
            document.getElementById("sample3_extraAddress").value = '';
          }

          document.getElementById('sample3_postcode').value = data.zonecode;
          document.getElementById("sample3_address").value = addr;

          document.getElementById("sample3_detailAddress").focus();
          element_wrap.style.display = 'none';
          document.body.scrollTop = currentScroll;
        },
        onresize: function(size) {
          element_wrap.style.height = size.height + 'px';
        },
        width: '100%',
        height: '100%'
      }).embed(element_wrap);
      element_wrap.style.display = 'block';
    }

    document.addEventListener('DOMContentLoaded', function() {
      const form = document.querySelector('.validation-form');

      form.addEventListener('submit', function(event) {
        let valid = true;

        // Resetting custom validation messages
        form.querySelectorAll('.invalid-feedback').forEach(function(msg) {
          msg.style.display = 'none';
        });

        // Checking if passwords match
        const password = document.getElementById('password');
        const passwordConfirm = document.getElementById('password_confirm');

        if (password.value !== passwordConfirm.value) {
          valid = false;
          const errorMessage = passwordConfirm.nextElementSibling;
          errorMessage.textContent = '비밀번호가 일치하지 않습니다.';
          errorMessage.style.display = 'block';
        }

        // Checking if all required fields are filled
        form.querySelectorAll('input[required]').forEach(function(input) {
          if (!input.value) {
            valid = false;
            const errorMessage = input.nextElementSibling;
            errorMessage.textContent = `${input.previousElementSibling.textContent}을(를) 입력해주세요.`;
            errorMessage.style.display = 'block';
          }
        });

        // Prevent form submission if validation fails
        if (!valid) {
          event.preventDefault();
        }
      });
    });
  </script>
</body>
</html>
다음지도 api 사용자가 직접 움직여서 마커 찍은다음에 위도 경도 정보 db에 저장