Va.File — 파일 업로드 입력 (선택 표시 + 리셋 버튼 통합)
파일 선택 다이얼로그를 여는 표준 파일 입력 컴포넌트. 선택된 파일명 표시·File 버튼·Reset 버튼이 하나의 필드로 통합되어 있어, 일반 <input type="file">보다 사용자 UX가 정리되어 있습니다.
- 클래스: Va.File — va_component.js:9844
- short name: file
- 상속: Va.PureField (Input·Textarea와 형제)
- isContainer: true
- 베이스 CSS: va-file

1. 기본 사용
{
tagName: 'file',
onChange: 'onFileSelected'
}
렌더 결과:
- 좌측 표시 영역: Choose file (기본) → 선택 후 파일명
- File 버튼: 클릭 시 파일 선택 다이얼로그
- Reset 버튼: 선택 초기화
2. Va.File vs Va.FileButton vs 관련 컴포넌트
VanillaFront에는 파일 관련 컴포넌트가 여러 개 있습니다. 상황별 차이:
항목Va.FileVa.FileButtonVa.FileDropUpload
| UI 형태 | 표시 + 두 버튼(File/Reset) | 버튼 하나 | 드래그앤드롭 영역 |
| 선택 파일명 표시 | ✓ (기본) | ✕ | ✕ (별도 처리) |
| Reset 버튼 내장 | ✓ | ✕ | 관련 없음 |
| 기본 아이콘 | 없음 | ico_attach | 없음 |
| 드래그앤드롭 | ✕ | ✕ | ✓ |
| 폼 필드로 취급 | ✓ (PureField) | ✕ (Component) | ✕ |
한 줄 요약: "폼 안 표준 파일 선택 필드 — 파일명 표시와 리셋까지 포함."
3. 주요 속성
File 전용
속성기본값설명
| multiSelect | false | 다중 파일 선택 (properties에 선언 있으나 실제 반영 여부는 확인 필요) |
| fileButtonText | 'File' | File 버튼 텍스트 |
| resetButtonText | 'reset' | Reset 버튼 텍스트 |
| displayText | 'Choose file' | 초기 표시 텍스트 |
⚠️ multiSelect의 실제 동작 주의 — 옵션에 선언되어 있지만 코드가 <input>의 multiple 속성을 자동 세팅하지는 않아 보입니다. 필요 시 component.fieldElement.setAttribute('multiple', 'multiple')로 직접 설정.
PureField 상속
속성설명
| readonly / disabled | 상태 (두 버튼 모두 자동 전파) |
| size / appearance / shape | 시각 스타일 |
| stopPropagation | 이벤트 버블링 |
⚠️ 파일 관련 표준 옵션 누락 — accept(.jpg,.png 등 타입 필터), capture(모바일 카메라 직접) 같은 옵션이 노출되어 있지 않음. 필요하면 component.fieldElement.setAttribute('accept', 'image/*') 직접 세팅.
4. 이벤트
이벤트시그니처발생 시점
| change | (component, element, files, evt) | 파일 선택 완료 시 — files는 FileList |
| reset | (component, fieldElement, evt) | Reset 버튼 클릭 시 |
| click | (component, element, evt) | File 버튼 클릭 시 (다이얼로그 열기 직전) |
| focus / blur | (component, element, evt) | 표준 |
change 콜백 예시
onFileSelected(comp, el, files, evt) {
// files는 FileList
for (let i = 0; i < files.length; i++) {
console.log(files[i].name, files[i].size, files[i].type);
}
// FormData로 서버 전송
const formData = new FormData();
for (let i = 0; i < files.length; i++) {
formData.append('file', files[i]);
}
this.formService(this, '/api/upload', formData, this.onUploaded);
}
주의사항:
- 취소 시 이벤트 안 옴 — 다이얼로그를 그냥 닫으면 change 발생 안 함 (표준 파일 input 동작)
- 같은 파일 재선택 안 될 수 있음 — 표준 파일 input 동작. 필요 시 component.fieldElement.value = ''로 초기화
5. 메서드
파일 조회
메서드설명
| getFiles() | fieldElement.files (FileList) 반환 |
상태 (PureField 상속)
메서드설명
| setDisabled(bool) / setReadOnly(bool) | 상태 (두 버튼 자동 전파) |
| focus() / blur() | 포커스 |
주의: setValue() / getValue()는 PureField 상속이지만 파일 필드 특성상 실질 활용 제한적. 파일 조회는 getFiles() 사용.
6. 내부 컴포넌트 (innerComponents)
Va.File은 두 개의 Va.Button을 내부에 소유:
내부 컴포넌트접근 방법역할
| fileButtonComponent | component.fileButtonComponent | File 버튼 인스턴스 |
| resetButtonComponent | component.resetButtonComponent | Reset 버튼 인스턴스 |
필요 시 각 버튼의 세부 옵션·이벤트를 직접 조작할 수 있습니다.
mounted() {
// File 버튼 아이콘 추가
this.getRef('file').fileButtonComponent.setIcon('ico_attach');
}
7. 내부 구조
<div elname="element" class="va-file [size]..." tag-name="file" field="true">
<div elname="fieldWrapper" class="field-wrapper">
<input elname="field" type="file" style="display:none"> ← 숨겨진 실제 input
<div elname="display" class="display">Choose file</div> ← 파일명 표시
<div cpname="fileButton" class="va-button">File</div> ← 파일 선택 버튼
<div cpname="resetButton" class="va-button">reset</div> ← 리셋 버튼
<div elname="focusLine" class="focus-line"></div>
</div>
</div>
핵심 트릭:
- <input type="file">은 display:none — 실제 사용자 클릭은 File 버튼이 받음
- File 버튼 클릭 시 → 프로그램적으로 fieldElement.dispatchEvent(new MouseEvent("click")) → 다이얼로그 열림
- 표시 영역은 별도 div, 파일명을 콤마로 이어 표시
8. 언제 쓰나
Va.File이 맞을 때
- 폼 안 파일 첨부 — 게시글 첨부, 프로필 이미지 등
- 표준 UX (파일명 확인 + 리셋 가능)
- 자주 리셋이 필요한 상황 (여러 번 재선택)
다른 걸 쓸 때
- 단순 파일 첨부 버튼 (표시 없음) → Va.FileButton
- 드래그앤드롭 지원 → Va.FileDropUpload
- 이미지 미리보기 → Va.ImageFile
- 라벨 붙은 폼 필드 → Va.FileField
9. 흔한 조합 예시
// 표준
{
tagName: 'file',
onChange: 'onFileSelected'
}
// 버튼 텍스트 한글로
{
tagName: 'file',
fileButtonText: '파일 선택',
resetButtonText: '초기화',
displayText: '파일을 선택하세요'
}
// 이미지만 (accept 직접 세팅)
mounted() {
this.getRef('file').fieldElement.setAttribute('accept', 'image/*');
}
// 다중 파일 (multiple 직접 세팅)
mounted() {
this.getRef('file').fieldElement.setAttribute('multiple', 'multiple');
}
// 읽기 전용 (표시만)
{
tagName: 'file',
disabled: true,
displayText: '업로드 불가'
}
10. 실전 예 — 첨부파일 업로드
class Attachment extends Va.View {
mounted() {
// PDF와 이미지만 허용
this.getRef('file').fieldElement.setAttribute('accept', '.pdf,image/*');
}
onFileSelected(comp, el, files, evt) {
if (files.length === 0) return;
// 크기 검증 (10MB 제한)
for (let i = 0; i < files.length; i++) {
if (files[i].size > 10 * 1024 * 1024) {
new Va.Alert({
title: '용량 초과',
message: `${files[i].name}은 10MB를 초과합니다`
}).show(this);
comp.resetButtonComponent.element.click(); // 자동 리셋
return;
}
}
// FormData로 서버 전송
const formData = new FormData();
for (let i = 0; i < files.length; i++) {
formData.append('files', files[i]);
}
this.showMasking();
FileService.upload(this, formData, (view, ok, res) => {
view.hideMasking();
if (ok) {
new Va.Alert({ title: '완료', message: '업로드 완료' }).show(view);
}
});
}
onReset(comp, el, evt) {
console.log('파일 선택 초기화');
}
config() {
return {
tagName: 'page',
tags: [{
tagName: 'panel',
tags: [
{ tagName: 'h2', innerHTML: '첨부파일' },
{
tagName: 'file',
ref: 'file',
fileButtonText: '파일 선택',
resetButtonText: '초기화',
displayText: 'PDF/이미지 (최대 10MB)',
onChange: 'onFileSelected',
onReset: 'onReset'
}
]
}]
};
}
}
11. 알아두면 좋을 주의사항
- change 취소 시 안 옴 — 사용자가 다이얼로그 그냥 닫으면 이벤트 없음.
- 같은 파일 재선택 안 될 수 있음 — HTML 표준 특성. fieldElement.value = ''로 초기화 후 재시도.
- multiSelect 옵션이 실제 반영되지 않을 수 있음 — properties 선언은 있지만 코드가 multiple 속성 세팅 로직 없음. 확실히 하려면 DOM 직접 조작.
- accept / capture 옵션 노출 안 됨 — DOM 직접 조작 필요.
- <input type="file">이 display:none — File 버튼 클릭 시 프로그램적으로 클릭 발사.
- 파일명 표시는 콤마로 연결 — 다중 파일 시 file1.pdf, file2.pdf 형태.
- Reset 버튼이 있어 편리 — 사용자가 실수로 잘못 선택했을 때 되돌리기 쉬움.
- getFiles()는 FileList 반환 — 배열이 아님. Array.from(files) 변환 후 map/filter 등 사용.
- preventParentFieldEvent: true — 부모 Field 이벤트 개입 방지.
- 드래그앤드롭 없음 — 필요 시 Va.FileDropUpload 사용.
- disabled/readonly 시 두 버튼 모두 비활성 — 자동 전파.
- click 이벤트 두 곳에서 dispatch — File 버튼 클릭 시 내부에서 두 번 이벤트 발생 가능. 콜백 방어.
12. file vs fileButton vs fileDropUpload 선택
상황추천
| 폼 안 표준 파일 첨부 | file |
| 간단한 첨부 버튼 (표시 없음) | fileButton |
| 드래그앤드롭 지원 | fileDropUpload |
| 이미지 미리보기 필요 | imageFile |
| 라벨 붙은 폼 필드 | fileField |
| 여러 파일 순차 업로드 | fileDropUpload (진행률 표시) |
참고
- API 문서 페이지: https://vanillafront.com/docs.html?theme=light#main#apifile
- 연관: Va.FileButton(형제, 단순 버튼형), Va.FileField(라벨 포함 버전)
'컴포넌트 > 필드 컴포넌트' 카테고리의 다른 글
| FileField (파일필드) (1) | 2026.09.14 |
|---|---|
| TextareaField (텍스트영역필드) (0) | 2026.09.13 |
| Textarea (텍스트영역) (0) | 2026.09.13 |
| SwitchField (스위치필드) (0) | 2026.09.13 |
| Switch (스위치) (0) | 2026.09.13 |