html 코드 톺아보기

오늘 완성한 웹앱의 1) GAS 창, 2)웹앱 을 새 창으로 켜 놓고 시작합니다~

1. html 파일의 구조

내용 보기

html 파일은 아래와 같이 구성됩니다.

<!DOCTYPE html>
<html>
  <head>
  
  </head>
  <body>
  
  </body>
</html>
  • <html>,</html> : html문서의 시작과 끝
  • <head>,</head> : html 문서에 대한 정보 정의하는 영역(언어, 제목, 뷰포트 등)
  • <body>,</body>: 클라이언트에게 보여지는 모든 것이 담기는 영역

지금은 웹앱의 특성상 <style>태그와 <script>태그가 추가되어 있는 구조입니다.

<!DOCTYPE html>
<html>
  <head>
    <style>
    </style>
    <script>
    </script>
  
  </head>
  <body>
  
  </body>
</html>
  • <style>: CSS코드가 들어가는 부분. 사실상 디자인 영역
  • <script>: 자바스크립트 코드가 들어가는 영역

우리가 만든 코드 안에서도 html 기본 구조를 확인해 봅시다.

html코드 보기
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <style>
      body { font-family: "맑은 고딕", sans-serif; margin: 20px; }
      h2, h3 { text-align: center; margin-bottom: 20px; }
      .greeting-box { border: 1px solid #ccc; border-radius: 8px; padding: 15px; background-color: #f9f9f9; margin-bottom: 20px; line-height: 1.6; }
      table { border-collapse: collapse; width: 100%; max-width: 800px; margin: 0 auto 30px auto; text-align: center; }
      table, th, td { border: 1px solid #999; }
      th, td { padding: 10px; }
      th { background-color: #f0f0f0; }
      .form-section { max-width: 600px; margin: 0 auto; }
      .form-group { margin-bottom: 15px; }
      label { display: block; margin-bottom: 5px; font-weight: bold; }
      input[type="text"], select, textarea { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; font-family: inherit; }
      textarea { height: 80px; resize: vertical; }
      .radio-group { display: flex; gap: 20px; }
      .submit-btn { display: inline-block; background-color: #4CAF50; color: white; padding: 10px 20px; font-size: 16px; border: none; border-radius: 6px; cursor: pointer; transition: background-color 0.3s ease; }
      .submit-btn:hover { background-color: #45a049; }
    </style>
    <script>
      function submitForm() {
        const name = document.getElementById("studentName").value.trim();
        const date = document.getElementById("dateSelect").value;
        const time = document.querySelector("input[name='time']:checked")?.value || "";
        const note = document.getElementById("note").value.trim();

        if (!name || !date || !time) {
          alert("학생 이름, 날짜, 시간을 모두 입력해주세요.");
          return;
        }

        google.script.run
          .withSuccessHandler(function(response) {
            const btn = document.getElementById("submitBtn");
            if (response === "success") {
              btn.innerText = "전송 완료";
              btn.disabled = true;
              btn.style.backgroundColor = "#999";
              alert("상담 예약이 완료되었습니다.");
              loadReservationData(); // 저장 후 표 갱신
            } else if (response === "duplicate") {
              alert("이미 예약이 존재합니다. 다른 날짜 또는 시간을 택해주세요.");
            } else {
              alert("예약 중 오류가 발생했습니다. 다시 시도해주세요.");
            }
          })
          .saveReservation(name, date, time, note);
      }

      // 서버에서 시트 데이터 읽어와 표에 표시
      function loadReservationData() {
        google.script.run.withSuccessHandler(function(data) {
          const times = ["19:00-20:00","20:00-21:00"];
          const dates = ["9.15.(월)","9.16.(화)","9.17.(수)","9.18.(목)","9.19.(금)"];
          
          times.forEach((time, rowIdx) => {
            dates.forEach((date, colIdx) => {
              const cell = document.querySelectorAll("table tr")[rowIdx + 2].cells[colIdx + 1];
              cell.textContent = data[time][date] || "";
            });
          });
        }).getReservationData();
      }

      window.onload = function() {
        loadReservationData(); // 페이지 로드 시 예약 현황 표시
      };
    </script>
  </head>
  <body>
    <h2>아이좋아고등학교 3학년 1반 학부모 상담 예약</h2>
    <div class="greeting-box">
      안녕하십니까. 3학년 1반 학부모님. 학기초 상담주간을 맞이하여 학부모 상담을 실시하고자 합니다. 
      바쁘시겠지만 시간을 내시어, 자녀의 학교 생활 및 교우 관계, 진로진학과 관련하여 알찬 시간이 될 수 있도록 많은 참석 부탁드립니다. 
      원하는 날짜와 시간을 선택하셔서 상담 예약을 부탁드립니다.
    </div>

    <table>
      <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td>9.15.</td>
        <td>9.16.</td>
        <td>9.17.</td>
        <td>9.18.</td>
        <td>9.19.</td>
      </tr>
      <tr>
        <td>19:00-20:00</td>
        <td></td><td></td><td></td><td></td><td></td>
      </tr>
      <tr>
        <td>20:00-21:00</td>
        <td></td><td></td><td></td><td></td><td></td>
      </tr>
    </table>

    <h3>상담 신청</h3>
    <div class="form-section">
      <div class="form-group">
        <label>1. 학생의 이름을 적어주세요</label>
        <input type="text" id="studentName" placeholder="예: 홍길동">
      </div>

      <div class="form-group">
        <label>2. 원하시는 날짜를 택해주세요</label>
        <select id="dateSelect">
          <option value="">-- 선택하세요 --</option>
          <option value="9.15.(월)">9.15.(월)</option>
          <option value="9.16.(화)">9.16.(화)</option>
          <option value="9.17.(수)">9.17.(수)</option>
          <option value="9.18.(목)">9.18.(목)</option>
          <option value="9.19.(금)">9.19.(금)</option>
        </select>
      </div>

      <div class="form-group">
        <label>3. 원하시는 시간을 택해주세요</label>
        <div class="radio-group">
          <label><input type="radio" name="time" value="19:00-20:00"> 19:00-20:00</label>
          <label><input type="radio" name="time" value="20:00-21:00"> 20:00-21:00</label>
        </div>
      </div>

      <div class="form-group">
        <label>4. 참고사항이 있다면 적어주세요.</label>
        <textarea id="note" placeholder="예: 아이의 성향, 특별히 상담하고 싶은 내용 등"></textarea>
      </div>

      <button id="submitBtn" class="submit-btn" onclick="submitForm()">전송</button>
    </div>
  </body>
</html>

.

2.body태그

내용 보기

클라이언트 눈에 보이는 모든 것은 <body>태그 안에 있다.

1)제목

<body>
    <h2>아이좋아고등학교 3학년 1반 학부모 상담 예약</h2>
  • <h2></h2> : 글자 크기를 2단계로 하라.

.
2) 학생 이름 입력란

<div class="form-group">
        <label>1. 학생의 이름을 적어주세요</label>
        <input type="text" id="studentName" placeholder="예: 홍길동">
      </div>
  • <div></div> : 영역으로 묶는 코드
  • class = “form-group” : 이 구역(div)의 class선택자를 form-group으로 하라.
  • <input> : 사용자로부터 입력받는 요소를 생성하는 태그(이름, 전화번호, 주소, 의견,..)
    | type=”text” : 텍스트 타입을 입력받을것
    | id = “studentName” : 이 입력폼의 id선택자를 studentName으로 하라.
    | placeholder : 입력값에 대한 힌트

3) 전송 버튼

<button id="submitBtn" class="submit-btn" onclick="submitForm()">전송</button>   
  • <button>,</button> : 버튼 생성 태그
  • 이 버튼의 고유한 이름 역할을 하는 선택자는? submitBtn
  • 버튼의 또 다른 선택자는? submit-btn
  • onclick=”submitForm()” : 버튼이 클릭되면 submitForm()이라는 함수를 실행시켜라. (<<API)

.

3.다양한 html 폼 요소

내용 보기

1)텍스트입력필드

<input type="text" id="studentName" placeholder="예: 홍길동">
  • <input type=”text”> : 텍스트 입력필드

2) 콤보박스(드롭다운)

