fradrive/static/js/utils/inputs.js
2019-04-20 21:21:20 +02:00

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);
}
})();