컴포넌트/필드 컴포넌트

YearField (연도필드)

VanillaFront 2026. 9. 11. 14:15

Va.YearField — 라벨 + 년도 선택 필드

Va.YearPicker가 순수 년도 입력이라면, Va.YearField는 그 위에 라벨·필수 표시·검증 메시지를 얹은 완성 폼 필드입니다. Field 계열 아키텍처 그대로, 내부에 Va.YearPicker를 소유하는 Composition 구조. Date 계열 Field 중에서 가장 가볍고 단순합니다.

  • 클래스: Va.YearField  va_component.js:8645
  • short name: yearField
  • 상속: Va.Field (다른 Field 형제들과 같음)
  • 내부 컴포넌트: Va.YearPicker 인스턴스 (fieldComponent)
  • isContainer: true
  • 베이스 CSS: va-field (role="date-field" 자동 부여)


1. 기본 사용

{
    tagName: 'yearField',
    label: '회계연도',
    value: '2024',
    required: true,
    onSelect: 'onYearChange'
}

라벨 + 검증 + 10년 격자 팝업이 한 번에 세팅. 저장 값은 4자리 문자열.


2. Field 계열에서의 위치

Va.Field
   ├─ Va.InputField         ← Va.Input
   ├─ Va.SearchField        ← Va.Search
   ├─ Va.NumberField        ← Va.Number
   ├─ Va.ComboboxField      ← Va.Combobox
   ├─ Va.YearField          ← Va.YearPicker         (년만)          ← 이 문서
   ├─ Va.MonthField         ← Va.MonthPicker        (년-월)
   ├─ Va.DateField          ← Va.DatePicker         (년-월-일)
   ├─ Va.DateTimeField      ← Va.DateTimePicker     (년-월-일 + 시분초)
   └─ ...

YearField의 정체: Field 베이스 + 내부에 Va.YearPicker 인스턴스.

⚠️ 이름 규칙 유지 — DateField·MonthField·DateTimeField와 함께 "Picker"가 이름에서 생략되는 그룹.


3. Va.YearPicker / 다른 Date 계열 Field와의 차이

항목Va.YearPickerVa.YearFieldVa.DateField

라벨
검증 메시지
info 툴팁
입력 대상 년도만 년도만 년-월-일
저장 값 길이 4자리 4자리 8자리
팝업 UI 10년 격자 10년 격자 (내부 위임) 일 단위 캘린더
role="date-field" 자동
bindParams (부모 바인딩)

한 줄 요약: "폼 안 라벨 붙은 년도 필드 — 회계연도·설립년도 등에 최적."


4. 주요 속성

팝업

속성기본값설명

popWidth 240 팝업 폭
expanded false 팝업 초기 상태
min / max properties에 있으나 YearPicker 자체 로직에서 실질 강제 안 됨

라벨 (Field 상속)

속성설명

label 라벨 텍스트 또는 객체
labelPosition top / bottom / left / right
labelWidth 라벨 폭
noLabel 라벨 숨김
infoButton info 아이콘
required 필수 표시

필드 관련 (YearPicker로 위임)

속성설명

value 년도 값 (4자리 문자열)
placeholder 플레이스홀더
readonly / disabled 상태
size / appearance / shape 시각 스타일
stopPropagation 이벤트 버블링
dateFormat / dateSeperator (선언만, 년도 하나엔 실효 미미)
valueDateFormat / valueDateSeperator 마찬가지

검증

속성설명

validation {state, size, message}
validationState success / warning / error
validationMessage 메시지

세부 커스터마이즈 (monthPicker 옵션 키 — ⚠️ 주의)

{
    tagName: 'yearField',
    label: '설립년도',
    monthPicker: {                  // ← 옵션 키가 'monthPicker' (실수로 그대로 남음)
        popWidth: 320
    }
}

⚠️ 옵션 키가 monthPicker — YearField 코드가 MonthField에서 복사되며 남은 흔적으로 보입니다 (va_component.js:8680). yearPicker로 넘겨도 무시됩니다. 실무에선 이 옵션을 잘 안 쓰지만, 알아둬야 헤매지 않아요.

