Va.NumberField — 라벨 + 숫자 입력 + 검증까지 감싼 폼 필드
Va.Number가 순수 숫자 입력이라면, Va.NumberField는 그 위에 라벨·필수 표시·검증 메시지·설명 텍스트를 얹은 "완성된 숫자 폼 필드" 입니다. Field 계열의 3형제(InputField, SearchField, NumberField)와 같은 아키텍처를 따르되, 내부에 Va.Number를 소유합니다.
- 클래스: Va.NumberField — va_component.js:5494
- short name: numberField
- 상속: Va.Field (InputField·SearchField와 형제)
- 내부 컴포넌트: Va.Number 인스턴스를 자식으로 소유 (fieldComponent)
- isContainer: true
- 베이스 CSS: va-field

1. 기본 사용
{
tagName: 'numberField',
label: '수량',
value: 10,
min: 0,
max: 100,
step: 1,
required: true,
onChange: 'onQtyChange'
}
라벨 · 필드 · 검증 영역이 자동 세팅되고, 내부 <input type="number">가 스피너까지 제공.
2. Field 3형제와의 위치
세 Field 컴포넌트가 완전히 같은 패턴으로 만들어져 있어 한 번에 정리:
Va.Field
├─ Va.InputField ← 내부에 Va.Input (text)
├─ Va.SearchField ← 내부에 Va.Search (search)
├─ Va.NumberField ← 내부에 Va.Number (number) ← 이 문서
├─ Va.TextareaField
├─ Va.ComboboxField
└─ ...
세 개 모두:
- 라벨/검증/설명 영역 = Field 베이스가 제공
- 실제 입력창 = 내부 PureField 계열 인스턴스가 담당
- 옵션 spread + _syncProperties 패턴 동일
차이는 딱 세 가지:
- 내부에 어떤 PureField를 생성하는가 (Va.Number)
- 세부 커스터마이즈 옵션 키 (number)
- Number 전용 속성 추가 (min / max / step)
3. Va.Number / Va.InputField와의 차이
항목Va.NumberVa.NumberFieldVa.InputField
| 라벨 | ✕ | ✓ | ✓ |
| 검증 메시지 | ✕ | ✓ | ✓ |
| 설명 텍스트 | ✕ | ✓ | ✓ |
| info 툴팁 | ✕ | ✓ | ✓ |
| input type | number 고정 | number 고정 | text 기본 |
| min / max / step | ✓ | ✓ (전용 속성) | ✕ (input 옵션으로만) |
| textAlign 기본 | 'right' | 'right' | 왼쪽 |
| 브라우저 스피너 | ✓ | ✓ | ✕ |
4. 주요 속성
Number 전용 속성 (Field 위에서도 유효)
속성기본값설명
| min | — | 최솟값 |
| max | — | 최댓값 |
| step | (내부 Number 기본 1) | 스피너 증감 단위 |
주목: 이 세 개가 Field 자체의 properties에 추가되어 있습니다 (va_component.js:5500). InputField/SearchField와의 차이. 그래서 setOption()이 인식하고 _syncProperties()로 내부 Number에도 자동 반영됩니다.
⚠️ decimalPlaces는 NumberField의 명시 속성이 아님 — 하지만 number 옵션 통해서 넘길 수는 있습니다 (아래 참조).
라벨 관련 (Field 상속)
속성기본값설명
| label | — | 라벨 텍스트 또는 옵션 객체 |
| labelPosition | 'top' | top / bottom / left / right |
| labelWidth | 자동 | 라벨 영역 폭 |
| labelAlign | — | 라벨 정렬 |
| noLabel | false | 라벨 영역 숨김 |
| infoButton | — | 라벨 옆 info 아이콘 (툴팁) |
| required | false | 필수 표시 |
필드 관련 (Number로 위임)
속성설명
| value | 필드 값 |
| placeholder | 플레이스홀더 |
| readonly / disabled | 상태 |
| textAlign | 정렬 — 기본 'right' (숫자 관행) |
| size / appearance / shape | 시각 스타일 |
| masking | 마스킹 (거의 안 씀) |
| valueType | 값 타입 힌트 |
검증
속성설명
| validation | {state, size, message} 객체 |
| validationState | success / warning / error |
| validationMessage | 메시지 텍스트 |
| validationSize | 메시지 크기 |
세부 커스터마이즈 (number 옵션 키)
{
tagName: 'numberField',
label: '평점',
min: 0,
max: 5,
step: 0.1,
number: { // ← 내부 Number에 직접 전달
decimalPlaces: 1,
autocomplete: 'off'
}
}
number 객체는 va_component.js:5524에서 내부 Va.Number 생성 시 spread됩니다. 특히 decimalPlaces는 이 통로로 넘겨야 반영됩니다 (Field 자체 속성엔 선언 안 되어 있음).
각 Field 계열의 옵션 키가 다릅니다 — InputField는 input, SearchField는 search, NumberField는 number.
5. 이벤트 (Field 상속)
Input/Search Field와 완전히 동일:
이벤트시그니처발생 시점
| change | (component, element, evt) | 값 변경 확정. 발생 시 검증 자동 리셋 |
| focus / blur | (component, element, evt) | blur 200ms debounce |
| click | (component, element, evt) | 필드 클릭 |
| keydown | (component, element, keyCode, evt) | 검증 자동 리셋 |
| keyup | (component, element, evt) | — |
| keypress | (component, element, evt) | — |
| contextmenu / mousedown | 표준 |
6. 메서드 (Field 상속)
InputField·SearchField와 완전히 동일:
값
메서드설명
| getValue() | 내부 Number의 getValue() 위임 (문자열 반환 — 계산엔 Number() 변환 필요) |
| setValue(value) | 값 세팅 + 검증 자동 리셋 (내부 Number가 decimalPlaces 적용) |
상태
메서드설명
| setDisabled(bool) / getDisabled() | 비활성화 |
| setReadOnly(bool) / setReadonly(bool) | 읽기 전용 |
| setLabel(label) | 라벨 변경 |
| setPlaceholder(text) | 플레이스홀더 변경 |
| setSize(size) | 크기 변경 |
검증
메서드설명
| setValidation(state, message) | 검증 표시 + aria 자동 세팅 |
| clearValidation() | 검증 해제 |
포커스
메서드설명
| focus() / blur() | 내부 Number에 위임 |
주의: setMin / setMax / setStep 같은 편의 setter는 없습니다. 값 변경이 필요하면 component.min = ...; component.update()로 직접.
7. 내부 구조
<div elname="element" class="va-field va-input [vertical|horizontal] [disabled]" 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.Number
<div class="field-wrapper">
<input type="number" step="1" min="0" max="100" ...>
<div class="focus-line"></div>
</div>
</div>
</div>
</div>
<div elname="validationDiv" style="display:none">
<div class="va-validation">...</div>
</div>
</div>
InputField/SearchField와 구조 동일, 안쪽 input의 type="number" + step/min/max 속성만 다름.
8. 언제 쓰나
NumberField가 맞을 때
- 폼 안 숫자 입력 필드 (수량·나이·평점·금액)
- 라벨과 함께 필수 표시·검증 메시지가 필요할 때
- 범위 제한(min/max)이 명확한 값
- 소수점 자릿수 강제(number.decimalPlaces)가 필요한 값
다른 걸 쓸 때
- 라벨 없는 인라인 숫자 입력 → Va.Number
- ±버튼이 좌우에 붙은 형태 → Va.NumberWithButtonField
- 금액에 콤마 포맷 → Va.InputField + input.numberComma:true
- 텍스트+숫자 혼합 (전화번호, 신용카드 등) → Va.InputField + masking
9. 흔한 조합 예시
// 수량
{
tagName: 'numberField',
label: '수량',
min: 0,
max: 999,
step: 1,
value: 1,
required: true
}
// 평점 (0~5, 소수 첫째)
{
tagName: 'numberField',
label: '평점',
min: 0,
max: 5,
step: 0.1,
number: { decimalPlaces: 1 },
value: 3.5
}
// 금액 (1000원 단위 스피너)
{
tagName: 'numberField',
label: '금액',
min: 0,
step: 1000,
value: 10000,
textAlign: 'right'
}
// 환율 (소수 넷째)
{
tagName: 'numberField',
label: '환율',
step: 0.0001,
number: { decimalPlaces: 4 },
value: 1300.1234
}
// 나이 (info 툴팁 포함)
{
tagName: 'numberField',
label: '나이',
min: 0,
max: 150,
infoButton: {
tooltip: '만 나이 기준으로 입력하세요'
}
}
10. 알아두면 좋을 주의사항
- getValue()는 문자열 — 계산엔 Number(component.getValue()) 변환 필수.
- min/max는 키보드 직접 입력 못 막음 — 정확한 범위 강제는 change 콜백에서 clamp하거나 setValidation('error', ...)으로 알림.
- decimalPlaces는 number 옵션으로만 — Field 자체 속성엔 없음. {number: {decimalPlaces: 2}} 형태로 전달.
- type 변경 불가 — 'number' 고정. text로 쓰려면 InputField 사용.
- numberComma 미지원 — 금액 콤마 필요하면 InputField + numberComma 조합.
- 초기 value가 0 — 빈 값 시작 원하면 value: '' 명시 (내부 Number의 기본값).
- textAlign 기본 'right' — 숫자 관행. 왼쪽 정렬 필요하면 명시.
- change/keydown 시 검증 자동 리셋 — 사용자가 값을 수정하기 시작하면 이전 에러가 사라짐.
- 브라우저 스피너 UX — 스피너 폭이 필드 오른쪽을 잡아먹음. 얇은 필드에선 CSS로 숨기는 게 나을 수 있음.
- decimalPlaces 실시간 반올림 UX 주의 — 사용자가 소수 입력 중일 때 값이 튀는 느낌이 있음 (내부 Number의 keyup 동작).
- 옵션 키가 number — InputField의 input, SearchField의 search와 헷갈리지 말 것.
- 필수 검증 자동화는 없음 — required: true는 라벨 별표만 표시. 실제 값 존재 검증은 콜백에서 setValidation() 호출로 처리.
'컴포넌트 > 필드 컴포넌트' 카테고리의 다른 글
| ColorField (색상필드) (0) | 2026.09.10 |
|---|---|
| ColorPicker(색상선택) (0) | 2026.09.10 |
| Number (숫자) (0) | 2026.09.10 |
| SearchField (검색필드) (0) | 2026.09.10 |
| Search (검색) (0) | 2026.09.10 |