컴포넌트/필드 컴포넌트

DateField (날짜필드)

VanillaFront 2026. 9. 10. 15:40

Va.DateField — 라벨 + 캘린더 팝업 날짜 필드

Va.DatePicker가 순수 날짜 입력이라면, Va.DateField는 그 위에 라벨·필수 표시·검증 메시지를 얹은 완성 폼 필드입니다. Field 계열 아키텍처 그대로, 내부에 Va.DatePicker를 소유하는 Composition 구조.

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


1. 기본 사용

{
    tagName: 'dateField',
    label: '생년월일',
    value: '19900315',
    required: true,
    onSelect: 'onBirthdayChange'
}

라벨 + 검증 + 캘린더 팝업 + 마스킹 입력이 한 번에 세팅.


2. Field 계열에서의 위치

Va.Field
   ├─ Va.InputField          ← Va.Input
   ├─ Va.SearchField         ← Va.Search
   ├─ Va.NumberField         ← Va.Number
   ├─ Va.ComboboxField       ← Va.Combobox
   ├─ Va.FilterboxField      ← Va.Filterbox
   ├─ Va.TagField            ← Va.Tag
   ├─ Va.DateField           ← Va.DatePicker      ← 이 문서
   └─ ...

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

⚠️ 이름 주의: 다른 Field 형제들은 Va.InputField ← Va.Input, Va.NumberField ← Va.Number처럼 이름 규칙이 정확한데 여기는 Va.DateField ← Va.DatePicker 로 이름이 어긋납니다. 등록명도 dateField이니 datePickerField가 아닙니다.


3. Va.DatePicker / 다른 Field와의 차이

항목Va.DatePickerVa.DateFieldVa.InputField

라벨
검증 메시지
info 툴팁
캘린더 팝업 ✓ (내부 위임)
날짜 마스킹 ✓ (내부 재설정)
dateFormat / valueDateFormat 분리
role="date-field" 자동
bindParams (부모 바인딩) ✕ (ComboboxField에만 있음)

한 줄 요약: "폼 안 라벨 붙은 캘린더 날짜 필드."


4. 주요 속성

날짜 포맷 (DatePicker와 동일)

속성기본값설명

dateFormat 'ymd' 화면 표시 순서 — ymd / mdy / dmy
dateSeperator '-' 화면 구분자
valueDateFormat 'ymd' 저장 값 순서
valueDateSeperator '' 저장 값 구분자 (기본 없음)

범위

속성설명

min 최소 선택 가능 날짜 (YYYYMMDD)
max 최대 선택 가능 날짜

팝업

속성기본값설명

popWidth 260 팝업 폭
expanded false 팝업 초기 상태

라벨 (Field 상속)

속성설명

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

필드 관련 (DatePicker로 위임)

속성설명

value 날짜 값 (valueDateFormat 기준 문자열)
placeholder 플레이스홀더
readonly / disabled 상태
size / appearance / shape 시각 스타일
masking 자동 (dateFormat/seperator에 따라)
stopPropagation 이벤트 버블링

검증

속성설명

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

세부 커스터마이즈 (datePicker 옵션 키)

{
    tagName: 'dateField',
    label: '입사일',
    datePicker: {                // ← 내부 DatePicker에 직접 전달
        popWidth: 320
    }
}

각 Field 계열 옵션 키:

  • InputField → input
  • ComboboxField → combobox
  • TagField → tag
  • DateField → datePicker

5. 이벤트

DatePicker의 이벤트를 재발화:

이벤트시그니처발생 시점

select (component, element, evt) 캘린더에서 날짜 클릭 시. 발생 시 검증 자동 리셋
beforePop / afterPop / hidePop 팝업 표시  
expand / collapse 팝업 확장/축소  
focus / blur 표준  
change / keydown Field 표준 (검증 자동 리셋)  

⚠️ select 이벤트가 두 번 dispatch됨 — 소스 va_component.js:7303va_component.js:7333에서 각각. 콜백 중복 실행 위험. 방어 코드 필요.

⚠️ select 콜백 시그니처가 짧음 — (component, element, evt) 3개 인자만. DatePicker의 (component, element, value, evt)와 다름 — value가 빠져 있어 콜백에서 component.getValue()로 직접 조회 필요.


6. 메서드

값 관리 — 오버라이드된 setter/getter

메서드설명

setValue(value) valueDateFormat 규약을 따르는 값 세팅. 8자리 미만이면 무시, ''면 비움. DateField 자체에 재구현되어 있음 (Field 상속 아님)
getValue() valueDateFormat 규약을 따르는 값 반환. DateField 자체에 재구현
getDisplay() 화면 표시 형태로 반환 (dateFormat/seperator 적용)

상태 (Field 상속)

메서드설명

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

검증

메서드설명

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

포커스

메서드설명

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

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


7. 내부 구조

<div elname="element" class="va-field [vertical|horizontal]"
     role="date-field" field="true">                       ← role="date-field" 자동
  <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.DatePicker
        <div class="field-wrapper">
          <input type="text" placeholder="____-__-__">
          <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. 마스킹 이중 설정

