(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: * * * 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: * * */ 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.nextElementSibling; 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); } // FH: leaving this as it is to be able to understand whats going on // 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); }, }; } })();