컴포넌트/필드 컴포넌트

ComboboxField (콤보박스필드)

VanillaFront 2026. 9. 10. 15:17

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

ComboboxField
ComboboxField 다중선택


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. 알아두면 좋을 주의사항

  1. getValue() 반환 타입 — single이면 문자열/숫자, multiSelect면 배열.
  2. setValue()는 데이터에 있어야 반영 — data에 없는 key를 세팅하면 무시.
  3. select 이벤트 인자 7개  (component, element, listItem, data, key, display, evt). 필요한 것만.
  4. select 이벤트 dispatch가 두 번 — 소스 va_component.js:5673-5675에서 한 번, 내부 Combobox에서도 한 번. 콜백 중복 실행 조심.
  5. 바인딩은 옵션이 있을 때만 자동 등록  bindParams/bindCallbackKeys/bindCallbackClearKeys 중 하나라도 있으면 자동 이벤트 리스너 부착.
  6. autoSetFieldValue: false 강제 — Combobox 로직에 맞춤.
  7. addCheckAll은 multiSelect일 때만 — single에선 무시.
  8. 팝업이 hiddenArea로 이동 — 부모 overflow/z-index 영향 없음.
  9. 가상 스크롤 자동 — 대량 데이터도 부드러움.
  10. _hiddenRootElement가 popElement — 팝업 auto-hide/other-components 로직 참여.
  11. 템플릿 자동 생성 — 지정 안 하면 display 필드만 있는 심플 리스트로 자동. multiSelect면 checkbox 자동 포함.
  12. focus() 위임 — Combobox의 fieldElement에 포커스. 팝업 자동 열기는 아님.
  13. 바인딩 필드 참조는 ref 이름 문자열로 — 부모 뷰 안의 다른 필드의 ref 이름을 매핑.
  14. 옵션 키가 combobox — 다른 Field 형제들과 헷갈리지 말 것.