231 lines
6.6 KiB
JavaScript
231 lines
6.6 KiB
JavaScript
(function() {
|
|
'use strict';
|
|
|
|
window.utils = window.utils || {};
|
|
|
|
var JS_INITIALIZED_CLASS = 'js-initialized';
|
|
|
|
function isNotInitialized(element) {
|
|
return !element.classList.contains(JS_INITIALIZED_CLASS);
|
|
}
|
|
|
|
window.utils.inputs = function(wrapper, options) {
|
|
|
|
var utilInstances = [];
|
|
|
|
// checkboxes
|
|
var checkboxes = Array.from(wrapper.querySelectorAll('input[type="checkbox"]'));
|
|
checkboxes.filter(isNotInitialized).forEach(function(checkbox) {
|
|
utilInstances.push(window.utils.setup('checkbox', checkbox));
|
|
});
|
|
|
|
// radios
|
|
var radios = Array.from(wrapper.querySelectorAll('input[type="radio"]'));
|
|
radios.filter(isNotInitialized).forEach(function(radio) {
|
|
utilInstances.push(window.utils.setup('radio', radio));
|
|
});
|
|
|
|
// file-uploads
|
|
var fileUploads = Array.from(wrapper.querySelectorAll('input[type="file"]'));
|
|
fileUploads.filter(isNotInitialized).forEach(function(input) {
|
|
utilInstances.push(window.utils.setup('fileUpload', input, options));
|
|
});
|
|
|
|
// file-checkboxes
|
|
var fileCheckboxes = Array.from(wrapper.querySelectorAll('.file-checkbox'));
|
|
fileCheckboxes.filter(isNotInitialized).forEach(function(input) {
|
|
utilInstances.push(window.utils.setup('fileCheckbox', input, options));
|
|
});
|
|
|
|
function destroyUtils() {
|
|
utilInstances.forEach(function(utilInstance) {
|
|
utilInstance.destroy();
|
|
});
|
|
}
|
|
|
|
return {
|
|
scope: wrapper,
|
|
destroy: destroyUtils,
|
|
};
|
|
};
|
|
|
|
// (multiple) dynamic file uploads
|
|
// expects i18n object with following strings:
|
|
// »filesSelected«: label of multi-upload button after selection
|
|
// example: "Dateien ausgewählt" (will be prepended by number of selected files)
|
|
// »selectFile«: label of single-upload button before selection
|
|
// example: "Datei auswählen"
|
|
// »selectFiles«: label of multi-upload button before selection
|
|
// example: "Datei(en) auswählen"
|
|
|
|
var FILE_UPLOAD_INPUT_LIST_CLASS = 'file-input__list';
|
|
var FILE_UPLOAD_INPUT_UNPACK_CHECKBOX_CLASS = 'file-input__unpack';
|
|
var FILE_UPLOAD_INPUT_LABEL_CLASS = 'file-input__label';
|
|
var FILE_UPLOAD_INPUT_HIDDEN_CLASS = 'file-input__input--hidden';
|
|
|
|
window.utils.fileUpload = function(input, options) {
|
|
var isMulti = input.hasAttribute('multiple');
|
|
var fileList = isMulti ? addFileList() : null;
|
|
var label = addFileLabel();
|
|
var i18n = options.i18n;
|
|
|
|
if (!i18n) {
|
|
throw new Error('window.utils.fileUpload(input, options) needs to be passed i18n object via options');
|
|
}
|
|
input.classList.add(JS_INITIALIZED_CLASS);
|
|
|
|
function renderFileList(files) {
|
|
fileList.innerHTML = '';
|
|
Array.from(files).forEach(function(file, index) {
|
|
var fileDisplayEl = document.createElement('li');
|
|
fileDisplayEl.innerHTML = file.name;
|
|
fileList.appendChild(fileDisplayEl);
|
|
});
|
|
}
|
|
|
|
function updateLabel(files) {
|
|
if (files.length) {
|
|
if (isMulti) {
|
|
label.innerText = files.length + ' ' + i18n.filesSelected;
|
|
} else {
|
|
label.innerHTML = files[0].name;
|
|
}
|
|
} else {
|
|
resetFileLabel();
|
|
}
|
|
}
|
|
|
|
function addFileList() {
|
|
var list = document.createElement('ol');
|
|
list.classList.add(FILE_UPLOAD_INPUT_LIST_CLASS);
|
|
var unpackEl = input.parentElement.querySelector('.' + FILE_UPLOAD_INPUT_UNPACK_CHECKBOX_CLASS);
|
|
if (unpackEl) {
|
|
input.parentElement.insertBefore(list, unpackEl);
|
|
} else {
|
|
input.parentElement.appendChild(list);
|
|
}
|
|
return list;
|
|
}
|
|
|
|
function addFileLabel() {
|
|
var label = document.createElement('label');
|
|
label.classList.add(FILE_UPLOAD_INPUT_LABEL_CLASS);
|
|
label.setAttribute('for', input.id);
|
|
input.parentElement.insertBefore(label, input);
|
|
return label;
|
|
}
|
|
|
|
function resetFileLabel() {
|
|
if (isMulti) {
|
|
label.innerText = i18n.selectFiles;
|
|
} else {
|
|
label.innerText = i18n.selectFile;
|
|
}
|
|
}
|
|
|
|
// initial setup
|
|
resetFileLabel();
|
|
input.classList.add(FILE_UPLOAD_INPUT_HIDDEN_CLASS);
|
|
input.addEventListener('change', function() {
|
|
input.dispatchEvent(new Event('input'));
|
|
if (isMulti) {
|
|
renderFileList(input.files);
|
|
}
|
|
|
|
updateLabel(input.files);
|
|
});
|
|
|
|
return {
|
|
scope: input,
|
|
destroy: function() {},
|
|
};
|
|
}
|
|
|
|
// to remove previously uploaded files
|
|
|
|
var FILE_UPLOAD_CONTAINER_CLASS = 'file-container';
|
|
var FILE_UPLOAD_CONTAINER_CHECKED_CLASS = 'file-container--checked';
|
|
|
|
window.utils.fileCheckbox = function(input) {
|
|
// adds eventlistener(s)
|
|
function addListener(container) {
|
|
input.addEventListener('change', function(event) {
|
|
container.classList.toggle(FILE_UPLOAD_CONTAINER_CHECKED_CLASS, this.checked);
|
|
});
|
|
}
|
|
|
|
// initial setup
|
|
function setup() {
|
|
var cont = input.parentNode;
|
|
while (cont !== document.body) {
|
|
if (cont.matches('.' + FILE_UPLOAD_CONTAINER_CLASS)) {
|
|
break;
|
|
}
|
|
cont = cont.parentNode;
|
|
}
|
|
addListener(cont);
|
|
input.classList.add(JS_INITIALIZED_CLASS);
|
|
cont.classList.add(JS_INITIALIZED_CLASS);
|
|
}
|
|
|
|
setup();
|
|
|
|
return {
|
|
scope: input,
|
|
destroy: function() {},
|
|
};
|
|
}
|
|
|
|
// turns native checkboxes into custom ones
|
|
window.utils.checkbox = function(input) {
|
|
|
|
if (!input.parentElement.classList.contains('checkbox')) {
|
|
var parentEl = input.parentElement;
|
|
var siblingEl = input.nextElementSibling;
|
|
var wrapperEl = document.createElement('div');
|
|
var labelEl = document.createElement('label');
|
|
wrapperEl.classList.add('checkbox');
|
|
labelEl.setAttribute('for', input.id);
|
|
wrapperEl.appendChild(input);
|
|
wrapperEl.appendChild(labelEl);
|
|
input.classList.add(JS_INITIALIZED_CLASS);
|
|
|
|
if (siblingEl) {
|
|
parentEl.insertBefore(wrapperEl, siblingEl);
|
|
} else {
|
|
parentEl.appendChild(wrapperEl);
|
|
}
|
|
}
|
|
|
|
return {
|
|
scope: input,
|
|
destroy: function() {},
|
|
};
|
|
}
|
|
|
|
// turns native radio buttons into custom ones
|
|
window.utils.radio = function(input) {
|
|
|
|
if (!input.parentElement.classList.contains('radio')) {
|
|
var parentEl = input.parentElement;
|
|
var siblingEl = input.nextElementSibling;
|
|
var wrapperEl = document.createElement('div');
|
|
wrapperEl.classList.add('radio');
|
|
wrapperEl.appendChild(input);
|
|
|
|
if (siblingEl && siblingEl.matches('label')) {
|
|
wrapperEl.appendChild(siblingEl);
|
|
}
|
|
|
|
input.classList.add(JS_INITIALIZED_CLASS);
|
|
parentEl.appendChild(wrapperEl);
|
|
}
|
|
|
|
return {
|
|
scope: input,
|
|
destroy: function() {},
|
|
};
|
|
}
|
|
|
|
})();
|