101 lines
2.8 KiB
JavaScript
101 lines
2.8 KiB
JavaScript
import { Utility } from '../../core/utility';
|
|
import './file-input.sass';
|
|
|
|
const FILE_INPUT_CLASS = 'file-input';
|
|
const FILE_INPUT_INITIALIZED_CLASS = 'file-input--initialized';
|
|
const FILE_INPUT_LIST_CLASS = 'file-input__list';
|
|
const FILE_INPUT_UNPACK_CHECKBOX_CLASS = 'file-input__unpack';
|
|
const FILE_INPUT_LABEL_CLASS = 'file-input__label';
|
|
|
|
@Utility({
|
|
selector: 'input[type="file"][uw-file-input]',
|
|
})
|
|
export class FileInput {
|
|
|
|
_element;
|
|
_app;
|
|
|
|
_isMultiFileInput = false;
|
|
_fileList;
|
|
_label;
|
|
|
|
constructor(element, app) {
|
|
if (!element) {
|
|
throw new Error('FileInput utility cannot be setup without an element!');
|
|
}
|
|
|
|
this._element = element;
|
|
this._app = app;
|
|
|
|
if (this._element.classList.contains(FILE_INPUT_INITIALIZED_CLASS)) {
|
|
throw new Error('FileInput utility already initialized!');
|
|
}
|
|
|
|
// check if is multi-file input
|
|
this._isMultiFileInput = this._element.hasAttribute('multiple');
|
|
if (this._isMultiFileInput) {
|
|
this._fileList = this._createFileList();
|
|
}
|
|
|
|
this._label = this._createFileLabel();
|
|
this._updateLabel();
|
|
|
|
// add change listener
|
|
this._element.addEventListener('change', () => {
|
|
this._updateLabel();
|
|
this._renderFileList();
|
|
});
|
|
|
|
// add util class for styling and mark as initialized
|
|
this._element.classList.add(FILE_INPUT_CLASS);
|
|
this._element.classList.add(FILE_INPUT_INITIALIZED_CLASS);
|
|
}
|
|
|
|
destroy() {
|
|
// TODO
|
|
}
|
|
|
|
_renderFileList() {
|
|
if (!this._fileList) {
|
|
return;
|
|
}
|
|
|
|
const files = this._element.files;
|
|
this._fileList.innerHTML = '';
|
|
Array.from(files).forEach((file) => {
|
|
const fileDisplayEl = document.createElement('li');
|
|
fileDisplayEl.innerHTML = file.name;
|
|
this._fileList.appendChild(fileDisplayEl);
|
|
});
|
|
}
|
|
|
|
_createFileList() {
|
|
const list = document.createElement('ol');
|
|
list.classList.add(FILE_INPUT_LIST_CLASS);
|
|
const unpackEl = this._element.parentElement.querySelector('.' + FILE_INPUT_UNPACK_CHECKBOX_CLASS);
|
|
if (unpackEl) {
|
|
this._element.parentElement.insertBefore(list, unpackEl);
|
|
} else {
|
|
this._element.parentElement.appendChild(list);
|
|
}
|
|
return list;
|
|
}
|
|
|
|
_createFileLabel() {
|
|
const label = document.createElement('label');
|
|
label.classList.add(FILE_INPUT_LABEL_CLASS);
|
|
label.setAttribute('for', this._element.id);
|
|
this._element.parentElement.insertBefore(label, this._element);
|
|
return label;
|
|
}
|
|
|
|
_updateLabel() {
|
|
const files = this._element.files;
|
|
if (files && files.length) {
|
|
this._label.innerText = this._isMultiFileInput ? files.length + ' ' + this._app.i18n.get('filesSelected') : files[0].name;
|
|
} else {
|
|
this._label.innerText = this._isMultiFileInput ? this._app.i18n.get('selectFiles') : this._app.i18n.get('selectFile');
|
|
}
|
|
}
|
|
}
|