Display (디스플레이)
Va.Display — 읽기 전용 값 표시
입력 대신 값을 표시만 하는 필드. 다른 폼 필드와 시각적 규격을 맞춰 정렬된 값 표시가 필요할 때 사용합니다. <input readonly>보다 유연해서 HTML 콘텐츠까지 담을 수 있습니다.
- 클래스: Va.Display — va_component.js:9557
- short name: display
- 상속: Va.PureField (Input과 형제)
- DOM 태그: <div> (Input과 달리 <input>이 아님)
- isContainer: true
- 베이스 CSS: va-display

1. 기본 사용
{
tagName: 'display',
text: '홍길동',
style: { width: '200px' }
}
- 입력 불가한 값 표시
- 다른 폼 필드와 같은 크기·정렬로 배치 가능
- 편집 없이 데이터 조회 화면에 어울림
2. Display의 특징
Display는 처음부터 readonly: true가 강제되어 있고 (this.readonly = true), 값 입력 로직 대신 텍스트/HTML 표시에 특화되어 있습니다.
항목Va.Input (readonly)Va.Display
| DOM 태그 | <input> | <div> |
| HTML 콘텐츠 | ✕ | ✓ (innerHTML 지원) |
| 선택 가능 | 텍스트 선택 | 텍스트 선택 |
| 키 이벤트 | 발생 | 발생 (읽기 전용) |
| 상속 | PureField | PureField |
| 기본 readonly | false | true 강제 |
| 컴포넌트 목적 | 편집 가능 필드 | 표시 전용 |
한 줄 요약: "폼 안 라벨 없는 읽기 전용 값 표시 필드."
3. 주요 속성
Display 전용
속성설명
| text | 표시할 순수 텍스트 |
| innerHTML | HTML 포함 콘텐츠 (내부 _sanitize 적용) |
text와 innerHTML이 모두 있으면 text 우선.
PureField 상속
readonly (기본 true), disabled, size, appearance, stopPropagation 등.
⚠️ readonly가 강제로 true — 옵션으로 readonly: false를 넘겨도 무시됨. Display는 본래 표시 전용.
4. 이벤트
Display는 자체 이벤트가 매우 적음 — properties/events 배열 spread만 하고 특별한 이벤트 등록 없음.
PureField의 표준 이벤트(focus, blur, click 등)는 상속되지만, 편집 관련 이벤트(change 등)는 실질적 의미가 없음.
5. 메서드
값 관리 (오버라이드)
메서드설명
| setValue(value) | 값 세팅 — innerHTML과 element.textContent 둘 다 설정 |
| getValue() | element.textContent 반환 |
⚠️ setValue()의 특이한 구현 (va_component.js:9601-9604):
setValue(value){
this.innerHTML = value;
this.element.textContent = value; // ← element 전체를 textContent로 덮음
}
이 코드가 element 전체 자식을 지움 — fieldWrapper, fieldElement, focusLine 등이 사라져 텍스트만 남게 될 수 있음. 이후 getValue()가 그 텍스트만 반환하므로 표면적으론 동작하지만 내부 구조 훼손 위험. text 옵션이나 update() 경로가 더 안전.
권장: setValue()보다는 option.text / option.innerHTML을 옵션으로 지정하거나, 값 변경이 필요하면 component.text = value; component.update();.
6. 내부 구조
<div elname="element" class="va-display" tag-name="display" field="true">
<div elname="fieldWrapper" class="field-wrapper">
<div elname="field" style="border:0px">홍길동</div> ← 값 표시 영역
<div elname="focusLine" class="focus-line"></div>
</div>
</div>
핵심:
- <input> 대신 <div> 를 fieldElement로 사용 (PureField 생성자에 'div' 전달)
- border:0 강제 — 다른 폼 필드와 구분 없이 자연스럽게 보임
- text는 textContent, innerHTML은 innerHTML로 세팅
7. text vs innerHTML
두 옵션은 처리 경로가 다름:
text — 순수 텍스트
{ tagName: 'display', text: '<b>강조</b>' }
// 화면: <b>강조</b> (그대로 보임, HTML 파싱 안 됨)
- containerElement.textContent로 세팅
- HTML 태그가 있어도 텍스트로만 표시
- XSS 걱정 없음
innerHTML — HTML 포함
{ tagName: 'display', innerHTML: '<b>강조</b>' }
// 화면: 강조 (bold 스타일 적용)
- fieldElement.innerHTML로 세팅 (Va._sanitize 적용)
- HTML 태그 렌더링
- XSS 방지를 위해 sanitize 통과
서버에서 받은 사용자 입력 텍스트는 text로 표시하는 게 안전.
8. 언제 쓰나
Display가 맞을 때
- 상세 조회 화면의 값 표시 (편집 없음)
- 폼과 정렬을 맞춰야 하는 읽기 전용 값
- HTML 콘텐츠 표시 (링크 포함, 강조 등)
- 리포트·요약 화면
- 계산 결과 표시 (다른 필드의 값을 조합)
다른 걸 쓸 때
- 편집 가능 텍스트 → Va.Input
- 라벨 붙은 표시 → Va.DisplayField
- 그냥 텍스트 표시 (폼 정렬 필요 없음) → <div> / Va.Div / Va.Span
- 긴 문서형 텍스트 → Va.Textarea + readonly
9. 흔한 조합 예시
// 표준
{
tagName: 'display',
text: '홍길동',
style: { width: '200px' }
}
// HTML 콘텐츠
{
tagName: 'display',
innerHTML: '<b>VIP</b> 고객'
}
// 링크 포함
{
tagName: 'display',
innerHTML: '<a href="/detail/123">상세 보기</a>'
}
// 폼 안 다른 필드와 정렬 (DisplayField 아닌 이유는 라벨 불필요)
{
tagName: 'div',
layout: 'ds-flex fd-row gap-s',
tags: [
{ tagName: 'inputField', label: '이름' },
{ tagName: 'display', text: '(자동 생성)' }
]
}
// 계산 결과 표시
mounted() {
const total = this.getRef('a').getValue() + this.getRef('b').getValue();
this.getRef('sumDisplay').text = total;
this.getRef('sumDisplay').update();
}
// 서버 응답 표시
onLoad(view, ok, res) {
if (ok) {
view.getRef('userName').innerHTML = res.data.userName;
view.getRef('userName').update();
}
}
10. 실전 예 — 주문 상세 조회
class OrderDetail extends Va.View {
async mounted() {
const res = await OrderService.get(this, { orderId: '12345' });
if (res.result) {
const order = res.data.info;
this.getRef('orderId').text = order.orderId;
this.getRef('orderId').update();
this.getRef('custName').text = order.custName;
this.getRef('custName').update();
this.getRef('amount').text = order.amount.toLocaleString() + '원';
this.getRef('amount').update();
this.getRef('status').innerHTML =
`<span style="color:${order.status === 'DONE' ? 'green' : 'orange'}">${order.statusName}</span>`;
this.getRef('status').update();
}
}
config() {
return {
tagName: 'page',
tags: [{
tagName: 'panel',
tags: [
{ tagName: 'h2', innerHTML: '주문 상세' },
{
tagName: 'div',
layout: 'ds-flex fd-column gap-s',
tags: [
{
tagName: 'div',
layout: 'ds-flex fd-row gap-s',
tags: [
{ tagName: 'div', innerHTML: '주문번호:', style: { width: '100px' } },
{ tagName: 'display', ref: 'orderId' }
]
},
{
tagName: 'div',
layout: 'ds-flex fd-row gap-s',
tags: [
{ tagName: 'div', innerHTML: '고객명:', style: { width: '100px' } },
{ tagName: 'display', ref: 'custName' }
]
},
{
tagName: 'div',
layout: 'ds-flex fd-row gap-s',
tags: [
{ tagName: 'div', innerHTML: '금액:', style: { width: '100px' } },
{ tagName: 'display', ref: 'amount' }
]
},
{
tagName: 'div',
layout: 'ds-flex fd-row gap-s',
tags: [
{ tagName: 'div', innerHTML: '상태:', style: { width: '100px' } },
{ tagName: 'display', ref: 'status' }
]
}
]
}
]
}]
};
}
}
핵심:
- 폼과 시각적 규격을 맞춘 값 표시
- 상태는 HTML 콘텐츠로 색상 강조
- 편집 불가능 (조회 전용)
실무에선 대개 DisplayField로 라벨과 함께 감싸는 게 편함.
11. 알아두면 좋을 주의사항
- readonly: true 강제 — 옵션으로 편집 가능 만들 수 없음.
- <input> 아닌 <div> 기반 — 폼 서브밋에 값 참여 안 됨. 데이터 전송은 별도 처리 필요.
- setValue() 내부 구조 훼손 위험 — element.textContent = value가 자식 요소 다 지움. 안전한 방법은 component.text = value; component.update().
- text vs innerHTML 차이 — HTML 렌더링 여부. XSS 조심.
- innerHTML은 _sanitize 통과 — 위험한 태그(예: <script>)는 제거되지만 완벽한 방어는 아님.
- 이벤트 매우 제한적 — 편집 이벤트는 실질 의미 없음.
- getValue()는 textContent — HTML 태그 제거된 순수 텍스트.
- 정렬 목적으로 사용 — 라벨 없이 다른 필드와 나란히 두려면 유용.
- 라벨 필요하면 DisplayField — 폼 안 정식 필드 관행에 맞춤.
- change 이벤트 없음 — 값이 프로그램적으로 바뀌어도 이벤트 발생 안 함. 필요하면 세팅 후 명시적 로직.
12. display vs input readonly vs div 선택
상황추천
| 폼 안 값 표시 (라벨 없이) | display |
| 폼 안 값 표시 (라벨 함께) | displayField |
| HTML 콘텐츠 표시 | display + innerHTML |
| 편집 가능 필드로 표시만 잠금 | input + readonly: true |
| 폼 관계없는 일반 텍스트 | <div> / Va.Div |
| 긴 문서 스크롤 표시 | textarea + readonly |
참고
- API 문서 페이지: https://vanillafront.com/docs.html?theme=light#main#apidisplay
- 연관: Va.DisplayField(라벨 포함), Va.Input(편집 가능 형제)