RadioGroupField (라디오그룹 필드)
Va.RadioGroupField — 라벨 + 배타 선택 라디오 그룹
Va.RadioGroup이 순수 배타 선택 그룹이라면, Va.RadioGroupField는 그 위에 폼 라벨·필수 표시·검증 메시지를 얹은 완성 폼 필드입니다. Field 계열 아키텍처 그대로, 내부에 Va.RadioGroup을 소유하는 Composition 구조. 실무에서 라디오를 쓸 때 가장 자주 만나게 되는 컴포넌트.
- 클래스: Va.RadioGroupField — va_component.js:11343
- short name: radioGroupField
- 상속: Va.Field (다른 Field 형제들과 같음)
- 내부 컴포넌트: Va.RadioGroup 인스턴스 (fieldComponent)
- isContainer: true
- 베이스 CSS: va-radio-group-field

1. 기본 사용
{
tagName: 'radioGroupField',
label: '결제 방식',
key: 'code',
display: 'name',
data: [
{ code: 'CARD', name: '신용카드', checked: true },
{ code: 'BANK', name: '계좌이체' },
{ code: 'PHONE', name: '휴대폰 결제' }
],
required: true,
onChange: 'onPaymentChange'
}
라벨 + 검증 + 배타 선택 라디오들이 한 번에 세팅. 값은 선택된 하나의 key로 다룹니다.
2. Field 계열에서의 위치
Va.Field
├─ Va.InputField ← Va.Input
├─ Va.CheckboxField ← Va.Checkbox (단일)
├─ Va.CheckboxGroupField ← Va.CheckboxGroup (다중)
├─ Va.RadioField ← Va.Radio (단일)
├─ Va.RadioGroupField ← Va.RadioGroup (배타) ← 이 문서
└─ ...
RadioGroupField의 정체: Field 베이스 + 내부에 Va.RadioGroup 인스턴스.
3. RadioGroup / 다른 Field와의 차이
항목Va.RadioGroupVa.RadioGroupFieldVa.CheckboxGroupField
| 폼 라벨 | ✕ | ✓ | ✓ |
| 검증 메시지 | ✕ | ✓ | ✓ |
| info 툴팁 | ✕ | ✓ | ✓ |
| 필수 표시(별표) | ✕ | ✓ | ✓ |
| 선택 개수 | 1개 (배타) | 1개 (배타) | N개 (다중) |
| 값 형태 | 단일 key | 단일 key | key 배열 |
| 자체 배타 로직 | ✓ | ✓ (내부 위임) | — |
| 상속 | Component | Field | Field |
한 줄 요약: "폼 안 라벨 붙은 배타 선택 라디오 그룹."
4. 주요 속성
데이터 관련 (RadioGroup 계승)
속성기본값설명
| data | — | 옵션 배열. 각 항목 { [key], [display], checked } |
| key | 'key' | 값 필드명 |
| display | 'display' | 표시 필드명 |
배치·상태
속성기본값설명
| direction | 'horizontal' | 'horizontal'(가로) / 'vertical'(세로) |
| radioLabelClick | true | 라디오 옆 라벨 클릭으로 선택 가능 |
| readonly / disabled | — | 상태 (자식 전체에 전파) |
| size | — | 크기 |
라벨 관련 (Field 상속)
속성설명
| label | 폼 라벨 |
| labelPosition | top / bottom / left / right |
| labelWidth | 라벨 폭 |
| noLabel | 폼 라벨 숨김 |
| infoButton | info 아이콘 |
| required | 필수 표시 |
검증
속성설명
| validation | {state, size, message} |
| validationState | success / warning / error |
| validationMessage | 메시지 |
세부 커스터마이즈 (radioGroup 옵션 키)
{
tagName: 'radioGroupField',
label: '결제 방식',
radioGroup: { // ← 내부 RadioGroup에 직접 전달
stopPropagation: false
}
}
각 Field 계열 옵션 키:
- InputField → input
- CheckboxField → checkbox
- CheckboxGroupField → checkboxGroup
- RadioField → radio
- RadioGroupField → radioGroup
5. 이벤트
이벤트시그니처발생 시점
| change | (component, element, value, evt) | 라디오 선택 시. value는 선택된 항목의 key |
| click | (component, element, value, evt) | 클릭 시. value는 클릭된 항목의 key |
change 콜백 예시
onPaymentChange(comp, el, value, evt) {
console.log('선택됨:', value); // 'CARD' / 'BANK' / 'PHONE'
if (value === 'CARD') {
this.getRef('cardInfo').setDisplay('flex');
}
}
RadioGroup과 동일하게 change/click의 세 번째 인자가 선택된 key. 배타 선택이라 그것이 곧 "현재 값".
이벤트 목록이 매우 짧음 — 소스에 this.events = ['change']만 명시. focus/blur 등 표준 Field 이벤트가 재발화 목록에 없어, 필요하면 component.fieldComponent에 직접 리스너 붙여야 합니다.
6. 메서드 (RadioGroup 위임)
값 조회·세팅
메서드설명
| getValue() | 선택된 항목의 단일 key 반환. 아무것도 선택 안 됐으면 null |
| setValue(key) | 해당 key를 가진 항목 선택 (배타 로직 자동) |
| getDisplay() | 선택된 항목의 display 배열 (실제로는 원소 하나) |
| getDisplayAsText() | display를 한 줄 문자열로 |
데이터 관리
메서드설명
| setData(data) | 데이터 전체 교체 |
| getData() | 현재 데이터 반환 |
| addData(item) | 항목 추가 (기본 체크됨 — 배타 주의) |
| insertData(item, index) | 특정 위치에 삽입 |
| append(component) | 프로그램적으로 라디오 자식 추가 |
상태
메서드설명
| setDisabled(bool) | 자식 전체 비활성화 |
| setReadOnly(bool) | 자식 전체 읽기 전용 |
검증
메서드설명
| setValidation(state, message) | 검증 표시 + aria |
| clearValidation() | 검증 해제 |
주의: focus() 편의 메서드 없음. 첫 라디오에 포커스 주려면 component.fieldComponent.getChildComponents()[0].focus() 우회.
7. 내부 구조
<div elname="element" class="va-field va-radio-group-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-radio-group [horizontal|vertical]">
← 내부 Va.RadioGroup
<div class="radio-group-inner">
<div class="va-radio">…</div>
<div class="va-radio">…</div>
<!-- 자식 라디오들 -->
</div>
</div>
</div>
</div>
<div elname="validationDiv" style="display:none">
<div class="va-validation">...</div>
</div>
</div>
두 개의 방향 축 각각 존재:
- labelPosition — 폼 라벨의 위치 (Field 담당)
- direction — 그룹 안 라디오 배치 방향 (RadioGroup 담당)
두 옵션을 자유롭게 조합할 수 있습니다.
8. update()의 200ms 지연
CheckboxGroupField와 동일한 특성. update()에서 상태 반영이 _setTimer('update', ..., 200)으로 감싸져 200ms 후 실행 (va_component.js:11401-11407).
this._setTimer('update', ()=>{
this.fieldComponent.setReadOnly(this.readonly);
this.fieldComponent.setDisabled(this.disabled);
...
}, 200)
실무적 함의:
- setReadOnly() / setDisabled() 호출 후 즉시 UI에 반영되지 않을 수 있음
- 연속 호출 시 마지막 것만 반영됨 (_setTimer 특성)
프로그램적으로 상태 바꾸고 바로 다른 로직 진행할 때 이 지연을 인지하세요.
9. 언제 쓰나
RadioGroupField가 맞을 때
- 폼 안 배타 선택 필드 (성별, 결제 방식, 등급, 배송 방식)
- 항목 2~5개 정도
- 라벨·필수·검증이 필요할 때
- 서버에서 받은 동적 옵션 목록
다른 걸 쓸 때
- 라벨 없이 인라인 → Va.RadioGroup
- 여러 선택 → Va.CheckboxGroupField
- 항목 6개 이상 → Va.ComboboxField (드롭다운)
- 세그먼트 UI → Va.SegmentedControl
- 단일 on/off → Va.CheckboxField / Va.SwitchField
10. 흔한 조합 예시
// 표준
{
tagName: 'radioGroupField',
label: '결제 방식',
key: 'code',
display: 'name',
data: [
{ code: 'CARD', name: '신용카드', checked: true },
{ code: 'BANK', name: '계좌이체' }
],
required: true,
onChange: 'onPaymentChange'
}
// 세로 배치
{
tagName: 'radioGroupField',
label: '요금제',
key: 'code',
display: 'name',
direction: 'vertical',
data: [
{ code: 'BASIC', name: '기본 - 월 9,900원' },
{ code: 'PREMIUM', name: '프리미엄 - 월 19,900원' }
]
}
// 좌측 라벨 (폼 정렬)
{
tagName: 'radioGroupField',
label: '성별',
labelPosition: 'left',
labelWidth: 100,
key: 'code',
display: 'name',
data: [
{ code: 'M', name: '남성' },
{ code: 'F', name: '여성' }
]
}
// info 툴팁
{
tagName: 'radioGroupField',
label: '수신 방식',
infoButton: {
tooltip: '알림을 받을 방식을 선택하세요'
},
key: 'code',
display: 'name',
data: [ ... ]
}
// 서버에서 데이터 로드
mounted() {
OptionService.list(this, {}, (view, ok, res) => {
if (ok) view.getRef('opt').setData(res.data.list);
});
}
// 초기값 프로그램적 세팅
this.getRef('opt').setValue('BANK');
// 검증
onSubmit() {
const method = this.getRef('payment').getValue();
if (method == null) {
this.getRef('payment').setValidation('error', '결제 방식을 선택하세요');
return;
}
this.getRef('payment').clearValidation();
// ...
}
11. 실전 예 — 회원가입 요금제 선택
class Signup extends Va.View {
async mounted() {
// 사용 가능한 요금제 로드
const res = await PlanService.list(this);
if (res.result) {
this.getRef('plan').setData(res.data.list);
}
}
onPlanChange(comp, el, value, evt) {
// 요금제에 따라 상세 정보 표시
const plan = this.getRef('plan').getData().find(p => p.code === value);
if (plan) {
this.getRef('detail').setValue(plan.description);
}
}
onSubmit(btn, el, evt) {
const plan = this.getRef('plan').getValue();
if (plan == null) {
this.getRef('plan').setValidation('error', '요금제를 선택하세요');
return;
}
this.getRef('plan').clearValidation();
SignupService.register(this, { plan }, (view, ok) => {
if (ok) new Va.Alert({ title: '완료', message: '가입 완료' }).show(view);
});
}
config() {
return {
tagName: 'page',
tags: [{
tagName: 'panel',
tags: [
{ tagName: 'h2', innerHTML: '요금제 선택' },
{
tagName: 'radioGroupField',
ref: 'plan',
label: '요금제',
key: 'code',
display: 'name',
direction: 'vertical',
required: true,
onChange: 'onPlanChange'
},
{
tagName: 'inputField',
ref: 'detail',
label: '요금제 설명',
readonly: true
},
{
tagName: 'button',
text: '가입 완료',
appearance: 'primary',
onClick: 'onSubmit'
}
]
}]
};
}
}
12. 알아두면 좋을 주의사항
- getValue()는 단일 key — CheckboxGroupField(배열)와 다름. null 반환 가능.
- setValue(key)가 자동 배타 처리 — 다른 항목 자동 해제.
- change/click의 세 번째 인자는 선택된 key — 그대로 사용 가능.
- 이벤트 목록이 ['change']만 명시 — focus/blur 등 표준 Field 이벤트 재발화 안 됨.
- update()가 200ms 지연 — setReadOnly/setDisabled 즉시 반영 안 됨.
- addData는 새 항목이 자동으로 체크됨 — 배타 로직 상 기존 선택이 해제될 수 있음.
- getDisplay()는 배열 반환 — 이름과 달리 배열. [0] 접근이나 getDisplayAsText() 사용.
- 검증 자동 리셋 없음 — change 후 명시적으로 clearValidation() 호출 필요할 수 있음.
- 폼 라벨과 그룹 방향 독립 — labelPosition: 'left' + direction: 'vertical' 조합 가능.
- focus() 편의 메서드 없음 — 자식 첫 번째에 포커스 주려면 우회.
- HTML name 자동 그룹핑 — 표준 폼 서브밋에서도 배타.
- removeData/modifyData 없음 — 전체 교체는 setData().
13. radioGroupField vs checkboxGroupField vs comboboxField 선택
상황추천
| 여러 옵션 중 하나만 선택 (2~5개) | radioGroupField |
| 여러 옵션 중 여러 개 | checkboxGroupField |
| 옵션 6개 이상 | comboboxField (드롭다운) |
| 세그먼트 UI (붙어있는 버튼) | segmentedControl |
| 단일 on/off | checkboxField / switchField |
"옵션 2~5개 배타 선택은 radioGroupField, 그 이상은 comboboxField" — 기본 원칙.
참고
- API 문서 페이지: https://vanillafront.com/docs.html?theme=light#main#apiradiogroupfield
- 연관: Va.RadioGroup(내부), Va.CheckboxGroupField(대응 다중 선택 버전)