<select id="dateSelect">
          <option value="">-- 선택하세요 --</option>
          <option value="9.15.(월)">9.15.(월)</option>
          <option value="9.16.(화)">9.16.(화)</option>
          <option value="9.17.(수)">9.17.(수)</option>
          <option value="9.18.(목)">9.18.(목)</option>
          <option value="9.19.(금)">9.19.(금)</option>
        </select>
  • <select></select> : 콤보박스(드롭다운)의 시작과 끝
  • <option value=”9.15.(월)”> 9.15.(월)을 선택하세요 </option>
    : “9.15.(월)을 선택하세요” 옵션을 택하면 드롭다운의 값이 “9.15.(월)”이 되도록 하여라.

Q. 해당셀렉트에 9.20.(토) 항목을 추가해보세요

3)라디오버튼

<label><input type="radio" name="time" value="19:00-20:00"> 19:00-20:00</label>
          
  • <input type=”radio”> : 라디오버튼 형식의 입력폼

.

4.style태그

내용 보기

style 태그는 무엇을(선택자) 어떻게(속성) 꾸밀지 정해주는 부분이다. CSS언어로 작성.

body { font-family: "맑은 고딕"; }
  • 의미 : body태그 즉 페이지 전체의 글꼴은 맑은 고딕으로 해주세요
  • 선택자(무엇을) : body
  • 속성(어떻게) : font-family:”맑은 고딕”