DateField는 생성자에서 마스킹을 두 번 설정합니다:

  1. optionField.masking에 넣어 DatePicker 생성자로 전달 (va_component.js:7252)
  2. DatePicker 생성 후 this.fieldComponent.setMasking(this.masking) 재호출 (va_component.js:7294)

이유: dateFormat이 옵션으로 넘어와도 정확한 마스킹 패턴이 반영되도록. 실무엔 큰 영향 없지만 코드 의도.


9. 언제 쓰나

DateField가 맞을 때

  • 폼 안 라벨 붙은 날짜 필드 — 생년월일, 계약일, 마감일
  • 검증 메시지("날짜를 선택하세요") 필요
  • 화면 표시 포맷과 서버 저장 포맷이 다를 때
  • 캘린더 UI로 시각적 선택 필요

다른 걸 쓸 때

  • 라벨 없는 인라인 → Va.DatePicker
  • 년-월-일이 아닌 다른 조합:
    • 년도만 → Va.YearField/Va.YearPicker
    • 년-월 → Va.MonthField/Va.MonthPicker
    • 시작-종료 → Va.DateRangeField/Va.DateRangePicker
    • 날짜+시간 → Va.DateTimeField/Va.DateTimePicker
    • 시간만 → Va.TimeField/Va.TimePicker

10. 흔한 조합 예시

// 표준 사용
{
    tagName: 'dateField',
    label: '생년월일',
    value: '19900315',
    required: true
}

// 미국식 표시 + 한국 저장
{
    tagName: 'dateField',
    label: 'Birthday',
    dateFormat: 'mdy',
    dateSeperator: '/',
    valueDateFormat: 'ymd',
    value: '19900315'         // 화면: 03/15/1990
}

// 서버가 하이픈 포함 원할 때
{
    tagName: 'dateField',
    label: '계약일',
    valueDateSeperator: '-',
    value: '2024-03-15'
}

// 범위 제한 (올해만)
{
    tagName: 'dateField',
    label: '예약일',
    min: '20240101',
    max: '20241231',
    required: true
}

// 좌측 라벨 + 필수
{
    tagName: 'dateField',
    label: '입사일',
    labelPosition: 'left',
    labelWidth: 100,
    required: true
}

// 오늘 이후만
{
    tagName: 'dateField',
    label: '희망 배송일',
    min: new Date().toISOString().slice(0,10).replace(/-/g,''),
    onSelect: 'onDeliveryDateChange'
}

// info 툴팁
{
    tagName: 'dateField',
    label: '마감일',
    infoButton: {
        tooltip: 'YYYY-MM-DD 형식으로 자동 입력됩니다'
    }
}

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

  1. 컴포넌트명 주의  dateField (not datePickerField).
  2. value는 문자열 — Date 객체 아님. '20241225' 같은 문자열.
  3. setValue() 8자리 미만이면 무시 — 조용히 return.
  4. setValue(null)도 무시 — return만.
  5. setValue('') / setValue(' ')은 비움 처리 — trim 후 빈 문자열이면 필드 클리어.
  6. select 이벤트 두 번 dispatch — 콜백 방어 필요.
  7. select 콜백에 value 인자 없음 — DatePicker와 시그니처 다름. component.getValue() 별도 호출.
  8. dateFormat과 valueDateFormat 혼동 주의 — 화면 vs 저장.
  9. 일부 메서드 위임 누락  setRawValue/getRawValue/showPop/hidePop 등. fieldComponent로 직접.
  10. getValue() 반환 로직에 미묘한 차이  valueDateFormat이 dmy일 때 seperator 없어도 순서만 재배치 (va_component.js:7441-7444). 다른 포맷은 seperator가 있어야 재배치.
  11. 팝업 상태머신 참여 — 다른 팝업과 자동 상호 배타 (Va.addAutoHide).
  12. 마스킹 자동 — dateFormat에 따라 masking 자동 설정. 사용자가 지정하면 덮어씀.
  13. role="date-field" — DateField 자신에게 자동 부여되는 ARIA 힌트. DatePicker 단독으로는 없는 속성.
  14. change/keydown 시 검증 자동 리셋 — 사용자가 값 수정 시 이전 에러 사라짐.
  15. 범위 검사는 팝업 UI에만 — 필드 직접 타이핑으로 min/max 밖 값도 들어감. 별도 검증 필요.
  16. timezone 없음 — 로컬 문자열만.

12. dateField vs datePickerField 명명 이슈

VanillaFront의 Field 계열 이름 규칙을 보면:

PureFieldField규칙

Va.Input Va.InputField ✓ 규칙적
Va.Search Va.SearchField
Va.Number Va.NumberField
Va.Combobox Va.ComboboxField
Va.Filterbox Va.FilterboxField
Va.Tag Va.TagField
Va.ColorPicker Va.ColorField ⚠️ "Picker" 생략
Va.DatePicker Va.DateField ⚠️ "Picker" 생략
Va.DateTimePicker ? 확인 필요
Va.MonthPicker ? 확인 필요

ColorPicker → ColorField, DatePicker → DateField 처럼 "Picker" 부분이 Field 계열 이름에서 생략되는 경향. 새 컴포넌트 이름 유추 시 참고.