각 Field 계열 옵션 키:

  • InputField → input
  • ComboboxField → combobox
  • DateField / DateTimeField → datePicker
  • MonthField → monthPicker
  • YearField → monthPicker (!) — 버그성 잔재

5. 이벤트

YearPicker의 이벤트를 재발화:

이벤트시그니처발생 시점

select (component, element, value, evt) 팝업에서 년도 클릭 시. value는 선택된 년도 문자열
beforePop / afterPop / hidePop 팝업 표시/숨김  
expand / collapse 팝업 확장/축소  
focus / blur 표준  
change / keydown Field 표준  

주목: select 콜백 시그니처에 value 인자가 살아 있음. DateField와 달리 값이 콜백에 넘어옵니다.


6. 메서드

값 관리 (Field 상속 그대로)

메서드설명

getValue() 내부 YearPicker의 getValue() 위임 — 필드값 그대로 반환
setValue(value) Field 상속 — 값 그대로 세팅 (포맷 변환 없음)

주목: YearField는 setValue() / getValue()를 오버라이드하지 않습니다. DateField·DateTimeField는 복잡한 포맷 변환 로직으로 오버라이드했지만, 년도는 4자리 단순 문자열이라 변환이 필요 없어요.

상태 (Field 상속)

메서드설명

setDisabled(bool) / getDisabled() 비활성화
setReadOnly(bool) / setReadonly(bool) 읽기 전용
setLabel(label) 라벨 변경
setPlaceholder(text) 플레이스홀더
setSize(size) 크기

검증

메서드설명

setValidation(state, message) 검증 표시 + aria
clearValidation() 검증 해제

포커스

메서드설명

focus() / blur() 내부 YearPicker의 fieldElement에 위임

주의: showPop, hidePop, showYearPickerPop, hideYearPickerPop 같은 세부 메서드는 위임 없음. 필요하면 component.fieldComponent.xxx()로 직접.


7. 내부 구조

<div elname="element" class="va-field [vertical|horizontal]"
     role="date-field" 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-yearpicker">        ← 내부 Va.YearPicker
        <div class="field-wrapper">
          <input type="text">
          <div class="focus-line"></div>
          <div class="calendar-icon-wrapper">
            <span class="icon menu ico_calender_ltr">📅</span>
          </div>
        </div>
        <!-- 팝업은 hiddenArea로 이동 -->
      </div>
    </div>
  </div>
  <div elname="validationDiv" style="display:none">
    <div class="va-validation">...</div>
  </div>
</div>

8. 언제 쓰나

YearField가 맞을 때

  • 폼 안 회계연도 선택 (2024년 결산 등)
  • 설립년도·졸업년도·시행년도 같은 년도만 필요한 필드
  • 연간 통계 리포트의 년도 파라미터
  • 연도별 배치 작업 대상 선택
  • 라벨·필수·검증이 필요한 폼 필드

다른 걸 쓸 때

  • 라벨 없이 인라인 → Va.YearPicker
  • 년-월 필요 → Va.MonthField
  • 년-월-일 필요 → Va.DateField
  • 시간까지 → Va.DateTimeField
  • 년도 목록이 짧고 특정됨 (예: 2020~2024) → Va.ComboboxField에 년도 배열이 더 간단
  • 시작~종료 년도 범위 → 두 YearField 조합

9. 흔한 조합 예시

// 표준
{
    tagName: 'yearField',
    label: '회계연도',
    value: '2024',
    required: true
}

// 좌측 라벨
{
    tagName: 'yearField',
    label: '설립년도',
    labelPosition: 'left',
    labelWidth: 100,
    value: '2010'
}

// 오늘 년도로 초기화
mounted() {
    const year = String(new Date().getFullYear());
    this.getRef('year').setValue(year);
}

// info 툴팁
{
    tagName: 'yearField',
    label: '기준년도',
    infoButton: {
        tooltip: '통계 기준 년도를 선택하세요'
    }
}

// 검증
{
    tagName: 'yearField',
    label: '년도',
    ref: 'year',
    required: true,
    onSelect: 'onYearPicked'
}

onSubmit() {
    const year = this.getRef('year').getValue();
    if (!year) {
        this.getRef('year').setValidation('error', '년도를 선택하세요');
        return;
    }
    // ...
}

