From 7cd873f30854012c9c4d97a25be1d70c08226ad2 Mon Sep 17 00:00:00 2001 From: Felix Hamann Date: Fri, 9 Mar 2018 22:22:40 +0100 Subject: [PATCH] refined file-inputs --- templates/default-layout.lucius | 6 ++ templates/widgets/form.julius | 129 +++++++++++++++++++------------- templates/widgets/form.lucius | 108 +++++++++++++++----------- 3 files changed, 145 insertions(+), 98 deletions(-) diff --git a/templates/default-layout.lucius b/templates/default-layout.lucius index 0bc38fb16..07834f3d4 100644 --- a/templates/default-layout.lucius +++ b/templates/default-layout.lucius @@ -24,6 +24,7 @@ /* THEME INDEPENDENT COLORS */ --errorbase: red; --warningbase: #fe7700; + --validbase: #2dcc35; /* FONTS */ @@ -129,3 +130,8 @@ th, td { margin: 10px 0; } } + +.pseudo-focus { + outline: 5px auto var(--lightbase); + outline: 5px auto -webkit-focus-ring-color; +} diff --git a/templates/widgets/form.julius b/templates/widgets/form.julius index bfbca4ef6..1c1932f06 100644 --- a/templates/widgets/form.julius +++ b/templates/widgets/form.julius @@ -44,87 +44,110 @@ }; window.utils.reactiveFileUpload = function(input, parent) { - var currInputCount = 0; - // shows new add-mode-button after destInput - function showAddMore(destInput) { - var addMore = document.createElement('div'); - addMore.classList.add('form-group__add-entry'); - addMore.addEventListener('click', function() { - if (addMore.classList.contains('form-group__remove-entry')) { - addMore.remove(); - destInput.remove(); - currInputCount--; - updateParent(); - } else { - addMore.classList.remove('form-group__add-entry'); - addMore.classList.add('form-group__remove-entry'); - var nextInput = makeInput(destInput.getAttribute('name')); - parent.appendChild(nextInput); - } - }); - parent.appendChild(addMore); + var currValidInputCount = 0; + var addMore = false; + var inputName = input.getAttribute('name'); + // FileInput PseudoClass + function FileInput(container, input, label, remover) { + this.container = container; + this.input = input; + this.label = label; + this.remover = remover; + addListener(this); + + this.addTo = function(parentElement) { + parentElement.appendChild(this.container); + parentElement.appendChild(this.remover); + } + this.remove = function() { + this.container.remove(); + this.remover.remove(); + } + this.isValid = function() { + return this.container.classList.contains('file-input__container--valid'); + } + } + function addNextInput() { + var inputs = parent.querySelectorAll('.file-input__container'); + if (inputs[inputs.length - 1].classList.contains('file-input__container--valid')) { + makeInput(inputName).addTo(parent); + } } // updates submitbutton and form-group-stripe - function updateParent() { + function updateForm() { var submitBtn = parent.parentElement.querySelector('[type=submit]'); - if (currInputCount > 0) { + parent.classList.remove('form-group--has-error'); + if (currValidInputCount > 0) { if (parent.classList.contains('form-group')) { parent.classList.add('form-group--valid') - parent.classList.remove('form-group--has-error'); } submitBtn.removeAttribute('disabled'); + addNextInput(); } else { if (parent.classList.contains('form-group')) { - parent.classList.remove('form-group--has-error'); parent.classList.remove('form-group--valid') } submitBtn.setAttribute('disabled', 'disabled'); } } // addseventlistener destInput - function addListener(destInput) { - destInput.addEventListener('change', function(event) { - if (destInput.value.length > 0) { - destInput.nextSibling.innerHTML = destInput.value; - currInputCount++; - showAddMore(destInput); + function addListener(fileInput) { + fileInput.input.addEventListener('change', function(event) { + if (fileInput.input.value.length > 0) { + // update label + var filePath = fileInput.input.value.replace(/\\/g, '/').split('/'); + var fileName = filePath[filePath.length - 1]; + fileInput.label.innerHTML = fileName; + // increase count if this field was empty previously + if (!fileInput.isValid()) { + currValidInputCount++; + } + fileInput.container.classList.add('file-input__container--valid') + // show next input } else { - destInput.nextSibling.innerHTML = 'Choose file'; + currValidInputCount--; + fileInput.remove(); } - updateParent(); + updateForm(); + }); + fileInput.input.addEventListener('focus', function() { + fileInput.container.classList.add('pseudo-focus'); + }); + fileInput.input.addEventListener('blur', function() { + fileInput.container.classList.remove('pseudo-focus'); + }); + fileInput.label.addEventListener('click', function() { + fileInput.input.click(); + }); + fileInput.remover.addEventListener('click', function() { + if (fileInput.isValid()) { + currValidInputCount--; + } + fileInput.remove(); + updateForm(); }); } - // create new wrapped input element with name name function makeInput(name) { + var cont = document.createElement('div'); + var desc = document.createElement('span'); var nextInput = document.createElement('input'); + var remover = document.createElement('div'); + cont.classList.add('file-input__container'); + desc.classList.add('file-input__label'); + remover.classList.add('file-input__remover'); nextInput.setAttribute('name', name); nextInput.setAttribute('type', 'file'); - addListener(nextInput); - return wrapButton(nextInput); - } - - // wraps input in container to be able to style it properly - function wrapButton(input) { - var cont = document.createElement('div'); - var desc = document.createElement('span'); - cont.classList.add('form-group__file-input-container'); - desc.classList.add('form-group__file-input-label'); - desc.innerHTML = 'Choose file'; - cont.appendChild(input); + cont.appendChild(nextInput); cont.appendChild(desc); - cont.addEventListener('click', function() { - input.click(); - }); - return cont; + return new FileInput(cont, nextInput, desc, remover); } - // initial setup function setup() { - addListener(input); - var currInput = wrapButton(input); - parent.appendChild(currInput); - updateParent(); + var newInput = makeInput(inputName); + input.remove(); + newInput.addTo(parent); + updateForm(); } setup(); } diff --git a/templates/widgets/form.lucius b/templates/widgets/form.lucius index 03bca934b..0fac63bb5 100644 --- a/templates/widgets/form.lucius +++ b/templates/widgets/form.lucius @@ -81,7 +81,7 @@ textarea:focus { display: grid; grid-template-columns: repeat(3, minmax(150px, max-content)); grid-auto-rows: 30px; - grid-gap: 10px; + grid-gap: 5px; align-items: center; margin: 10px 0; margin-left: -20px; @@ -94,47 +94,12 @@ textarea:focus { } .form-group--valid { - border-left: 8px solid #2dcc35; + border-left: 8px solid var(--validbase); } .form-group--has-error { border-left: 8px solid var(--errorbase) !important; } -.form-group__add-entry, -.form-group__remove-entry { - display: block; - width: 40px; - height: 30px; - background-color: var(--lightbase); - border-radius: 2px; - position: relative; - grid-column-start: 3; -} -.form-group__remove-entry { - background-color: var(--warningbase); -} -.form-group__remove-entry::after { - content: none; -} -.form-group__add-entry::before, -.form-group__add-entry::after, -.form-group__remove-entry::after { - content: ''; - position: absolute; -} -.form-group__add-entry::before { - width: 4px; - height: 20px; - background-color: white; - transform: translate(18px, 5px); -} -.form-group__add-entry::after, -.form-group__remove-entry::after { - width: 20px; - height: 4px; - background-color: white; - transform: translate(10px, 13px); -} /* CUSTOM LEGACY CHECKBOX AND RADIO BOXES */ input[type="checkbox"] { @@ -292,15 +257,68 @@ input[type="file"] { outline: 0; border: 0; } -.form-group__file-input-container { - border-radius: 2px; - background-color: var(--darkbase); - padding: 7px 13px; - color: var(--whitebase); +.file-input__container { grid-column-start: 2; - text-align: left; +} +.file-input__label, +.file-input__remover { + display: block; + border-radius: 2px; + padding: 5px 13px; + color: var(--whitebase); cursor: pointer; } -.form-group__file-input-label { - +.file-input__label { + background-color: var(--lighterbase); + text-align: left; + position: relative; + min-width: 40px; + height: 30px; +} +.file-input__label::after, +.file-input__label::before { + position: absolute; + content: ''; + background-color: white; + width: 16px; + height: 2px; + top: 14px; + top: 50%; + left: 12px; + left: 50%; +} + +.file-input__label::after { + transform: translate(-50%, -50%) rotate(90deg); +} +.file-input__label::before { + transform: translate(-50%, -50%); +} +.file-input__remover { + display: none; + width: 40px; + height: 30px; + text-align: center; + background-color: var(--warningbase); + grid-column-start: 3; + position: relative; +} +.file-input__remover::before { + position: absolute; + content: ''; + width: 16px; + height: 2px; + top: 14px; + left: 12px; + background-color: white; +} +.file-input__container--valid > .file-input__label { + background-color: var(--lightbase); +} +.file-input__container--valid > .file-input__label::before, +.file-input__container--valid > .file-input__label::after { + content: none; +} +.file-input__container--valid + .file-input__remover { + display: block; }