move js utils for inputs to static
This commit is contained in:
parent
9d6eb5ae4e
commit
1277982449
@ -1004,6 +1004,7 @@ siteLayout' headingOverride widget = do
|
||||
addScript $ StaticR js_utils_tabber_js
|
||||
addScript $ StaticR js_utils_alerts_js
|
||||
addScript $ StaticR js_utils_asidenav_js
|
||||
addScript $ StaticR js_utils_inputs_js
|
||||
addStylesheet $ StaticR css_utils_tabber_scss
|
||||
addStylesheet $ StaticR css_utils_alerts_scss
|
||||
addStylesheet $ StaticR css_utils_asidenav_scss
|
||||
|
||||
171
static/js/utils/inputs.js
Normal file
171
static/js/utils/inputs.js
Normal file
@ -0,0 +1,171 @@
|
||||
(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) {
|
||||
// checkboxes / radios
|
||||
var checkboxes = Array.from(wrapper.querySelectorAll('input[type="checkbox"], input[type="radio"]'));
|
||||
checkboxes.filter(isNotInitialized).forEach(window.utils.checkboxRadio);
|
||||
|
||||
// file-uploads
|
||||
var fileUploads = Array.from(wrapper.querySelectorAll('input[type="file"]'));
|
||||
fileUploads.filter(isNotInitialized).forEach(function(input) {
|
||||
window.utils.fileUpload(input, options);
|
||||
});
|
||||
|
||||
// file-checkboxes
|
||||
var fileCheckboxes = Array.from(wrapper.querySelectorAll('.file-checkbox'));
|
||||
fileCheckboxes.filter(isNotInitialized).forEach(function(inp) {
|
||||
window.utils.fileCheckbox(inp);
|
||||
inp.classList.add(JS_INITIALIZED_CLASS);
|
||||
});
|
||||
};
|
||||
|
||||
// (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);
|
||||
});
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
// turns native checkboxes and radio buttons into custom ones
|
||||
window.utils.checkboxRadio = function(input) {
|
||||
|
||||
var type = input.getAttribute('type');
|
||||
|
||||
if (!input.parentElement.classList.contains(type)) {
|
||||
var parentEl = input.parentElement;
|
||||
var siblingEl = input.nextElementSibling;
|
||||
var wrapperEl = document.createElement('div');
|
||||
var labelEl = document.createElement('label');
|
||||
wrapperEl.classList.add(type);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
||||
@ -3,7 +3,7 @@ $forall FileUploadInfo{..} <- fileInfos
|
||||
<div .file-container :fuiChecked:.file-container--checked>
|
||||
<label .file-container__label.btn for=#{fuiHtmlId}>#{fuiTitle}
|
||||
<div .checkbox>
|
||||
<input .file-container__checkbox.js-file-checkbox id=#{fuiHtmlId} name=#{fieldName} :fuiChecked:checked value=#{toPathPiece fuiId} type="checkbox">
|
||||
<input .file-container__checkbox.file-checkbox id=#{fuiHtmlId} name=#{fieldName} :fuiChecked:checked value=#{toPathPiece fuiId} type="checkbox">
|
||||
<label for=#{fuiHtmlId}>
|
||||
|
||||
$# new files
|
||||
|
||||
@ -1,147 +1,8 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
window.utils = window.utils || {};
|
||||
|
||||
// allows for multiple file uploads with separate inputs
|
||||
window.utils.initializeFileUpload = function(input) {
|
||||
var isMulti = input.hasAttribute('multiple');
|
||||
var fileList = isMulti ? addFileList() : null;
|
||||
var label = addFileLabel();
|
||||
|
||||
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 + ' Dateien ausgwählt';
|
||||
} else {
|
||||
label.innerHTML = files[0].name;
|
||||
}
|
||||
} else {
|
||||
resetFileLabel();
|
||||
}
|
||||
}
|
||||
|
||||
function addFileList() {
|
||||
var list = document.createElement('ol');
|
||||
list.classList.add('file-input__list');
|
||||
var unpackEl = input.parentElement.querySelector('.file-input__unpack');
|
||||
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-input__label');
|
||||
label.setAttribute('for', input.id);
|
||||
input.parentElement.insertBefore(label, input);
|
||||
return label;
|
||||
}
|
||||
|
||||
function resetFileLabel() {
|
||||
// interpolate translated String here
|
||||
label.innerText = 'Datei' + (isMulti ? 'en' : '') + ' auswählen';
|
||||
}
|
||||
|
||||
// initial setup
|
||||
resetFileLabel();
|
||||
input.classList.add('file-input__input--hidden');
|
||||
input.addEventListener('change', function() {
|
||||
input.dispatchEvent(new Event('input'));
|
||||
if (isMulti) {
|
||||
renderFileList(input.files);
|
||||
}
|
||||
|
||||
updateLabel(input.files);
|
||||
});
|
||||
}
|
||||
|
||||
// to remove previously uploaded files
|
||||
window.utils.reactiveFileCheckbox = function(input) {
|
||||
// adds eventlistener(s)
|
||||
function addListener(container) {
|
||||
input.addEventListener('change', function(event) {
|
||||
container.classList.toggle('file-container--checked', this.checked);
|
||||
});
|
||||
}
|
||||
|
||||
// initial setup
|
||||
function setup() {
|
||||
var cont = input.parentNode;
|
||||
while (cont !== document.body) {
|
||||
if (cont.matches('.file-container')) {
|
||||
break;
|
||||
}
|
||||
cont = cont.parentNode;
|
||||
}
|
||||
addListener(cont);
|
||||
}
|
||||
setup();
|
||||
}
|
||||
|
||||
window.utils.initializeCheckboxRadio = function(input, type) {
|
||||
|
||||
if (!input.parentElement.classList.contains(type)) {
|
||||
var parentEl = input.parentElement;
|
||||
var siblingEl = input.nextElementSibling;
|
||||
var wrapperEl = document.createElement('div');
|
||||
var labelEl = document.createElement('label');
|
||||
wrapperEl.classList.add(type);
|
||||
labelEl.setAttribute('for', input.id);
|
||||
wrapperEl.appendChild(input);
|
||||
wrapperEl.appendChild(labelEl);
|
||||
|
||||
if (siblingEl) {
|
||||
parentEl.insertBefore(wrapperEl, siblingEl);
|
||||
} else {
|
||||
parentEl.appendChild(wrapperEl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
document.addEventListener('setup', function(e) {
|
||||
if (e.detail.module && e.detail.module !== 'inputs')
|
||||
return;
|
||||
|
||||
// initialize checkboxes
|
||||
Array.from(e.detail.scope.querySelectorAll('input[type="checkbox"]:not(.js-initialized)')).forEach(function(inp) {
|
||||
window.utils.initializeCheckboxRadio(inp, 'checkbox');
|
||||
inp.classList.add("js-initialized");
|
||||
});
|
||||
|
||||
// initialize radios
|
||||
Array.from(e.detail.scope.querySelectorAll('input[type="radio"]:not(.js-initialized)')).forEach(function(inp) {
|
||||
window.utils.initializeCheckboxRadio(inp, 'radio');
|
||||
inp.classList.add("js-initialized");
|
||||
});
|
||||
|
||||
// initialize file-upload-fields
|
||||
Array.from(e.detail.scope.querySelectorAll('input[type="file"]:not(.js-initialized)')).forEach(function(inp) {
|
||||
window.utils.initializeFileUpload(inp);
|
||||
inp.classList.add("js-initialized");
|
||||
});
|
||||
|
||||
// initialize file-checkbox-fields
|
||||
Array.from(e.detail.scope.querySelectorAll('.js-file-checkbox:not(.js-initialized)')).forEach(function(inp) {
|
||||
window.utils.reactiveFileCheckbox(inp);
|
||||
inp.classList.add("js-initialized");
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.dispatchEvent(new CustomEvent('setup', { detail: { scope: document.body, module: 'inputs' }, bubbles: true, cancelable: true }));
|
||||
var i18n = {
|
||||
filesSelected: 'Dateien ausgewählt',
|
||||
selectFile: 'Datei auswählen',
|
||||
selectFiles: 'Datei(en) auswählen',
|
||||
};
|
||||
window.utils.setup('inputs', document.body, { i18n });
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user