Merge branch 'feat/file_inputs' into 'master'

Fixes for multi-file-input and -checkbox

See merge request !22
This commit is contained in:
Felix Hamann 2018-04-03 18:32:48 +02:00
commit 0b0444ede4
3 changed files with 64 additions and 40 deletions

View File

@ -1,17 +1,21 @@
$newline never $newline never
$forall FileUploadInfo{..} <- fileInfos
<input type=checkbox id=#{fieldId}_zip name=#{fieldName} value=#{unpackZips} :req:required> <div .file-checkbox__container :fuiChecked:.file-checkbox__container--checked>
<label for=#{fieldId}_zip> <label .file-checkbox__label.reactive-label.btn for=#{fuiHtmlId}>#{fuiTitle}
ZIPs entpacken <div .checkbox>
<input .file-checkbox.js-file-checkbox id=#{fuiHtmlId} name=#{fieldName} :fuiChecked:checked value=#{toPathPiece fuiId} type="checkbox">
<ul>
$forall FileUploadInfo{..} <- fileInfos
<li>
<input type=checkbox name=#{fieldName} value=#{toPathPiece fuiId} id=#{fuiHtmlId} :fuiChecked:checked>
<span style="display:none">
#{fuiTitle}
<label for=#{fuiHtmlId}> <label for=#{fuiHtmlId}>
#{fuiTitle}
<li>
<input type=file id=#{fieldId} name=#{fieldName} multiple> <div .file-checkbox__container.file-checkbox__container--checked>
<label .file-checkbox__label.reactive-label.btn for=fi1>file1.txt
<div .checkbox>
<input .file-checkbox.js-file-checkbox id=fi1 name=file checked value="file1.txt" type="checkbox">
<label for=fi1>
$# new files
<input type="file" name=#{fieldName} multiple>
<div .file-input__unpack>
<label for=#{fieldId}_zip>ZIPs entpacken
<input type=checkbox id=#{fieldId}_zip name=#{fieldName} value=#{unpackZips} :req:required>

View File

