Checkbox (체크박스)
Va.Checkbox — 체크박스
가장 흔한 폼 입력 중 하나. VanillaFront의 Checkbox는 표준 <input type="checkbox">을 감싸되, 값의 형태를 다양하게 선택 할 수 있고 (true/false, Y/N, 1/0), 3상 상태(mixed), 라벨 클릭 토글, 키보드(스페이스) 지원을 모두 포함합니다.
- 클래스: Va.Checkbox — va_component.js:4483
- short name: checkbox
- 상속: Va.PureField (Input·Combobox와 형제)
- isContainer: true
- 베이스 CSS: va-checkbox

1. 기본 사용
{
tagName: 'checkbox',
checkboxLabel: '동의합니다',
checked: false,
onChange: 'onAgreeChange'
}
- 좌측: 체크박스 아이콘
- 우측: 라벨 (동의합니다)
- 라벨 클릭도 토글로 동작 (기본)
2. Va.Checkbox의 특징
일반 HTML <input type="checkbox">와 크게 다른 점:
항목HTML 표준Va.Checkbox
| 값 타입 | 항상 boolean | true/false / Y/N / 1/0 선택 가능 |
| 3상 상태 | indeterminate 프로퍼티 (시각적으로만) | checked: 'mixed' 로 지원 |
| 라벨 | <label for="..."> 별도 태그 | checkboxLabel 옵션 하나로 통합 |
| 키보드 | 브라우저 기본 | 스페이스로 토글, focus 시각 표시 자동 |
| ARIA | 개발자가 붙여야 | role="checkbox", aria-checked 자동 |
| 아이콘 | OS 기본 스타일 | 커스텀 SVG 아이콘 (테마 반영) |
3. 값 타입 3종 — valueType
체크 상태를 어떤 값으로 다룰지 지정합니다.
valueType체크 시미체크 시언제 쓰나
| (미지정, 기본) | true | false | 표준 JS boolean |
| 'YN' | 'Y' | 'N' | DB가 Y/N 컬럼일 때 |
| '10' | 1 | 0 | DB가 int 0/1 컬럼일 때 |
예시
// 기본 boolean
{ tagName: 'checkbox', checkboxLabel: '동의', valueType: undefined }
// getChecked() → true / false
// Y/N 문자열
{ tagName: 'checkbox', checkboxLabel: '동의', valueType: 'YN' }
// getChecked() → 'Y' / 'N'
// 0/1 숫자
{ tagName: 'checkbox', checkboxLabel: '동의', valueType: '10' }
// getChecked() → 1 / 0
서버 DB 스키마에 맞추는 게 핵심입니다. Y/N 컬럼인데 boolean으로 다루면 저장 때마다 변환하느라 코드가 지저분해집니다. valueType으로 처음부터 맞춰두세요.
4. 3상 상태 (checked: 'mixed')
일반적인 체크박스는 켜짐/꺼짐 2상이지만, VanillaFront는 중간 상태(mixed) 를 지원합니다.
{
tagName: 'checkbox',
checkboxLabel: '전체 선택',
checked: 'mixed'
}
언제 쓰나:
- 부모-자식 트리 구조에서 자식 일부만 선택된 상태
- "모두 선택" 체크박스가 자식 중 일부만 체크됐음을 시각화할 때
시각: 체크 아이콘이 ico_checkbox_indeterminate (가로 막대) 로 표시됩니다.
ARIA: aria-checked="mixed"로 자동 세팅 → 스크린리더가 정확히 인식.
실전 패턴
class TreeCheckbox extends Va.View {
updateParent() {
const children = this.getRefs('child');
const checked = children.filter(c => c.getChecked()).length;
if (checked === 0) this.getRef('parent').setChecked(false);
else if (checked === children.length) this.getRef('parent').setChecked(true);
else this.getRef('parent').setChecked('mixed');
}
}
5. 주요 속성
체크 상태
속성기본값설명
| checked | false | 상태값. true/false, 'Y'/'N', 1/0, 'mixed' 모두 인식 |
| valueType | undefined | 'YN' / '10' / 미지정 (표준 boolean) |
| selected | false | 선택 상태 (checked와는 별개 개념) |
라벨
속성기본값설명
| checkboxLabel | — | 우측에 표시되는 라벨 텍스트 |
| checkboxLabelClick | true | 라벨 클릭으로도 토글 가능 여부 |
데이터 (그리드·리스트에서 활용)
속성설명
| key | 데이터 key 필드명 (그리드의 checkbox 컬럼 등에서 사용) |
| display | 표시 필드명 |
PureField 상속
readonly, disabled, size, appearance, stopPropagation 등 표준.
6. 이벤트
이벤트시그니처발생 시점
| change | (component, element, checked, evt) | 체크 상태 변경 시 — 가장 자주 씀. checked가 새 상태값 |
| click | (component, element, evt) | 클릭 시 (change와 함께 발생) |
| keydown | (component, element, keyCode, evt) | 스페이스 눌러 토글 시 |
| keyup | (component, element, keyCode, evt) | 키업 |
| focus / blur | (component, element, evt) | 포커스 진입/이탈 |
change 콜백 예시
onAgreeChange(comp, el, checked, evt) {
console.log('새 상태:', checked); // true / 'Y' / 1 / 'mixed' 등
this.getRef('submitBtn').setDisabled(!checked);
}
⚠️ change 이벤트의 세 번째 인자가 새 상태값 — 다른 이벤트와 시그니처가 미묘하게 다릅니다. 필요하면 comp.getChecked()로 정규화된 값을 다시 조회.
7. 메서드
상태 조회·변경
메서드설명
| getChecked() | 현재 값 반환. valueType 규약에 맞춰 반환 (Y/N, 1/0, boolean) |
| setChecked(value) | 상태 세팅. true/'Y'/1/'mixed' 등 다양한 형태 수용 |
| check() | true로 세팅 (편의) |
| uncheck() | false로 세팅 (편의) |
포커스
메서드설명
| focus() | fieldWrapperElement에 포커스 (실제 <input>이 아님) |
| blur() | 블러 |
상태 (PureField 상속)
메서드설명
| setDisabled(bool) / setReadOnly(bool) | 상태 |
주의: setValue() / getValue()는 PureField의 것을 쓰지만, 체크박스의 실질 값은 getChecked() / setChecked()로 다루는 게 정석입니다.
8. 내부 구조
<div elname="element" class="va-checkbox [checked|mixed] [focused] [disabled]"
tag-name="checkbox" field="true">
<div elname="inner" class="checkbox-inner">
<div elname="fieldWrapper" class="field-wrapper" tabindex="0"
role="checkbox" aria-checked="true|false|mixed" aria-label="동의합니다">
<input elname="field" type="checkbox" style="display:none" tabindex="-1">
<span elname="icon" class="icon ico_checkbox_checked_fill">☑</span>
</div>
<label elname="checkboxLabel" class="label">동의합니다</label>
</div>
</div>
핵심 트릭:
- <input type="checkbox">는 display:none — 시각은 아이콘이 담당, 값은 여전히 표준 폼 서브밋에 참여
- fieldWrapper가 실제 tabindex 대상 — 키보드 포커스가 이쪽으로. <input>은 tabindex="-1"
- 아이콘 종류 3가지:
- ico_checkbox_unchecked — 빈 사각형
- ico_checkbox_checked_fill — 체크된 상태
- ico_checkbox_indeterminate — mixed 상태 (가로 막대)
- ARIA 자동 — role="checkbox", aria-checked, aria-label (checkboxLabel 있을 때)
9. 접근성 (a11y)
VanillaFront Checkbox는 접근성이 잘 되어 있습니다.
요소값
| role | "checkbox" (자동) |
| aria-checked | "true" / "false" / "mixed" (자동) |
| aria-label | checkboxLabel 값 (자동) |
| tabindex | 0 (Tab으로 접근 가능) |
| 스페이스 키 | 토글 (자동 처리) |
별도 세팅 없이도 스크린리더 사용자가 정확히 이해합니다.
10. Checkbox 계열 형제 컴포넌트
컴포넌트역할
| Va.Checkbox | 단일 체크박스 (이 문서) |
| Va.CheckboxField | Checkbox + Field 래퍼 (라벨/검증) |
| Va.CheckboxGroup | 여러 체크박스 그룹 (배열로 선택) |
| Va.CheckboxGroupField | CheckboxGroup + Field 래퍼 |
| Va.CheckboxMixed | 3상 상태 전용 컴포넌트 (자식과 연동) |
11. 언제 쓰나
Checkbox가 맞을 때
- 동의 여부 (약관, 마케팅 수신)
- 필터 on/off (표시 여부, 활성 상태)
- 다중 선택 목록 (여러 옵션 중 원하는 것들)
- 그리드의 행 선택 컬럼
- 부모-자식 트리에서 일괄 선택
다른 걸 쓸 때
- 라디오형 배타 선택 (하나만) → Va.Radio / Va.RadioGroup
- 라벨 붙은 폼 필드 → Va.CheckboxField
- 여러 선택지 그룹 → Va.CheckboxGroup
- ON/OFF 스위치 UI → Va.Switch (있다면)
- 시각적으로 버튼 형태로 → Va.ToggleButton
12. 흔한 조합 예시
// 표준 동의
{
tagName: 'checkbox',
checkboxLabel: '이용약관에 동의합니다',
ref: 'agree',
onChange: 'onAgreeChange'
}
// Y/N (DB 스키마 맞춤)
{
tagName: 'checkbox',
checkboxLabel: '수신 동의',
valueType: 'YN',
checked: 'N'
}
// 0/1 (int 컬럼)
{
tagName: 'checkbox',
checkboxLabel: '활성',
valueType: '10',
checked: 1
}
// 라벨 없이 아이콘만
{
tagName: 'checkbox',
checked: false,
style: { width: '32px' }
}
// mixed 상태 (전체 선택)
{
tagName: 'checkbox',
checkboxLabel: '전체 선택',
checked: 'mixed',
ref: 'selectAll'
}
// 읽기 전용
{
tagName: 'checkbox',
checkboxLabel: '완료됨',
checked: true,
readonly: true
}
// 라벨 클릭 비활성 (아이콘만 클릭 허용)
{
tagName: 'checkbox',
checkboxLabel: '주의: 신중히 선택',
checkboxLabelClick: false
}
13. 실전 패턴 — 전체 선택 + 개별 선택
class MultiSelect extends Va.View {
onSelectAll(comp, el, checked, evt) {
// 전체 선택 체크 시 모든 자식 체크
this.getRefs('child').forEach(c => c.setChecked(checked));
}
onChildChange(comp, el, checked, evt) {
// 자식 상태 → 부모 mixed 계산
const children = this.getRefs('child');
const count = children.filter(c => c.getChecked()).length;
if (count === 0) this.getRef('parent').setChecked(false);
else if (count === children.length) this.getRef('parent').setChecked(true);
else this.getRef('parent').setChecked('mixed');
}
config() {
return {
tagName: 'div',
layout: 'ds-flex fd-column gap-s',
tags: [
{
tagName: 'checkbox',
ref: 'parent',
checkboxLabel: '전체 선택',
onChange: 'onSelectAll'
},
{
tagName: 'div',
layout: 'ds-flex fd-column gap-xs',
style: { paddingLeft: '24px' },
tags: [
{ tagName: 'checkbox', ref: 'child', checkboxLabel: '항목 1', onChange: 'onChildChange' },
{ tagName: 'checkbox', ref: 'child', checkboxLabel: '항목 2', onChange: 'onChildChange' },
{ tagName: 'checkbox', ref: 'child', checkboxLabel: '항목 3', onChange: 'onChildChange' }
]
}
]
};
}
}
getRefs('child')가 배열을 반환하므로 forEach로 조작 가능. mixed 상태를 자동 계산하는 표준 패턴입니다.
14. 알아두면 좋을 주의사항
- checked는 다양한 형태 수용 — true, 'true', 'Y', 'y', 1, '1' 모두 체크로 인식. 'mixed'는 별도.
- getChecked()는 valueType 규약에 맞춰 반환 — 필드 세팅과 조회 형태를 일관되게 유지.
- change 이벤트 인자에 새 상태값 포함 — (comp, el, checked, evt). 다른 이벤트보다 인자 많음.
- click과 change 둘 다 발생 — 같은 클릭에 두 이벤트가 함께. 콜백에 로직 넣을 때 중복 실행 조심.
- <input> 자체는 숨겨짐 — 시각은 아이콘. 폼 서브밋에는 참여.
- fieldWrapper가 실제 focus 대상 — focus()가 <input>이 아니라 wrapper에 포커스.
- 스페이스 키 자동 토글 — keydown 32번 처리. preventDefault 자동.
- checkboxLabel 없으면 aria-label도 없음 — 접근성 관점에서 라벨 지정 권장.
- checkboxLabelClick: false 옵션 — 라벨 무심코 클릭하는 UX가 문제되는 상황(예: 긴 약관 텍스트)에 유용.
- selected 속성은 별개 — checked와 다른 개념. 그리드·리스트 항목의 선택 상태 등에서 활용.
- focus 이벤트가 readonly/disabled 상태에서 안 발생 — 소스에 조기 return 있음.
- mixed 상태에서 클릭 시 — 코드상 boolean 분기라 mixed → true 로 넘어감. 필요하면 별도 처리.
- 라벨 클릭 시 내부적으로 wrapper에 click 재전송 — dispatchEvent(new MouseEvent('click')) 방식. 이벤트가 두 번 처리될 위험은 없음.
- 초기값 세팅 시 setChecked 권장 — 프로그래매틱 변경엔 setChecked 사용. 옵션에 직접 세팅해도 되지만 setter가 update까지 트리거해 안전.
15. checkbox vs radio vs switch 선택
상황추천
| ON/OFF 단일 (동의, 활성) | checkbox |
| 여러 옵션 중 여러 개 선택 | checkbox × N (또는 checkboxGroup) |
| 여러 옵션 중 하나만 선택 | radio × N (또는 radioGroup) |
| ON/OFF를 스위치 스타일 (설정 화면) | switch |
| 시각적으로 버튼처럼 (툴바 토글) | toggleButton |
| 부모-자식 트리에서 일괄 선택 | checkbox + mixed 상태 |
"여러 선택 가능이면 checkbox, 하나만 가능이면 radio" 가 기본 원칙입니다.