Va.SwitchField — 라벨 + ON/OFF 스위치
Va.Switch가 순수 슬라이드 스위치라면, Va.SwitchField는 그 위에 폼 라벨·필수 표시·검증 메시지를 얹은 완성 폼 필드입니다. Field 계열 아키텍처 그대로, 내부에 Va.Switch를 소유하는 Composition 구조. CheckboxField와 완전히 같은 패턴이지만 UI만 스위치.
- 클래스: Va.SwitchField — va_component.js:10512
- short name: switchField
- 상속: Va.Field (다른 Field 형제들과 같음)
- 내부 컴포넌트: Va.Switch 인스턴스 (fieldComponent)
- isContainer: true
- 베이스 CSS: va-field

1. 기본 사용
{
tagName: 'switchField',
label: '알림',
checked: true,
onChange: 'onNotifChange'
}
라벨 + 검증 + 슬라이드 스위치가 한 번에 세팅.
2. Switch / CheckboxField와의 차이
항목Va.SwitchVa.SwitchFieldVa.CheckboxField
| 폼 라벨 | ✕ | ✓ | ✓ |
| 검증 메시지 | ✕ | ✓ | ✓ |
| 필수 표시(별표) | ✕ | ✓ | ✓ |
| UI 형태 | 슬라이드 스위치 | 슬라이드 스위치 | 사각 체크박스 |
| 의미 | ON/OFF 즉시 반영 | ON/OFF 즉시 반영 | 저장 시 반영 |
| 3상 상태(mixed) | ✕ | ✕ | ✓ |
| 자체 라벨 옵션 | ✕ | ✕ (checkboxLabel 사용 안 됨) | checkboxLabel |
한 줄 요약: "폼 안 라벨 붙은 ON/OFF 스위치 — 설정 화면에 최적."
3. 주요 속성
체크 상태 (Switch 계승)
속성기본값설명
| checked | false | 상태값. true/'Y'/1 등 다양한 형태 인식 |
| valueType | undefined | 'YN' / '10' / 미지정 (표준 boolean) |
| selected | — | 별개 개념 |
라벨 관련 (Field 상속)
속성설명
| label | 폼 라벨 |
| labelPosition | top / bottom / left / right |
| labelWidth | 라벨 폭 |
| noLabel | 폼 라벨 숨김 |
| infoButton | info 아이콘 |
| required | 필수 표시 |
검증
속성설명
| validation | {state, size, message} |
| validationState | success / warning / error |
| validationMessage | 메시지 |
세부 커스터마이즈 (오타 있음 — swtich)
{
tagName: 'switchField',
label: '알림',
swtich: { // ← ⚠️ 오타지만 실제 코드가 이 키를 씀
stopPropagation: false
}
}
⚠️ 옵션 키가 swtich (오타) — 소스 코드 va_component.js:10537에서 ...this.option.swtich로 되어 있음. switch가 아니라 오탈자로 swtich가 사실상의 옵션 키가 되어 버렸습니다. switch로 넘기면 무시됩니다.
각 Field 계열 옵션 키:
- InputField → input
- CheckboxField → checkbox
- SwitchField → swtich (!) — 버그성 오타 잔재
4. 이벤트
Switch의 이벤트를 재발화 + Field 표준:
이벤트시그니처발생 시점
| change | (component, element, checked, evt) | 스위치 토글 시. checked가 새 상태값 |
| click | (component, element, evt) | 클릭 시 |
| keydown | (component, element, keyCode, evt) | 스페이스로 토글 시 |
| keyup | (component, element, keyCode, evt) | 키업 |
| focus / blur | (component, element, evt) | 포커스 진입/이탈 |
change 콜백 예시
onNotifChange(comp, el, checked, evt) {
console.log('알림 상태:', checked); // true / false
NotifService.setEnabled(this, checked); // 즉시 서버 반영
}
Switch UX 관행 유지: change 즉시 서버 반영. 저장 버튼 없이 실시간 반영이 자연스러움.
5. 메서드
상태 조회·변경
메서드설명
| getChecked() | 현재 값 반환. valueType 규약 반영 |
| setChecked(value) | 상태 세팅 |
| check() | ON으로 세팅 (편의) |
| uncheck() | OFF로 세팅 (편의) |
상태 (Field 상속)
메서드설명
| setDisabled(bool) / getDisabled() | 비활성화 |
| setReadOnly(bool) / setReadonly(bool) | 읽기 전용 |
| setLabel(label) | 폼 라벨 변경 |
| setSize(size) | 크기 |
검증
메서드설명
| setValidation(state, message) | 검증 표시 |
| clearValidation() | 검증 해제 |
포커스
메서드설명
| focus() / blur() | 내부 Switch에 위임 |
⚠️ getChecked()의 valueType: '10' 반환값 — 문자열 '1'/'0' 반환 (va_component.js:10612, 10614). Switch 원본은 숫자 1/0. CheckboxField와 같은 미묘한 차이 (Field 계열은 문자열 통일 경향).
6. 내부 구조
<div elname="element" class="va-field [vertical|horizontal]" field="true">
<div elname="inner" class="field-inner">
<div elname="labelDiv" class="label-div">
<label cpname="label">알림 <span class="required">*</span></label>
</div>
<div elname="comment" class="field-comment"></div>
<div elname="fieldDiv" class="field-div">
<div cpname="field" class="va-switch [checked]"> ← 내부 Va.Switch
<div class="switch-inner">
<div class="field-wrapper">
<input type="checkbox" role="switch"
tabindex="0" aria-checked="true|false">
<div class="switch-div">
<div class="thumb"></div> ← 슬라이드 원
</div>
</div>
</div>
</div>
</div>
</div>
<div elname="validationDiv" style="display:none">
<div class="va-validation">...</div>
</div>
</div>
7. 언제 쓰나
SwitchField가 맞을 때
- 설정 화면의 ON/OFF (알림, 다크모드, 자동저장)
- 즉시 반영되는 상태 필드 (라벨과 함께)
- 정렬된 설정 리스트 (좌측 라벨, 우측 스위치)
- 필수 활성화가 필요한 옵션 (required: true)
다른 걸 쓸 때
- 라벨 없이 인라인 → Va.Switch
- 폼 안 동의 (저장 시 반영) → Va.CheckboxField
- 다중 선택 → Va.CheckboxGroupField
- 배타 선택 → Va.RadioGroupField
- 툴바 상태 토글 → Va.ToggleButton
8. 흔한 조합 예시
// 표준
{
tagName: 'switchField',
label: '푸시 알림',
checked: true,
onChange: 'onPushToggle'
}
// Y/N (DB 스키마)
{
tagName: 'switchField',
label: '이메일 수신',
valueType: 'YN',
checked: 'Y'
}
// 좌측 라벨 (설정 화면 관행)
{
tagName: 'switchField',
label: '다크 모드',
labelPosition: 'left',
labelWidth: 150,
checked: false
}
// info 툴팁
{
tagName: 'switchField',
label: '자동 저장',
infoButton: {
tooltip: '30초마다 자동으로 저장됩니다'
},
checked: true
}
// 폼 라벨 숨김 (스위치만)
{
tagName: 'switchField',
noLabel: true,
checked: true
}
9. 실전 예 — 알림 설정 (SwitchField 조합)
class NotificationSettings extends Va.View {
async mounted() {
const res = await SettingsService.get(this);
if (res.result) {
this.getRef('push').setChecked(res.data.pushEnabled);
this.getRef('email').setChecked(res.data.emailEnabled);
this.getRef('sms').setChecked(res.data.smsEnabled);
this.getRef('marketing').setChecked(res.data.marketing);
}
}
onPushToggle(comp, el, checked, evt) {
SettingsService.setPush(this, checked, (view, ok) => {
if (!ok) comp.setChecked(!checked); // 실패 시 롤백
});
}
onEmailToggle(comp, el, checked, evt) {
SettingsService.setEmail(this, checked);
}
onSmsToggle(comp, el, checked, evt) {
SettingsService.setSms(this, checked);
}
onMarketingToggle(comp, el, checked, evt) {
// 마케팅 동의는 확인 필요
if (checked) {
new Va.Confirm({
title: '마케팅 정보 수신',
message: '수신에 동의하시겠습니까?'
}).show(this, (ok) => {
if (ok) SettingsService.setMarketing(this, true);
else comp.setChecked(false);
});
} else {
SettingsService.setMarketing(this, false);
}
}
config() {
return {
tagName: 'page',
tags: [{
tagName: 'panel',
tags: [
{ tagName: 'h2', innerHTML: '알림 설정' },
{
tagName: 'switchField',
ref: 'push',
label: '푸시 알림',
labelPosition: 'left',
labelWidth: 200,
onChange: 'onPushToggle'
},
{
tagName: 'switchField',
ref: 'email',
label: '이메일 알림',
labelPosition: 'left',
labelWidth: 200,
onChange: 'onEmailToggle'
},
{
tagName: 'switchField',
ref: 'sms',
label: 'SMS 알림',
labelPosition: 'left',
labelWidth: 200,
onChange: 'onSmsToggle'
},
{
tagName: 'switchField',
ref: 'marketing',
label: '마케팅 정보 수신',
labelPosition: 'left',
labelWidth: 200,
infoButton: { tooltip: '이벤트 및 프로모션 정보를 받습니다' },
onChange: 'onMarketingToggle'
}
]
}]
};
}
}
SwitchField의 UX:
- 좌측 라벨, 우측 스위치 정렬 (labelPosition: 'left')
- 토글 즉시 서버 반영
- 실패 시 자동 롤백
- 저장 버튼 없음
10. 알아두면 좋을 주의사항
- 옵션 키가 swtich — 오타지만 코드가 이 키를 씀. 세부 커스터마이즈 시 이 키 사용.
- checked 인식 형태 다양 — true/'Y'/1 등 모두 켜짐.
- getChecked()가 valueType 규약 반영 — '10'은 문자열 '1'/'0' 반환.
- change 즉시 반영이 UX 관행 — 저장 버튼 안 씀. 실패 시 롤백 로직 필수.
- 자체 스위치 옆 라벨 없음 — checkboxLabel/radioLabel 같은 옵션 없음. Field의 label만 활용.
- 3상 상태(mixed) 없음 — Switch가 지원 안 함.
- role="switch" 자동 — 접근성 좋음.
- focus()는 내부 Switch에 위임 — <input>에 포커스.
- preventParentFieldEvent: true 강제 (Switch 생성자) — 부모 Field 이벤트 개입 방지.
- required: true는 별표 표시만 — 실제 검증은 개발자가 처리 (스위치를 켜지 않고 제출하는 상황).
11. switchField vs checkboxField 선택 원칙
상황추천
| 설정 화면 ON/OFF (즉시 반영) | switchField |
| 폼 안 동의 (제출 버튼으로 반영) | checkboxField |
| 필수 활성화 항목 (활성 전엔 진행 불가) | switchField + 별도 검증 |
| 여러 옵션 다중 선택 | checkboxGroupField |
| 모바일 앱 스타일 UI | switchField |
| 약관 동의 | checkboxField |
"즉시 반영되면 switchField, 폼 저장 시 반영되면 checkboxField" — 이 원칙만 지키면 됩니다.
참고
- API 문서 페이지: https://vanillafront.com/docs.html?theme=light#main#apiswitchfield
- 연관: Va.Switch(내부), Va.CheckboxField(대체 가능한 폼 저장형)
'컴포넌트 > 필드 컴포넌트' 카테고리의 다른 글
| TextareaField (텍스트영역필드) (0) | 2026.09.13 |
|---|---|
| Textarea (텍스트영역) (0) | 2026.09.13 |
| Switch (스위치) (0) | 2026.09.13 |
| StarSliderField (스타슬라이더필드) (0) | 2026.09.13 |
| StarSlider (스타슬라이더) (0) | 2026.09.13 |