DisplayField (디스플레이 필드)
Va.DisplayField — 라벨 + 읽기 전용 값 표시
Va.Display가 순수 표시 필드라면, Va.DisplayField는 그 위에 폼 라벨·검증 메시지 영역을 얹은 완성 폼 필드입니다. Field 계열 아키텍처 그대로, 내부에 Va.Display를 소유하는 Composition 구조. 폼 안 조회 화면의 정석.
- 클래스: Va.DisplayField — va_component.js:9612
- short name: displayField
- 상속: Va.Field (다른 Field 형제들과 같음)
- 내부 컴포넌트: Va.Display 인스턴스 (fieldComponent)
- isContainer: true
- 베이스 CSS: va-field

1. 기본 사용
{
tagName: 'displayField',
label: '고객명',
value: '홍길동'
}
라벨 + 읽기 전용 값 표시가 한 번에 세팅. 다른 폼 필드(InputField, ComboboxField 등)와 규격 통일.
2. Display / InputField(readonly)와의 차이
항목Va.DisplayVa.DisplayFieldVa.InputField(readonly)
| 폼 라벨 | ✕ | ✓ | ✓ |
| 검증 메시지 영역 | ✕ | ✓ | ✓ |
| 필수 표시 | ✕ | ✓ (실무엔 잘 안 씀) | ✓ |
| DOM 태그 | <div> | <div> (내부 위임) | <input> |
| HTML 콘텐츠 | ✓ | ✓ | ✕ |
| readonly 강제 | ✓ | ✓ | 옵션 |
| 폼 서브밋 값 | ✕ | ✕ | ✓ (readonly여도) |
한 줄 요약: "폼 안 라벨 붙은 읽기 전용 값 표시 필드 — 조회 화면 정석."
3. 주요 속성
Display 전용 (계승)
속성설명
| value | 표시할 값 (Field 표준 옵션) |
| text | 순수 텍스트 (Display 옵션으로 통과 시) |
| innerHTML | HTML 콘텐츠 (Display 옵션으로 통과 시) |
⚠️ readonly 강제 — 코드에서 this.readonly = true 세팅. 옵션으로 false 넘겨도 무시.
라벨 관련 (Field 상속)
속성설명
| label | 폼 라벨 |
| labelPosition | top / bottom / left / right |
| labelWidth | 라벨 폭 |
| noLabel | 폼 라벨 숨김 |
| infoButton | info 아이콘 |
| required | 필수 표시 (실질적 의미 없음 — 표시 전용이라) |
검증 (실질 사용 드묾)
속성설명
| validation | {state, size, message} |
| validationState | success / warning / error |
| validationMessage | 메시지 |
읽기 전용 필드에 검증 메시지는 활용도가 낮지만, "필수 값이 비어있음" 같은 상황엔 유용할 수 있음.
세부 커스터마이즈 (display 옵션 키)
{
tagName: 'displayField',
label: '상태',
display: { // ← 내부 Display에 직접 전달
innerHTML: '<b>승인 완료</b>'
}
}
각 Field 계열 옵션 키:
- InputField → input
- CheckboxField → checkbox
- DisplayField → display
4. 이벤트
Display의 이벤트를 재발화 (매우 제한적):
이벤트시그니처발생 시점
| select | (component, element, evt) | 선택 이벤트 (텍스트 선택 등) — 검증 자동 리셋 |
| keydown | (component, element, evt) | 키다운 — 검증 자동 리셋 |
주목: focus/blur/click/change 재발화 코드가 없음. 읽기 전용 필드라 실질적으로 이벤트 처리가 필요한 상황이 드물다는 설계 의도.
5. 메서드
값 관리 (Field 상속)
메서드설명
| getValue() | 내부 Display의 getValue() 위임 (textContent) |
| setValue(value) | Field 상속 — Display의 setValue()가 호출됨 |
⚠️ setValue()의 위험 — 내부 Display의 setValue()가 element 자식을 통째로 덮는 문제가 있어(element.textContent = value), 초기 구조 훼손 가능. 안전한 방법은 option.value나 option.text 지정.
상태 (Field 상속)
메서드설명
| setDisabled(bool) / getDisabled() | 비활성화 |
| setReadOnly(bool) / setReadonly(bool) | 읽기 전용 (이미 true 강제) |
| setLabel(label) | 폼 라벨 변경 |
| setSize(size) | 크기 |
검증
메서드설명
| setValidation(state, message) | 검증 표시 |
| clearValidation() | 검증 해제 |
6. 내부 구조
<div elname="element" class="va-field [vertical|horizontal]" field="true">
<div elname="inner" class="field-inner">
<div elname="labelDiv" class="label-div">
<label cpname="label">고객명</label>
</div>
<div elname="comment" class="field-comment"></div>
<div elname="fieldDiv" class="field-div">
<div cpname="field" class="va-display"> ← 내부 Va.Display
<div class="field-wrapper">
<div style="border:0px">홍길동</div> ← 값 (input 아님)
<div class="focus-line"></div>
</div>
</div>
</div>
</div>
<div elname="validationDiv" style="display:none">
<div class="va-validation">...</div>
</div>
</div>
핵심: 안쪽이 <input>이 아니라 <div>인 것 외엔 다른 Field 형제와 시각 구조 동일.
7. 언제 쓰나
DisplayField가 맞을 때
- 폼 안 조회 항목 (편집 없이 값 표시)
- 상세 화면 — 등록/수정 폼과 시각 규격 통일
- 자동 생성 값 표시 (주문번호, 생성일 등)
- 계산 결과 표시 (다른 필드 값 조합)
- 읽기 전용 상태를 명시적으로 표현
다른 걸 쓸 때
- 라벨 없이 인라인 → Va.Display
- 편집 가능하되 잠금 → Va.InputField + readonly: true
- 폼과 무관한 일반 텍스트 → <div> / Va.Div
- 긴 텍스트 스크롤 표시 → Va.TextareaField + readonly
8. 흔한 조합 예시
// 표준
{
tagName: 'displayField',
label: '고객명',
value: '홍길동'
}
// HTML 콘텐츠 (내부 display 옵션)
{
tagName: 'displayField',
label: '상태',
display: {
innerHTML: '<span style="color:green">활성</span>'
}
}
// 좌측 라벨 (조회 화면 관행)
{
tagName: 'displayField',
label: '주문번호',
labelPosition: 'left',
labelWidth: 100,
value: '20240315-001'
}
// 계산 결과 표시
mounted() {
const a = Number(this.getRef('a').getValue());
const b = Number(this.getRef('b').getValue());
this.getRef('sum').value = a + b;
this.getRef('sum').update();
}
// 서버 응답 표시
onLoad(view, ok, res) {
if (ok) {
view.getRef('createdAt').value = res.data.info.createdAt;
view.getRef('createdAt').update();
}
}
9. 실전 예 — 주문 상세 조회 폼
class OrderDetail extends Va.View {
async mounted() {
const orderId = this.getParams().orderId;
const res = await OrderService.get(this, { orderId });
if (res.result) {
const info = res.data.info;
this.getRef('orderId').value = info.orderId;
this.getRef('custName').value = info.custName;
this.getRef('amount').value = info.amount.toLocaleString() + '원';
this.getRef('createdAt').value = info.createdAt;
// HTML 콘텐츠로 상태 강조
const statusColor = info.status === 'DONE' ? 'green' : 'orange';
this.getRef('status').fieldComponent.innerHTML =
`<span style="color:${statusColor}">${info.statusName}</span>`;
// 각 필드 update() 트리거
['orderId', 'custName', 'amount', 'createdAt', 'status'].forEach(ref => {
this.getRef(ref).update();
});
}
}
config() {
return {
tagName: 'page',
tags: [{
tagName: 'panel',
tags: [
{ tagName: 'h2', innerHTML: '주문 상세' },
{
tagName: 'div',
layout: 'ds-flex fd-column gap-s',
tags: [
{
tagName: 'displayField',
ref: 'orderId',
label: '주문번호',
labelPosition: 'left',
labelWidth: 120
},
{
tagName: 'displayField',
ref: 'custName',
label: '고객명',
labelPosition: 'left',
labelWidth: 120
},
{
tagName: 'displayField',
ref: 'amount',
label: '결제 금액',
labelPosition: 'left',
labelWidth: 120
},
{
tagName: 'displayField',
ref: 'status',
label: '상태',
labelPosition: 'left',
labelWidth: 120
},
{
tagName: 'displayField',
ref: 'createdAt',
label: '주문일시',
labelPosition: 'left',
labelWidth: 120
}
]
},
{
tagName: 'button',
text: '수정',
appearance: 'primary',
onClick: 'onEdit'
}
]
}]
};
}
}
포인트:
- 좌측 라벨 정렬로 조회 화면다움 강조
- 다른 폼 필드(InputField 등)와 라벨 폭 통일 가능
- 상태는 HTML 콘텐츠로 색상 강조
- 수정 버튼 클릭 시 편집 폼(InputField 사용)으로 전환
10. 알아두면 좋을 주의사항
- readonly: true 강제 — Display와 동일. 편집 가능으로 만들 수 없음.
- 폼 서브밋에 값 참여 안 됨 — <input> 아님. 서버 전송은 별도 처리.
- setValue() 내부 구조 훼손 위험 — Display의 문제가 그대로 전파됨. option.value나 component.fieldComponent.innerHTML = ...; component.update() 권장.
- value vs text vs innerHTML — value는 Field 표준, text/innerHTML은 display 옵션으로 전달 시 우선.
- 옵션 키 display — 세부 커스터마이즈용.
- 이벤트 매우 제한적 — select/keydown만 재발화. 실질 활용 드묾.
- 검증 자동 리셋 있음 — select/keydown 시. 다만 편집 안 되는 필드라 검증 활용도 낮음.
- required: true는 별표만 표시 — 실질적 의미 없음 (편집 불가).
- 라벨 폭 통일이 조회 화면의 핵심 — labelPosition: 'left' + labelWidth로 다른 필드와 정렬.
- HTML 콘텐츠 세팅 시 — component.fieldComponent.innerHTML = value; component.update() 패턴이 안전.
11. displayField vs inputField(readonly) vs display 선택
상황추천
| 폼 안 조회 항목 (라벨 함께) | displayField |
| 라벨 없이 인라인 | display |
| 편집 가능하되 임시 잠금 | inputField + readonly: true |
| 폼 서브밋 값 필요 | inputField + readonly: true |
| HTML 콘텐츠 표시 | displayField + display.innerHTML |
| 긴 텍스트 | textareaField + readonly: true |
"조회 화면 = displayField, 잠긴 편집 화면 = inputField readonly" — 명확한 원칙.
참고
- API 문서 페이지: https://vanillafront.com/docs.html?theme=light#main#apidisplayfield
- 연관: Va.Display(내부), Va.InputField(대체 가능한 편집 잠금 필드)