(function() { 'use strict'; var JS_INITIALIZED_CLASS = 'js-inputs-initialized'; window.utils.inputs = function(wrapper, options) { options = options || {}; var utilInstances = []; if (wrapper.classList.contains(JS_INITIALIZED_CLASS) && !options.force) { return false; } // checkboxes var checkboxes = Array.from(wrapper.querySelectorAll('input[type="checkbox"]')); checkboxes.forEach(function(checkbox) { utilInstances.push(window.utils.setup('checkbox', checkbox)); }); // radios var radios = Array.from(wrapper.querySelectorAll('input[type="radio"]')); radios.forEach(function(radio) { utilInstances.push(window.utils.setup('radio', radio)); }); // file-uploads var fileUploads = Array.from(wrapper.querySelectorAll('input[type="file"]')); fileUploads.forEach(function(input) { utilInstances.push(window.utils.setup('fileUpload', input, options)); }); // file-checkboxes var fileCheckboxes = Array.from(wrapper.querySelectorAll('.file-checkbox')); fileCheckboxes.forEach(function(input) { utilInstances.push(window.utils.setup('fileCheckbox', input, options)); }); function destroyUtils() { utilInstances.filter(function(utilInstance) { return !!utilInstance; }).forEach(function(utilInstance) { utilInstance.destroy(); }); } wrapper.classList.add(JS_INITIALIZED_CLASS); return { scope: wrapper, destroy: destroyUtils, }; }; /** * * FileUpload Utility * * Attribute: uw-file-upload * (element must be an input of type='file') * * Example usage: * * * Internationalization: * This utility expects the following translations to be available: * »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_UTIL_NAME = 'fileUpload'; var FILE_UPLOAD_UTIL_SELECTOR = 'input[type="file"][uw-file-upload]'; var FILE_UPLOAD_CLASS = 'file-input'; var FILE_UPLOAD_INITIALIZED_CLASS = 'file-input--initialized'; var FILE_UPLOAD_LIST_CLASS = 'file-input__list'; var FILE_UPLOAD_UNPACK_CHECKBOX_CLASS = 'file-input__unpack'; var FILE_UPLOAD_LABEL_CLASS = 'file-input__label'; var fileUploadUtil = function(element) { var isMultiFileUpload = false; var fileList; var label; function init() { if (!element) { throw new Error('FileUpload utility cannot be setup without an element!'); } if (element.classList.contains(FILE_UPLOAD_INITIALIZED_CLASS)) { throw new Error('FileUpload utility already initialized!'); } // check if is multi-file upload isMultiFileUpload = element.hasAttribute('multiple'); if (isMultiFileUpload) { 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_UPLOAD_CLASS, FILE_UPLOAD_INITIALIZED_CLASS); return { name: FILE_UPLOAD_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_UPLOAD_LIST_CLASS); var unpackEl = element.parentElement.querySelector('.' + FILE_UPLOAD_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_UPLOAD_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 = isMultiFileUpload ? files.length + ' ' + I18n.get('filesSelected') : files[0].name; } else { label.innerText = isMultiFileUpload ? I18n.get('selectFiles') : I18n.get('selectFile'); } } return init(); } if (UtilRegistry) { UtilRegistry.register({ name: FILE_UPLOAD_UTIL_NAME, selector: FILE_UPLOAD_UTIL_SELECTOR, setup: fileUploadUtil, }); } // 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 init() { var cont = input.parentNode; while (cont !== document.body) { if (cont.matches('.' + FILE_UPLOAD_CONTAINER_CLASS)) { break; } cont = cont.parentNode; } addListener(cont); } return init(); } // 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); 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); } parentEl.appendChild(wrapperEl); } return { scope: input, destroy: function() {}, }; } // Override implicit submit (pressing enter) behaviour to trigger a specified submit button instead of the default window.utils.implicitSubmit = function(input, options) { var submit = options.submit; if (!submit) { throw new Error('window.utils.implicitSubmit(input, options) needs to be passed a submit element via options'); } var doSubmit = function(event) { if (event.keyCode == 13) { event.preventDefault(); submit.click(); } }; input.addEventListener('keypress', doSubmit); return { scope: input, destroy: function() { input.removeEventListener('keypress', doSubmit); }, }; } })();