ComboboxField (콤보박스필드)
Va.ComboboxField — 라벨 + 검색·다중선택·바인딩까지 감싼 완성 폼 필드
Va.Combobox가 순수 드롭다운이라면, Va.ComboboxField는 그 위에 라벨·검증·설명 + 부모-자식 필드 바인딩까지 얹은 "완성된 폼 콤보박스" 입니다. Field 계열 중에서 가장 많은 속성과 메서드를 갖는 컴포넌트로, 실무 폼에서 가장 자주 씁니다.
- 클래스: Va.ComboboxField — va_component.js:5555
- short name: comboboxField
- 상속: Va.Field (InputField·NumberField 등과 형제)
- 내부 컴포넌트: Va.Combobox 인스턴스 (fieldComponent)
- isContainer: true
- 베이스 CSS: va-combobox-field


1. 기본 사용
{
tagName: 'comboboxField',
label: '부서',
value: 'D01',
data: [
{ key: 'D01', display: '개발팀' },
{ key: 'D02', display: '기획팀' },
{ key: 'D03', display: '영업팀' }
],
required: true,
onSelect: 'onDeptSelect'
}
라벨 + 검증 + 팝업 드롭다운이 한 번에 세팅. Field 3형제(InputField, SearchField, NumberField)와 같은 패턴이지만, 바인딩 옵션이 훨씬 많아 실무 폼에 최적화되어 있습니다.
2. Field 계열에서의 위치
Va.Field
├─ Va.InputField ← Va.Input
├─ Va.SearchField ← Va.Search
├─ Va.NumberField ← Va.Number
├─ Va.ComboboxField ← Va.Combobox ← 이 문서
├─ Va.FilterboxField ← Va.Filterbox (필터 강화 버전)
└─ ...
ComboboxField의 정체: Field 베이스 + 내부에 Va.Combobox 인스턴스 + 부모-자식 필드 바인딩 로직 추가.
3. Va.Combobox / 다른 Field와의 차이
항목Va.ComboboxVa.ComboboxFieldVa.InputField
| 라벨 | ✕ | ✓ | ✓ |
| 검증 메시지 | ✕ | ✓ | ✓ |
| info 툴팁 | ✕ | ✓ | ✓ |
| 팝업 드롭다운 | ✓ | ✓ (내부 위임) | ✕ |
| 다중 선택 | ✓ | ✓ | ✕ |
| 템플릿 렌더링 | ✓ | ✓ | ✕ |
| bindParams (부모 필드 바인딩) | ✓ | ✓ (자동 이벤트 연결) | ✕ |
| bindCallbackKeys (자식 필드 자동 채움) | ✓ | ✓ (자동 이벤트 연결) | ✕ |
| commonCode / dynamicCode | ✓ | ✓ | ✕ |
| 속성 개수 | 많음 | 가장 많음 | 적음 |
4. 주요 속성 — Combobox 옵션 + Field 옵션 + 바인딩 옵션
Combobox의 모든 속성을 그대로 지원하고, 그 위에 Field 라벨 옵션과 부모-자식 바인딩 옵션을 추가합니다.
데이터 관련 (Combobox 계승)
속성기본값설명
| data | — | 항목 배열 |
| fakeData | — | 에디터 미리보기 데이터 |
| key | 'key' | 값 필드명 |
| display | 'display' | 표시 필드명 |
| displayType | 'display' | key / display / both |
| template | 자동 생성 | 항목 렌더 템플릿 |
| dataMode | 'data' | 데이터 소스 모드 |
선택 동작
속성기본값설명
| value | — | 현재 선택 값 |
| multiSelect | false | 다중 선택 |
| addCheckAll | — | "전체" 체크박스 (multiSelect일 때) |
| clickToSelect | true | 클릭으로 선택 |
| commonBlankKey | — | "빈 값" 옵션 key |
| editable | false | 자유 입력 허용 |
| autoSetFieldValue | false | 필드 값 자동 세팅 (Combobox처럼 false 강제) |
| getValueType | — | 값 반환 타입 조정 |
| fromValue / toValue | — | 범위 옵션 |
팝업
속성기본값설명
| expanded | false | 팝업 초기 상태 |
| popWidth | 자동 | 팝업 폭 |
| popMaxHeight | '400px' | 팝업 최대 높이 |
라벨 (Field 상속)
속성설명
| label | 라벨 텍스트 또는 객체 |
| labelPosition | top / bottom / left / right |
| labelWidth | 라벨 폭 |
| noLabel | 라벨 숨김 |
| infoButton | info 아이콘 |
| required | 필수 표시 |
검증
속성설명
| validation | {state, size, message} |
| validationState | success / warning / error |
| validationMessage | 메시지 |
바인딩 (ComboboxField의 진짜 강점)
속성설명
| bindParams | 팝업 열기 전 부모 필드 값들을 파라미터로 자동 수집 |
| bindRequired | 바인딩된 필드가 비어 있으면 팝업 열지 않음 |
| bindCallbackKeys | 선택 후 다른 필드에 값을 자동 세팅 (예: 부서 선택 → 팀장 필드 자동 채움) |
| bindCallbackClearKeys | 선택 후 다른 필드 값을 자동 비움 |
| commonCode | 공통 코드 마스터 데이터 로드 |
| dynamicCode | 동적 코드 (파라미터 기반) 로드 |
세부 커스터마이즈 (combobox 옵션 키)
{
tagName: 'comboboxField',
label: '카테고리',
combobox: { // ← 내부 Combobox에 직접 전달
rowHeight: 40,
pageSize: 50
}
}
각 Field 계열 옵션 키:
- InputField → input
- SearchField → search
- NumberField → number
- ColorField → colorPicker
- ComboboxField → combobox
5. 이벤트
Combobox의 이벤트를 모두 재발화:
이벤트시그니처발생 시점
| select | (component, element, listItem, data, key, display, evt) | 항목 선택 시 — 가장 자주 씀 |
| beforePop / afterPop | 팝업 표시 직전/직후 | |
| hidePop | 팝업 숨김 요청 | |
| expand / collapse | 팝업 확장/축소 | |
| focus / blur | 표준 | |
| change / click / keydown / keyup | Field 표준 (검증 자동 리셋 포함) |
자동 바인딩 이벤트
bindParams / bindCallbackKeys 옵션이 있으면 자동으로 이벤트가 걸립니다 (va_component.js:5684-5703):
- expand 시 → getBindParams(this) 호출 → 팝업 열기 전에 부모 값 수집
- collapse 시 → setCallbackKeys(this, this.getSelectedData()) 호출 → 다른 필드 자동 채움/비움
6. 메서드
값
메서드설명
| getValue() | 선택된 값 (single이면 문자열/숫자, multi면 배열) |
| setValue(value) | 값 세팅 (ignoreBindParams 자동 처리) |
| getDisplay() | 표시 텍스트 반환 |
| getDisplayAsText() | 표시를 순수 텍스트로 반환 |
데이터 (Combobox 위임)
메서드설명
| setData(data) | 데이터 교체 |
| getData() | 데이터 배열 |
| getSelectedData() | 선택된 항목의 전체 객체 |
| addData(data) / insertData(data, refData) | 추가/삽입 |
| modifyData(data, cls) | 수정 |
| removeData(data) / removeDataByKey(key) | 제거 |
| moveData(data, beforeData) | 이동 |
| select(data) | 프로그램적으로 특정 데이터 선택 |
| selectFirstData(eventOccur) | 첫 항목 자동 선택 (자주 씀) |
| focusFirstData(eventOccur) | selectFirstData 별칭 |
| applyData() | 데이터 반영 트리거 |
| getDataById(vaDataId) | 내부 ID로 데이터 조회 |
| getDataByListItem(listItem) / getListItemByData(data) | ListItem ↔ Data 상호 조회 |
상태 (Field 상속)
메서드설명
| setDisabled(bool) / getDisabled() | 비활성화 |
| setReadOnly(bool) / setReadonly(bool) | 읽기 전용 |
| setLabel(label) | 라벨 변경 |
| setPlaceholder(text) | 플레이스홀더 |
| setSize(size) | 크기 |
검증
메서드설명
| setValidation(state, message) | 검증 표시 + aria 자동 |
| clearValidation() | 검증 해제 |
바인딩
메서드설명
| getBindParams(component) | 부모 필드 값 수집 (Combobox 위임) |
| setCallbackKeys(component, data) | 자식 필드 자동 채움 |
포커스
메서드설명
| focus() / blur() | 내부 Combobox 위임 |
7. 바인딩 시스템 — ComboboxField의 킬러 기능
폼에서 필드 하나가 다른 필드와 연동될 때 자주 필요한 두 방향:
bindParams — "선택하기 전에 다른 필드 값을 사용"
{
// 부모 필드
tagName: 'comboboxField',
label: '회사',
ref: 'company',
data: [...]
},
{
// 자식 필드 — 회사가 선택되어야 부서 목록이 결정됨
tagName: 'comboboxField',
label: '부서',
ref: 'dept',
bindParams: {
companyCode: 'company' // 팝업 열 때 'company' 필드 값이 파라미터로 전달됨
},
bindRequired: true, // company가 비어 있으면 팝업 안 열림
dynamicCode: 'DEPT_LIST' // 서버에 companyCode 넘겨 부서 목록 조회
}
동작: 사용자가 부서 콤보를 클릭 → expand 이벤트 → getBindParams() 자동 호출 → company 값을 파라미터로 서버 조회 → 팝업에 부서 목록 표시.
bindCallbackKeys — "선택 후 다른 필드에 자동 채움"
{
tagName: 'comboboxField',
label: '직원',
data: [
{ key: 'E01', display: '홍길동', dept: '개발팀', email: 'hong@ex.com' }
],
bindCallbackKeys: {
deptDisplay: 'dept', // 선택한 항목의 dept를 'deptDisplay' 필드로
emailField: 'email' // 선택한 항목의 email을 'emailField' 필드로
}
}
동작: 사용자가 직원 선택 → collapse 이벤트 → setCallbackKeys() 자동 호출 → 선택된 데이터의 dept, email 값이 대응하는 다른 필드에 자동 세팅.
bindCallbackClearKeys — "선택 후 다른 필드 자동 비우기"
bindCallbackClearKeys: ['dependentField1', 'dependentField2']
값이 바뀌면 하위 종속 필드들의 값을 리셋할 때 사용.
이 세 옵션이 폼 필드 간 연쇄 로직을 컴포넌트 옵션 하나로 선언적으로 표현하게 해줍니다.
8. 내부 구조
<div elname="element" class="va-field va-combobox-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-input"> ← 내부 Va.Combobox
<div class="field-wrapper" role="combobox" aria-expanded="false">
<input type="text" style="border:0px">
<div class="focus-line"></div>
<div class="va-combobox-dropdown">▼</div>
</div>
<!-- 팝업은 hiddenArea로 이동됨 -->
</div>
</div>
</div>
<div elname="validationDiv" style="display:none">
<div class="va-validation">...</div>
</div>
</div>
9. 언제 쓰나
ComboboxField가 맞을 때
- 폼 안의 표준 선택 필드 (부서·카테고리·상태·국가)
- 라벨과 함께 필수 표시·검증이 필요할 때
- 부모 필드 값에 따라 자식 필드 목록이 바뀌는 연쇄 폼 (bindParams)
- 선택 후 다른 필드를 자동 채우는 UX (bindCallbackKeys)
- 공통 코드/동적 코드 마스터 사용 (commonCode / dynamicCode)
- 다중 선택 + 검증이 필요한 필터 필드
다른 걸 쓸 때
- 라벨 없는 인라인 → Va.Combobox
- 텍스트로 필터 검색 강화 → Va.FilterboxField
- 라디오형 5개 이하 선택 → Va.RadioGroupField
- 자유 텍스트 입력 → Va.InputField
- 트리 구조 선택 → Va.TreeGridField (있다면) 또는 Va.TreeGrid 팝업
10. 흔한 조합 예시
// 표준 사용
{
tagName: 'comboboxField',
label: '상태',
data: [
{ key: 'ACTIVE', display: '활성' },
{ key: 'INACTIVE', display: '비활성' }
],
value: 'ACTIVE'
}
// 다중 선택 필터
{
tagName: 'comboboxField',
label: '카테고리',
multiSelect: true,
addCheckAll: true,
data: [...]
}
// 부모-자식 바인딩
{
tagName: 'comboboxField',
label: '지역',
ref: 'region',
data: [...]
},
{
tagName: 'comboboxField',
label: '지점',
bindParams: { regionCode: 'region' },
bindRequired: true,
dynamicCode: 'BRANCH_BY_REGION'
}
// 선택 후 다른 필드 자동 채움
{
tagName: 'comboboxField',
label: '제품',
data: [
{ key: 'P1', display: '노트북', price: 1500000, stock: 20 }
],
bindCallbackKeys: {
priceField: 'price',
stockField: 'stock'
}
}
// 커스텀 템플릿 (아이콘 + 설명)
{
tagName: 'comboboxField',
label: '사용자',
template: {
tagName: 'listItem',
layout: 'ds-flex fd-row ai-center gap-s',
tags: [
{ tagName: 'avatar', size: 24, src: '{avatar}' },
{ tagName: 'div', innerHTML: '{name}' },
{ tagName: 'div', innerHTML: '{email}', style: 'color:gray' }
]
},
data: [...]
}
// 좌측 라벨 + 정렬
{
tagName: 'comboboxField',
label: '분류',
labelPosition: 'left',
labelWidth: 100,
required: true,
data: [...]
}
// 팝업 넓게
{
tagName: 'comboboxField',
label: '상세 항목',
popWidth: 500,
popMaxHeight: '600px',
data: [...]
}
11. 알아두면 좋을 주의사항
- getValue() 반환 타입 — single이면 문자열/숫자, multiSelect면 배열.
- setValue()는 데이터에 있어야 반영 — data에 없는 key를 세팅하면 무시.
- select 이벤트 인자 7개 — (component, element, listItem, data, key, display, evt). 필요한 것만.
- select 이벤트 dispatch가 두 번 — 소스 va_component.js:5673-5675에서 한 번, 내부 Combobox에서도 한 번. 콜백 중복 실행 조심.
- 바인딩은 옵션이 있을 때만 자동 등록 — bindParams/bindCallbackKeys/bindCallbackClearKeys 중 하나라도 있으면 자동 이벤트 리스너 부착.
- autoSetFieldValue: false 강제 — Combobox 로직에 맞춤.
- addCheckAll은 multiSelect일 때만 — single에선 무시.
- 팝업이 hiddenArea로 이동 — 부모 overflow/z-index 영향 없음.
- 가상 스크롤 자동 — 대량 데이터도 부드러움.
- _hiddenRootElement가 popElement — 팝업 auto-hide/other-components 로직 참여.
- 템플릿 자동 생성 — 지정 안 하면 display 필드만 있는 심플 리스트로 자동. multiSelect면 checkbox 자동 포함.
- focus() 위임 — Combobox의 fieldElement에 포커스. 팝업 자동 열기는 아님.
- 바인딩 필드 참조는 ref 이름 문자열로 — 부모 뷰 안의 다른 필드의 ref 이름을 매핑.
- 옵션 키가 combobox — 다른 Field 형제들과 헷갈리지 말 것.