201 lines
5.4 KiB
JavaScript
201 lines
5.4 KiB
JavaScript
(function() {
|
|
'use strict';
|
|
|
|
var inputUtilities = [];
|
|
|
|
/**
|
|
*
|
|
* FileInput Utility
|
|
* wraps native file input
|
|
*
|
|
* Attribute: uw-file-input
|
|
* (element must be an input of type='file')
|
|
*
|
|
* Example usage:
|
|
* <input type='file' uw-file-input>
|
|
*
|
|
* Internationalization:
|
|
* This utility expects the following translations to be available:
|
|
* »filesSelected«: label of multi-input button after selection
|
|
* example: "Dateien ausgewählt" (will be prepended by number of selected files)
|
|
* »selectFile«: label of single-input button before selection
|
|
* example: "Datei auswählen"
|
|
* »selectFiles«: label of multi-input button before selection
|
|
* example: "Datei(en) auswählen"
|
|
*
|
|
*/
|
|
|
|
var FILE_INPUT_UTIL_NAME = 'fileInput';
|
|
var FILE_INPUT_UTIL_SELECTOR = 'input[type="file"][uw-file-input]';
|
|
|
|
var FILE_INPUT_CLASS = 'file-input';
|
|
var FILE_INPUT_INITIALIZED_CLASS = 'file-input--initialized';
|
|
var FILE_INPUT_LIST_CLASS = 'file-input__list';
|
|
var FILE_INPUT_UNPACK_CHECKBOX_CLASS = 'file-input__unpack';
|
|
var FILE_INPUT_LABEL_CLASS = 'file-input__label';
|
|
|
|
var fileInputUtil = function(element) {
|
|
var isMultiFileInput = false;
|
|
var fileList;
|
|
var label;
|
|
|
|
function init() {
|
|
if (!element) {
|
|
throw new Error('FileInput utility cannot be setup without an element!');
|
|
}
|
|
|
|
if (element.classList.contains(FILE_INPUT_INITIALIZED_CLASS)) {
|
|
throw new Error('FileInput utility already initialized!');
|
|
}
|
|
|
|
// check if is multi-file input
|
|
isMultiFileInput = element.hasAttribute('multiple');
|
|
if (isMultiFileInput) {
|
|
fileList = createFileList();
|
|
}
|
|
|
|
label = createFileLabel();
|
|
updateLabel();
|
|
|
|
// add change listener
|
|
element.addEventListener('change', function() {
|
|
updateLabel();
|
|
renderFileList();
|
|
});
|
|
|
|
// add util class for styling and mark as initialized
|
|
element.classList.add(FILE_INPUT_CLASS, FILE_INPUT_INITIALIZED_CLASS);
|
|
|
|
return {
|
|
name: FILE_INPUT_UTIL_NAME,
|
|
element: element,
|
|
destroy: function() {},
|
|
};
|
|
}
|
|
|
|
function renderFileList() {
|
|
if (!fileList) {
|
|
return;
|
|
}
|
|
|
|
var files = element.files;
|
|
fileList.innerHTML = '';
|
|
Array.from(files).forEach(function(file) {
|
|
var fileDisplayEl = document.createElement('li');
|
|
fileDisplayEl.innerHTML = file.name;
|
|
fileList.appendChild(fileDisplayEl);
|
|
});
|
|
}
|
|
|
|
function createFileList() {
|
|
var list = document.createElement('ol');
|
|
list.classList.add(FILE_INPUT_LIST_CLASS);
|
|
var unpackEl = element.parentElement.querySelector('.' + FILE_INPUT_UNPACK_CHECKBOX_CLASS);
|
|
if (unpackEl) {
|
|
element.parentElement.insertBefore(list, unpackEl);
|
|
} else {
|
|
element.parentElement.appendChild(list);
|
|
}
|
|
return list;
|
|
}
|
|
|
|
function createFileLabel() {
|
|
var label = document.createElement('label');
|
|
label.classList.add(FILE_INPUT_LABEL_CLASS);
|
|
label.setAttribute('for', element.id);
|
|
element.parentElement.insertBefore(label, element);
|
|
return label;
|
|
}
|
|
|
|
function updateLabel() {
|
|
var files = element.files;
|
|
if (files && files.length) {
|
|
label.innerText = isMultiFileInput ? files.length + ' ' + I18n.get('filesSelected') : files[0].name;
|
|
} else {
|
|
label.innerText = isMultiFileInput ? I18n.get('selectFiles') : I18n.get('selectFile');
|
|
}
|
|
}
|
|
|
|
return init();
|
|
}
|
|
|
|
inputUtilities.push({
|
|
name: FILE_INPUT_UTIL_NAME,
|
|
selector: FILE_INPUT_UTIL_SELECTOR,
|
|
setup: fileInputUtil,
|
|
})
|
|
|
|
/**
|
|
*
|
|
* Checkbox Utility
|
|
* wraps native checkbox
|
|
*
|
|
* Attribute: (none)
|
|
* (element must be an input of type="checkbox")
|
|
*
|
|
* Example usage:
|
|
* <input type="checkbox">
|
|
*
|
|
*/
|
|
|
|
var CHECKBOX_UTIL_NAME = 'checkbox';
|
|
var CHECKBOX_UTIL_SELECTOR = 'input[type="checkbox"]';
|
|
|
|
var CHECKBOX_CLASS = 'checkbox';
|
|
var CHECKBOX_INITIALIZED_CLASS = 'checkbox--initialized';
|
|
|
|
var checkboxUtil = function(element) {
|
|
|
|
function init() {
|
|
if (!element) {
|
|
throw new Error('Checkbox utility cannot be setup without an element!');
|
|
}
|
|
|
|
if (element.classList.contains(CHECKBOX_INITIALIZED_CLASS)) {
|
|
// throw new Error('Checkbox utility already initialized!');
|
|
return false;
|
|
}
|
|
|
|
if (element.parentElement.classList.contains(CHECKBOX_CLASS)) {
|
|
// throw new Error('Checkbox element\'s wrapper already has class "' + CHECKBOX_CLASS + '"!');
|
|
return false;
|
|
}
|
|
|
|
var siblingEl = element.nextSibling;
|
|
var parentEl = element.parentElement;
|
|
|
|
var wrapperEl = document.createElement('div');
|
|
wrapperEl.classList.add(CHECKBOX_CLASS);
|
|
|
|
var labelEl = document.createElement('label');
|
|
labelEl.setAttribute('for', element.id);
|
|
|
|
wrapperEl.appendChild(element);
|
|
wrapperEl.appendChild(labelEl);
|
|
|
|
parentEl.insertBefore(wrapperEl, siblingEl);
|
|
|
|
element.classList.add(CHECKBOX_INITIALIZED_CLASS);
|
|
|
|
return {
|
|
name: CHECKBOX_UTIL_NAME,
|
|
element: element,
|
|
destroy: function() {},
|
|
};
|
|
}
|
|
|
|
return init();
|
|
}
|
|
|
|
inputUtilities.push({
|
|
name: CHECKBOX_UTIL_NAME,
|
|
selector: CHECKBOX_UTIL_SELECTOR,
|
|
setup: checkboxUtil,
|
|
});
|
|
|
|
// register the collected input utilities
|
|
if (UtilRegistry) {
|
|
inputUtilities.forEach(UtilRegistry.register);
|
|
}
|
|
})();
|