태그 선택자 스타일 지정

아래와 같이 <h2>태그로 작성된 태그의 스타일은 어떻게 지정할까?

<h2>아이좋아고등학교 3학년 1반 학부모 상담 예약</h2>

다음과 같이 h2태그 전체에 대해 글꼴 등의 스타일을 지정할 수 있다.

h2, h3 { text-align: center; margin-bottom: 20px; }
  • h2, h3 { } : h2, h3 태그 전체에 대해 {} 속의 내용대로 스타일 지정
  • text-align: center : 가운데정렬
  • margin-bottom : 20px : 아래쪽 여백 폭을 20px로 지정

class선택자 활용 스타일 지정

하지만 모든 태그에 대해 일일이 스타일을 지정하는 것은 비효율적이다. 예컨대 아래 상담섹션 구역에서 1,2,3,4번 항목의 글자체, 글씨 색 등은 통일되어야 하므로 스타일을 한꺼번에 지정하는 것이 효율적이다. 이 때 필요한 것이 class 선택자다.

.form-group { margin-bottom: 15px; }
  • .form-group { } : class선택자가 form-group인 모든 요소의 스타일은 {}안의 내용으로 통일

Q. 오늘 완성한 코드에서 상담신청 섹션의 1,2,3,4번 항목의 글자 색을 모두 회색으로 바꿔 보세요. (속성명: color)

.

5.script태그

내용 보기

여기서부터 살~짝 어려워진다. script 태그 안에는 클라이언트와 서버 간의 상호작용에 관한 함수가 들어 있다. 자바스크립트 언어를 쓴다.

1)script태그 구조

<script>

  //1.전송버튼 눌렀을 때의 기능 함수
  function submitForm() {
  }
  
  //2. 서버의 데이터를 가져와 프론트엔드의 표 채우는 기능 함수
  function loadReservationData(){
  }
  
  //3. 웹페이지가 처음 열렸을 때의 기능 함수
  window.onload = function() {
  }
  
</script>

.

2) function submitForm() {}

const name = document.getElementById("studentName").value.trim();
const date = document.getElementById("dateSelect").value;
const time = document.querySelector("input[name='time']:checked")?.value || "";
const note = document.getElementById("note").value.trim();
  • const name = document.getElementById(“studentName”).value.trim();
    : id선택자가 studentName인 녀석의 값을 가져와 name이라는 변수에 담아라

Q. 학생 이름이 “홍길동”이었으면 name의 값은?

A. 답 보기 : “홍길동”

아래 내용은 조금 많이 어려우므로 마음을 내려놓고 들어주세요. ^^

google.script.run
          .withSuccessHandler(function(response) {
            const btn = document.getElementById("submitBtn");
            if (response === "success") {
              btn.innerText = "전송 완료";
              btn.disabled = true;
              btn.style.backgroundColor = "#999";
              alert("상담 예약이 완료되었습니다.");
              loadReservationData(); // 저장 후 표 갱신
            } else if (response === "duplicate") {
              alert("이미 예약이 존재합니다. 다른 날짜 또는 시간을 택해주세요.");
            } else {
              alert("예약 중 오류가 발생했습니다. 다시 시도해주세요.");
            }
          })
          .saveReservation(name, date, time, note);
      }
  • google.script.run : code.gs에 든 함수 즉 서버함수를 실행시켜라.
  • .saveReservation(name, date, time, note) : name, date, time, note를 갖고 saveReservation 함수를 실행(호출)하라.
  • withSuccessHandler (function (response) {..}) : 일이 성공적으로 끝나면 그 결과를 response라는 이름으로 돌려줘. 그럼 내가 {} 속의 일을 할게.
이 내용이 어려운 이유는 여기에 콜백함수라는 개념이 쓰였기 때문입니다. 코딩 중급자는 이해할 수 있습니다. 아래에 콜백함수에 대해 소개한 글이 있으니 시간되실 때 읽어보셔도 좋습니다.

(클릭) 콜백함수 강의 보러 가기 (중급자 이상)

3)window.onload

이 함수는 서버에서 클라이언트로의 통신 함수이다. 웹앱에 접속하면 서버에 있는 예약 현황이 웹앱의 표에 뜨게 하자.

window.onload = function() {
        loadReservationData(); // 페이지 로드 시 예약 현황 표시
      }
  • window.onload : 웹앱의 모든 요소(이미지, 글자 등)가 완전히 로딩되었을 때
  • loadReservation() : loadReservation()함수를 실행(호출)하라. (예약현황 보여주는 함수)

.

>> code.gs 코드 톺아보기 바로가기


코멘트

“html 코드 톺아보기”에 대한 댓글 1개

  1. […] 이론 강의 글 가기 […]

댓글 남기기

Cha's Record에서 더 알아보기

지금 구독하여 계속 읽고 전체 아카이브에 액세스하세요.

계속 읽기