10. 알아두면 좋을 주의사항

  1. 컴포넌트명  yearField (not yearPickerField).
  2. value는 4자리 문자열  '2024'. 숫자 넘겨도 대체로 동작하지만 문자열이 안전.
  3. setValue()는 값 그대로 통과 — DateField 등과 달리 포맷 변환 없음. 잘못된 값도 그대로 저장.
  4. getValue()는 필드값 그대로 반환 — 사용자가 필드에 직접 타이핑한 값이 그대로 나옴. 4자리 숫자 검증 없음.
  5. 필드 타이핑 자유 — 마스킹 없음. abcd 같은 입력도 가능. 별도 검증 필요.
  6. dateFormat 등 포맷 옵션 실효 미미 — properties·optionField에 있지만 년도 하나만 다뤄 로직 반영이 제한적.
  7. min/max 실질 강제 없음 — YearPicker 팝업에도 범위 필터 UI 없음. 검증은 콜백에서.
  8. 옵션 키가 monthPicker — 세부 옵션은 이 키로 넘겨야 함 (버그성 잔재).
  9. 10년 격자만 지원 — 5년·20년 등 다른 크기 격자 옵션 없음.
  10. popWidth 기본 240 — DatePicker(260)보다 작음.
  11. 팝업 상태머신 참여 — 다른 팝업과 자동 상호 배타.
  12. role="date-field" 자동 — YearField이지만 role은 date-field. ARIA 힌트.
  13. change/keydown 시 검증 자동 리셋 없을 수도 — Field 표준 동작은 있지만 YearField 특유 로직 없음. Demo에서 확인 권장.
  14. 일부 메서드 위임 누락  showPop/hidePop 등. fieldComponent로 직접.

11. 실전 예 — 연간 리포트 필터 (Field 버전)

YearPicker 편의 예제를 Field로 감싼 버전:

class AnnualReport extends Va.View {
    mounted() {
        const currentYear = String(new Date().getFullYear());
        this.getRef('year').setValue(currentYear);
        this.loadReport(currentYear);
    }

    onYearSelect(field, el, value, evt) {
        this.loadReport(value);
    }

    loadReport(year) {
        if (!year || year.length !== 4) {
            this.getRef('year').setValidation('error', '유효한 년도를 선택하세요');
            return;
        }
        this.getRef('year').clearValidation();

        ReportService.getAnnual(this, { year }, (view, ok, res) => {
            if (ok) view.getRef('grid').setData(res.data.list);
        });
    }

    config() {
        return {
            tagName: 'page',
            tags: [{
                tagName: 'panel',
                tags: [
                    { tagName: 'h2', innerHTML: '연간 실적 리포트' },
                    {
                        tagName: 'div',
                        layout: 'ds-flex fd-row ai-end gap-s',
                        tags: [
                            {
                                tagName: 'yearField',
                                ref: 'year',
                                label: '기준년도',
                                required: true,
                                onSelect: 'onYearSelect',
                                style: { width: '150px' }
                            }
                        ]
                    },
                    {
                        tagName: 'grid',
                        ref: 'grid',
                        columns: [
                            { key: 'month',   title: '월',   width: 60 },
                            { key: 'revenue', title: '매출', fillRatio: 1 },
                            { key: 'cost',    title: '원가', fillRatio: 1 }
                        ]
                    }
                ]
            }]
        };
    }
}

YearPicker 단독 사용과 비교하면 라벨 + 필수 표시 + 검증 메시지가 자동 세팅되어 폼 UX가 자연스럽습니다.


12. yearField vs combobox 년도 선택 비교

상황추천

년도 범위가 넓거나 미확정 (1900~현재) yearField
년도 범위가 좁고 고정 (2020~2024, 5개) Va.ComboboxField (년도 배열 넣기)
사용자가 손쉽게 이전 10년으로 이동해야 함 yearField (팝업 화살표)
다국어·검색으로 선택 Va.ComboboxField
년도별 옵션에 부가 정보(예: "2024 - 갑진년") 필요 Va.ComboboxField + template

년도 범위와 UX 요구사항에 따라 선택하세요. 회계연도 같은 광범위 년도는 YearField, 정해진 몇 개 년도는 Combobox.