HTML 체크박스: 복수 선택·checked·미선택 전송 처리

HTML의 <input type="checkbox">는 각 항목을 독립적으로 선택·해제하는 입력 요소입니다. 선택된 체크박스만 name과 value가 제출되며, 선택하지 않은 항목은 false나 빈 문자열이 아니라 제출 데이터에서 빠집니다.

같은 name으로 여러 값 받기

체크박스는 라디오 버튼과 달리 같은 name을 가진 항목도 동시에 여러 개 선택할 수 있습니다. 같은 이름의 값이 반복되므로 데이터를 받을 때 모든 값을 읽어야 합니다. JavaScript FormData에서는 getAll을 사용할 수 있고, 서버에서는 프레임워크의 복수 값 처리 규칙을 확인합니다.

name은 항목 이름, value는 선택했을 때 제출할 값입니다. value를 생략하면 기본 문자열 on이 사용되므로 서로 다른 선택지를 구분하려면 값을 명시합니다. label과 연결하는 id는 각 체크박스마다 고유하게 지정합니다.

전체 예제: 복수 선택·필수 확인·제출 제외

다음 코드를 checkbox-demo.html로 저장해 브라우저에서 엽니다. 서버로 보내는 대신 실제 양식 항목을 페이지에 표시합니다. 비활성 항목이 선택되어 있어도 데이터에서 제외되는 것을 비교할 수 있습니다.

<!doctype html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>체크박스 제출 값</title>
  <style>pre { white-space: pre-wrap; overflow-wrap: anywhere; }</style>
</head>
<body>
  <h1>체크박스 실습</h1>
  <form id="demo">
    <fieldset>
      <legend>원하는 색 (복수 선택)</legend>
      <input type="checkbox" id="blue" name="color" value="blue" checked>
      <label for="blue">파랑</label>
      <input type="checkbox" id="red" name="color" value="red">
      <label for="red">빨강</label>
      <input type="checkbox" id="locked" name="color" value="green" checked disabled>
      <label for="locked">초록 (비활성)</label>
    </fieldset>
    <p>
      <input type="checkbox" id="ready" name="ready" value="yes" required>
      <label for="ready">실습 준비 완료 (필수)</label>
    </p>
    <button type="submit">값 확인</button>
    <button type="reset">초기화</button>
    <button type="button" id="partial">파랑을 부분 선택 모양으로 표시</button>
  </form>
  <pre id="result" aria-live="polite"></pre>
  <script>
    const form = document.getElementById('demo');
    const result = document.getElementById('result');
    const blue = document.getElementById('blue');
    form.addEventListener('submit', (event) => {
      event.preventDefault();
      result.textContent = JSON.stringify(Array.from(new FormData(form).entries()), null, 2);
    });
    document.getElementById('partial').addEventListener('click', () => {
      blue.indeterminate = true;
    });
    form.addEventListener('reset', () => {
      result.textContent = '';
      blue.indeterminate = false;
    });
  </script>
</body>
</html>
  1. 실습 준비 완료를 선택하지 않고 값 확인을 누르면 필수 검사가 제출을 막습니다.
  2. 실습 준비 완료와 빨강을 선택한 뒤 확인합니다. color=blue·color=red와 ready=yes가 표시되고 비활성 초록은 빠집니다.
  3. 파랑·빨강을 모두 해제하고 다시 확인하면 color 항목이 없어지고 ready만 남습니다.
  4. 초기화하면 파랑·초록은 원래 선택 상태로, 빨강·준비 완료는 미선택으로 돌아갑니다.

checked·required·부분 선택 상태 구분

checked 속성은 초기 선택을 나타냅니다. 현재 상태는 JavaScript의 checked 프로퍼티로 읽습니다. checked="false"도 선택 속성이 존재하는 것이므로 초기 미선택을 만들려면 속성을 생략합니다. reset은 모든 체크를 지우는 대신 초기값을 복원합니다.

required를 지정한 체크박스는 그 항목 자체가 선택되어야 합니다. 같은 name의 여러 체크박스 중 하나만 선택하면 된다는 뜻이 아닙니다. “이 중 하나 이상”이라는 조건은 별도의 검증과 안내가 필요합니다.

indeterminate는 JavaScript 프로퍼티로 지정하는 부분 선택 표시입니다. HTML 속성으로 설정하지 않으며, 제출 여부를 결정하는 checked 상태와 독립적입니다. 초기화 직후 부분 선택 표시 버튼을 누르고 준비 완료를 선택해 값을 확인하면 파랑은 여전히 제출됩니다. 부분 표시가 체크를 자동으로 지우거나 제3의 전송 값을 만드는 것은 아닙니다.

서버에서 미선택과 복수 값을 처리하기

미선택 항목이 없다고 무조건 오류로 보거나, 같은 이름의 마지막 값만 읽으면 의도와 달라질 수 있습니다. “아무것도 선택하지 않음”과 잘못된 요청을 업무 규칙에 맞게 구분하고 허용된 선택 값인지 서버에서 확인합니다.

PHP에서 name="color[]"를 사용하면 배열 형태로 받을 수 있지만, 이는 서버 파서의 규칙입니다. 브라우저가 모든 언어에 공통인 배열 객체를 전송하는 것은 아닙니다. 수신 값이 배열인지 확인하고, 누락·중첩 배열·허용되지 않은 값도 처리해야 합니다. 관련 규칙은 PHP의 외부 변수 처리 문서에서 확인할 수 있습니다. 체크박스 자체의 동작은 MDN checkbox 문서를 참고합니다.