@ -25,11 +25,12 @@
}; };
// allows for multiple file uploads with separate inputs // allows for multiple file uploads with separate inputs
window.utils.reactiveFileUpload = function(input, parent) { window.utils.reactiveFileUpload = function(input, formGroup) {
var currValidInputCount = 0; var currValidInputCount = 0;
var addMore = false; var addMore = false;
var inputName = input.getAttribute('name'); var inputName = input.getAttribute('name');
var isMulti = input.hasAttribute('multiple') ? true : false; var isMulti = input.hasAttribute('multiple') ? true : false;
var wrapper = formGroup;
// FileInput PseudoClass // FileInput PseudoClass
function FileInput(container, input, label, remover) { function FileInput(container, input, label, remover) {
this.container = container; this.container = container;
@ -49,26 +50,26 @@
} }
} }
function addNextInput() { function addNextInput() {
var inputs = parent.querySelectorAll('.file-input__container'); var inputs = wrapper.querySelectorAll('.file-input__container');
if (inputs[inputs.length - 1].classList.contains('file-input__container--valid')) { if (inputs[inputs.length - 1].classList.contains('file-input__container--valid')) {
makeInput(inputName).addTo(parent); makeInput(inputName).addTo(wrapper);
} }
} }
// updates submitbutton and form-group-stripe // updates submitbutton and form-group-stripe
function updateForm() { function updateForm() {
var submitBtn = parent.parentElement.querySelector('[type=submit]'); var submitBtn = formGroup.parentElement.querySelector('[type=submit]');
parent.classList.remove('form-group--has-error'); formGroup.classList.remove('form-group--has-error');
if (currValidInputCount > 0) { if (currValidInputCount > 0) {
if (parent.classList.contains('form-group')) { if (formGroup.classList.contains('form-group')) {
parent.classList.add('form-group--valid') formGroup.classList.add('form-group--valid')
} }
submitBtn.removeAttribute('disabled'); submitBtn.removeAttribute('disabled');
if (isMulti) { if (isMulti) {
addNextInput(); addNextInput();
} }
} else { } else {
if (parent.classList.contains('form-group')) { if (formGroup.classList.contains('form-group')) {
parent.classList.remove('form-group--valid') formGroup.classList.remove('form-group--valid')
} }
submitBtn.setAttribute('disabled', 'disabled'); submitBtn.setAttribute('disabled', 'disabled');
} }
@ -141,22 +142,27 @@
// initial setup // initial setup
function setup() { function setup() {
var newInput = makeInput(inputName); var newInput = makeInput(inputName);
if (isMulti) {
wrapper = document.createElement('div');
wrapper.classList.add('file-input__wrapper');
formGroup.insertBefore(wrapper, input);
}
input.remove(); input.remove();
newInput.addTo(parent); newInput.addTo(wrapper);
updateForm(); updateForm();
} }
setup(); setup();
} }
// to remove previously uploaded files // to remove previously uploaded files
window.utils.reactiveFileCheckbox = function(input, label, parent) { window.utils.reactiveFileCheckbox = function(input) {
// adds eventlistener(s) // adds eventlistener(s)
function addListener(container) { function addListener(container) {
container.addEventListener('click', function() { container.addEventListener('click', function() {
input.click(); input.click();
}); });
input.addEventListener('change', function(event) { input.addEventListener('change', function(event) {
container.classList.toggle('file-checkbox__container--valid', this.checked); container.classList.toggle('file-checkbox__container--checked', this.checked);
}); });
} }
@ -207,13 +213,12 @@ document.addEventListener('DOMContentLoaded', function() {
var input = document.querySelector('#' + label.getAttribute('for')); var input = document.querySelector('#' + label.getAttribute('for'));
if (!input) { if (!input) {
console.error('No input found for ReactiveLabel! Targeted input: \'#%s\'', label.getAttribute('for')); console.error('No input found for ReactiveLabel! Targeted input: \'#%s\'', label.getAttribute('for'));
label.classList.remove('reactive-label');
return false; return false;
} }
var parent = label.parentElement; var parent = label.parentElement;
var type = input.getAttribute('type'); var type = input.getAttribute('type');
var isFileUpload = /file/i.test(type);
var isFileCheckbox = input.classList.contains('file-checkbox');
var isListening = !RegExp(['date', 'checkbox', 'radio', 'hidden', 'file'].join('|')).test(type); var isListening = !RegExp(['date', 'checkbox', 'radio', 'hidden', 'file'].join('|')).test(type);
var isInFormGroup = parent.classList.contains('form-group') && parent.classList.contains('form-group--required'); var isInFormGroup = parent.classList.contains('form-group') && parent.classList.contains('form-group--required');
@ -221,16 +226,24 @@ document.addEventListener('DOMContentLoaded', function() {
if (isInFormGroup) { if (isInFormGroup) {
window.utils.reactiveFormGroup(parent, input); window.utils.reactiveFormGroup(parent, input);
} }
if (isFileUpload) {
window.utils.reactiveFileUpload(input, parent);
}
if (isFileCheckbox) {
window.utils.reactiveFileCheckbox(input, label, parent);
}
if (isListening) { if (isListening) {
window.utils.reactiveInputLabel(input, label); window.utils.reactiveInputLabel(input, label);
} else { } else {
label.classList.remove('reactive-label'); label.classList.remove('reactive-label');
} }
}); });
// initialize file-upload-fields
Array.from(document.querySelectorAll('input[type="file"]')).map(function(inp) {
var formGroup = inp.parentNode;
while (!formGroup.classList.contains('form-group') && formGroup !== document.body) {
formGroup = formGroup.parentNode;
}
window.utils.reactiveFileUpload(inp, formGroup);
});
// initialize file-checkbox-fields
Array.from(document.querySelectorAll('.js-file-checkbox')).map(function(inp) {
window.utils.reactiveFileCheckbox(inp);
});
}); });

View File

@ -263,11 +263,16 @@ input[type="file"].js-file-input {
outline: 0; outline: 0;
border: 0; border: 0;
} }
.file-input__wrapper {
grid-column-start: 2;
}
.file-input__container, .file-input__container,
.file-checkbox__container { .file-checkbox__container,
.file-input__unpack {
grid-column-start: 2; grid-column-start: 2;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
margin: 4px 0;
} }
.file-input__label, .file-input__label,
.file-input__remover, .file-input__remover,
@ -336,12 +341,12 @@ input[type="file"].js-file-input {
.file-input__container--valid > .file-input__label { .file-input__container--valid > .file-input__label {
background-color: var(--lightbase); background-color: var(--lightbase);
} }
.file-checkbox__container--valid > .file-checkbox__label { .file-checkbox__container--checked > .file-checkbox__label {
text-decoration: none; text-decoration: none;
background-color: var(--lighterbase); background-color: var(--lighterbase);
&:hover { &.btn:hover {
background-color: var(--greybase); background-color: var(--lighterbase);
text-decoration: line-through; text-decoration: line-through;
} }
} }
@ -353,8 +358,10 @@ input[type="file"].js-file-input {
display: block; display: block;
} }
@media (max-width: 999px) { @media (max-width: 999px) {
.file-input__wrapper,
.file-input__container, .file-input__container,
.file-checkbox__container { .file-checkbox__container,
.file-input__unpack {
grid-column-start: 1; grid-column-start: 1;
} }
} }