From 2abd483a3f7a4cabffe82350de8b21229bb1ea7b Mon Sep 17 00:00:00 2001 From: Marie Birner Date: Sat, 23 Sep 2023 19:19:28 +0200 Subject: [PATCH] [TASK] [NPM] install choices.js (styling copy & paste) --- frontend/logbook.ts | 10 + frontend/package.json | 3 + frontend/scss/components/_input.scss | 343 ++++++++++++++++++++- frontend/static/js/multiselect-dropdown.js | 225 -------------- templates/includes/forms/log.html.tera | 2 +- templates/log.html.tera | 5 +- 6 files changed, 359 insertions(+), 229 deletions(-) delete mode 100644 frontend/static/js/multiselect-dropdown.js diff --git a/frontend/logbook.ts b/frontend/logbook.ts index 26c5a18..8d848df 100644 --- a/frontend/logbook.ts +++ b/frontend/logbook.ts @@ -1,3 +1,13 @@ +import Choices from "choices.js"; + +const selects = document.querySelectorAll('select[multiple]'); + if(selects) { + Array.prototype.forEach.call(selects, (select: HTMLInputElement) => { + const choices = new Choices(select); + }); + } + + /*document.addEventListener('DOMContentLoaded', function() { setDistance('.set-distance-js'); }); diff --git a/frontend/package.json b/frontend/package.json index 6767a44..51e9ecb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -16,5 +16,8 @@ "typescript": "^4.9.3", "vite": "^4.2.0", "vite-plugin-static-copy": "^0.13.1" + }, + "dependencies": { + "choices.js": "^10.2.0" } } diff --git a/frontend/scss/components/_input.scss b/frontend/scss/components/_input.scss index 9660691..136715e 100644 --- a/frontend/scss/components/_input.scss +++ b/frontend/scss/components/_input.scss @@ -10,4 +10,345 @@ select { background-color: white; -webkit-appearance: none; appearance: none; -} \ No newline at end of file +} + +/* =============================== += Choices = +=============================== */ +.choices { + position: relative; + overflow: hidden; + margin-bottom: 24px; + font-size: 16px; +} +.choices:focus { + outline: none; +} +.choices:last-child { + margin-bottom: 0; +} +.choices.is-open { + overflow: visible; +} +.choices.is-disabled .choices__inner, +.choices.is-disabled .choices__input { + background-color: #eaeaea; + cursor: not-allowed; + -webkit-user-select: none; + user-select: none; +} +.choices.is-disabled .choices__item { + cursor: not-allowed; +} +.choices [hidden] { + display: none !important; +} + +.choices[data-type*=select-one] { + cursor: pointer; +} +.choices[data-type*=select-one] .choices__inner { + padding-bottom: 7.5px; +} +.choices[data-type*=select-one] .choices__input { + display: block; + width: 100%; + padding: 10px; + border-bottom: 1px solid #ddd; + background-color: #fff; + margin: 0; +} +.choices[data-type*=select-one] .choices__button { + background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg=="); + padding: 0; + background-size: 8px; + position: absolute; + top: 50%; + right: 0; + margin-top: -10px; + margin-right: 25px; + height: 20px; + width: 20px; + border-radius: 10em; + opacity: 0.25; +} +.choices[data-type*=select-one] .choices__button:hover, .choices[data-type*=select-one] .choices__button:focus { + opacity: 1; +} +.choices[data-type*=select-one] .choices__button:focus { + box-shadow: 0 0 0 2px #00bcd4; +} +.choices[data-type*=select-one] .choices__item[data-value=""] .choices__button { + display: none; +} +.choices[data-type*=select-one]::after { + content: ""; + height: 0; + width: 0; + border-style: solid; + border-color: #333 transparent transparent transparent; + border-width: 5px; + position: absolute; + right: 11.5px; + top: 50%; + margin-top: -2.5px; + pointer-events: none; +} +.choices[data-type*=select-one].is-open::after { + border-color: transparent transparent #333 transparent; + margin-top: -7.5px; +} +.choices[data-type*=select-one][dir=rtl]::after { + left: 11.5px; + right: auto; +} +.choices[data-type*=select-one][dir=rtl] .choices__button { + right: auto; + left: 0; + margin-left: 25px; + margin-right: 0; +} + +.choices[data-type*=select-multiple] .choices__inner, +.choices[data-type*=text] .choices__inner { + cursor: text; +} +.choices[data-type*=select-multiple] .choices__button, +.choices[data-type*=text] .choices__button { + position: relative; + display: inline-block; + margin-top: 0; + margin-right: -4px; + margin-bottom: 0; + margin-left: 8px; + padding-left: 16px; + border-left: 1px solid #008fa1; + background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjRkZGIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg=="); + background-size: 8px; + width: 8px; + line-height: 1; + opacity: 0.75; + border-radius: 0; +} +.choices[data-type*=select-multiple] .choices__button:hover, .choices[data-type*=select-multiple] .choices__button:focus, +.choices[data-type*=text] .choices__button:hover, +.choices[data-type*=text] .choices__button:focus { + opacity: 1; +} + +.choices__inner { + display: inline-block; + vertical-align: top; + width: 100%; + background-color: #f9f9f9; + padding: 7.5px 7.5px 3.75px; + border: 1px solid #ddd; + border-radius: 2.5px; + font-size: 14px; + min-height: 44px; + overflow: hidden; +} +.is-focused .choices__inner, .is-open .choices__inner { + border-color: #b7b7b7; +} +.is-open .choices__inner { + border-radius: 2.5px 2.5px 0 0; +} +.is-flipped.is-open .choices__inner { + border-radius: 0 0 2.5px 2.5px; +} + +.choices__list { + margin: 0; + padding-left: 0; + list-style: none; +} +.choices__list--single { + display: inline-block; + padding: 4px 16px 4px 4px; + width: 100%; +} +[dir=rtl] .choices__list--single { + padding-right: 4px; + padding-left: 16px; +} +.choices__list--single .choices__item { + width: 100%; +} + +.choices__list--multiple { + display: inline; +} +.choices__list--multiple .choices__item { + display: inline-block; + vertical-align: middle; + border-radius: 20px; + padding: 4px 10px; + font-size: 12px; + font-weight: 500; + margin-right: 3.75px; + margin-bottom: 3.75px; + background-color: #00bcd4; + border: 1px solid #00a5bb; + color: #fff; + word-break: break-all; + box-sizing: border-box; +} +.choices__list--multiple .choices__item[data-deletable] { + padding-right: 5px; +} +[dir=rtl] .choices__list--multiple .choices__item { + margin-right: 0; + margin-left: 3.75px; +} +.choices__list--multiple .choices__item.is-highlighted { + background-color: #00a5bb; + border: 1px solid #008fa1; +} +.is-disabled .choices__list--multiple .choices__item { + background-color: #aaaaaa; + border: 1px solid #919191; +} + +.choices__list--dropdown, .choices__list[aria-expanded] { + visibility: hidden; + z-index: 1; + position: absolute; + width: 100%; + background-color: #fff; + border: 1px solid #ddd; + top: 100%; + margin-top: -1px; + border-bottom-left-radius: 2.5px; + border-bottom-right-radius: 2.5px; + overflow: hidden; + word-break: break-all; + will-change: visibility; +} +.is-active.choices__list--dropdown, .is-active.choices__list[aria-expanded] { + visibility: visible; +} +.is-open .choices__list--dropdown, .is-open .choices__list[aria-expanded] { + border-color: #b7b7b7; +} +.is-flipped .choices__list--dropdown, .is-flipped .choices__list[aria-expanded] { + top: auto; + bottom: 100%; + margin-top: 0; + margin-bottom: -1px; + border-radius: 0.25rem 0.25rem 0 0; +} +.choices__list--dropdown .choices__list, .choices__list[aria-expanded] .choices__list { + position: relative; + max-height: 300px; + overflow: auto; + -webkit-overflow-scrolling: touch; + will-change: scroll-position; +} +.choices__list--dropdown .choices__item, .choices__list[aria-expanded] .choices__item { + position: relative; + padding: 10px; + font-size: 14px; +} +[dir=rtl] .choices__list--dropdown .choices__item, [dir=rtl] .choices__list[aria-expanded] .choices__item { + text-align: right; +} +@media (min-width: 640px) { + .choices__list--dropdown .choices__item--selectable, .choices__list[aria-expanded] .choices__item--selectable { + padding-right: 100px; + } + .choices__list--dropdown .choices__item--selectable::after, .choices__list[aria-expanded] .choices__item--selectable::after { + content: attr(data-select-text); + font-size: 12px; + opacity: 0; + position: absolute; + right: 10px; + top: 50%; + transform: translateY(-50%); + } + [dir=rtl] .choices__list--dropdown .choices__item--selectable, [dir=rtl] .choices__list[aria-expanded] .choices__item--selectable { + text-align: right; + padding-left: 100px; + padding-right: 10px; + } + [dir=rtl] .choices__list--dropdown .choices__item--selectable::after, [dir=rtl] .choices__list[aria-expanded] .choices__item--selectable::after { + right: auto; + left: 10px; + } +} +.choices__list--dropdown .choices__item--selectable.is-highlighted, .choices__list[aria-expanded] .choices__item--selectable.is-highlighted { + background-color: #f2f2f2; +} +.choices__list--dropdown .choices__item--selectable.is-highlighted::after, .choices__list[aria-expanded] .choices__item--selectable.is-highlighted::after { + opacity: 0.5; +} + +.choices__item { + cursor: default; +} + +.choices__item--selectable { + cursor: pointer; +} + +.choices__item--disabled { + cursor: not-allowed; + -webkit-user-select: none; + user-select: none; + opacity: 0.5; +} + +.choices__heading { + font-weight: 600; + font-size: 12px; + padding: 10px; + border-bottom: 1px solid #f7f7f7; + color: gray; +} + +.choices__button { + text-indent: -9999px; + -webkit-appearance: none; + appearance: none; + border: 0; + background-color: transparent; + background-repeat: no-repeat; + background-position: center; + cursor: pointer; +} +.choices__button:focus { + outline: none; +} + +.choices__input { + display: inline-block; + vertical-align: baseline; + background-color: #f9f9f9; + font-size: 14px; + margin-bottom: 5px; + border: 0; + border-radius: 0; + max-width: 100%; + padding: 4px 0 4px 2px; +} +.choices__input:focus { + outline: 0; +} +.choices__input::-webkit-search-decoration, .choices__input::-webkit-search-cancel-button, .choices__input::-webkit-search-results-button, .choices__input::-webkit-search-results-decoration { + display: none; +} +.choices__input::-ms-clear, .choices__input::-ms-reveal { + display: none; + width: 0; + height: 0; +} +[dir=rtl] .choices__input { + padding-right: 2px; + padding-left: 0; +} + +.choices__placeholder { + opacity: 0.5; +} + +/* ===== End of Choices ====== */ diff --git a/frontend/static/js/multiselect-dropdown.js b/frontend/static/js/multiselect-dropdown.js deleted file mode 100644 index 89d5bd9..0000000 --- a/frontend/static/js/multiselect-dropdown.js +++ /dev/null @@ -1,225 +0,0 @@ -var style = document.createElement('style'); -style.setAttribute("id","multiselect_dropdown_styles"); -style.innerHTML = ` -.multiselect-dropdown{ - display: inline-block; - border-radius: 4px; - border: solid 1px #ced4da; - background-color: white; - position: relative; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"); - background-repeat: no-repeat; - background-position: right .75rem center; - background-size: 16px 12px; - padding: 0.375rem 0.5rem; - line-height: 1.5rem; -} -.multiselect-dropdown span.optext, .multiselect-dropdown span.placeholder{ - margin-right:0.5em; - margin-bottom:2px; - padding:1px 0; - border-radius: 4px; - display:inline-block; -} -.multiselect-dropdown span.optext{ - background-color: rgba(226, 232, 240, 0.8); - padding:1px 0.75em; -} -.multiselect-dropdown span.optext .optdel { - float: right; - margin: 0 -6px 1px 5px; - font-size: 1em; - cursor: pointer; -} -.multiselect-dropdown span.optext .optdel:hover { color:#f43f5e;} -.multiselect-dropdown span.placeholder{ - color:#ced4da; -} -.multiselect-dropdown-list-wrapper{ - box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.1) 0px 1px 2px -1px; - z-index: 100; - padding:2px; - border-radius: .375rem; - border: solid 1px #ced4da; - display: none; - margin: -1px; - position: absolute; - top:0; - left: 0; - right: 0; - background: white; -} -.multiselect-dropdown-list-wrapper .multiselect-dropdown-search{ - margin-bottom:5px; - padding: 0.375rem 0.5rem; - line-height: 1.5rem; -} -.multiselect-dropdown-list{ - padding:2px; - height: 15rem; - overflow-y:auto; - overflow-x: hidden; -} -.multiselect-dropdown-list::-webkit-scrollbar { - width: 6px; -} -.multiselect-dropdown-list::-webkit-scrollbar-thumb { - background-color: rgba(226, 232, 240, 0.8); - border-radius: .375rem; -} - -.multiselect-dropdown-list div{ - padding: 5px; -} -.multiselect-dropdown-list input{ - height: 1.15em; - width: 1.15em; - margin-right: 0.35em; -} -.multiselect-dropdown-list div.checked{ -} -.multiselect-dropdown-list div:hover{ - background-color: rgba(226, 232, 240, 0.8); -} -.multiselect-dropdown span.maxselected {width:100%;} -.multiselect-dropdown-all-selector {border-bottom:solid 1px #999;} -`; -document.head.appendChild(style); - -function MultiselectDropdown(options){ - var config={ - search:true, - height:'15rem', - placeholder:'Auswählen', - txtSelected:'ausgewählt', - txtAll:'Alle', - txtRemove: 'Entfernen', - txtSearch:'Suchen', - ...options - }; - function newEl(tag,attrs){ - var e=document.createElement(tag); - if(attrs!==undefined) Object.keys(attrs).forEach(k=>{ - if(k==='class') { Array.isArray(attrs[k]) ? attrs[k].forEach(o=>o!==''?e.classList.add(o):0) : (attrs[k]!==''?e.classList.add(attrs[k]):0)} - else if(k==='style'){ - Object.keys(attrs[k]).forEach(ks=>{ - e.style[ks]=attrs[k][ks]; - }); - } - else if(k==='text'){attrs[k]===''?e.innerHTML=' ':e.innerText=attrs[k]} - else e[k]=attrs[k]; - }); - return e; - } - - - document.querySelectorAll("select[multiple]").forEach((el,k)=>{ - - var div=newEl('div',{class:'multiselect-dropdown',style:{width:config.style?.width??el.clientWidth+'px',padding:config.style?.padding??''}}); - el.style.display='none'; - el.parentNode.insertBefore(div,el.nextSibling); - var listWrap=newEl('div',{class:'multiselect-dropdown-list-wrapper'}); - var list=newEl('div',{class:'multiselect-dropdown-list',style:{height:config.height}}); - var search=newEl('input',{class:['multiselect-dropdown-search'].concat([config.searchInput?.class??'form-control']),style:{width:'100%',display:el.attributes['multiselect-search']?.value==='true'?'block':'none'},placeholder:config.txtSearch}); - listWrap.appendChild(search); - div.appendChild(listWrap); - listWrap.appendChild(list); - - el.loadOptions=()=>{ - list.innerHTML=''; - - if(el.attributes['multiselect-select-all']?.value=='true'){ - var op=newEl('div',{class:'multiselect-dropdown-all-selector'}) - var ic=newEl('input',{type:'checkbox'}); - op.appendChild(ic); - op.appendChild(newEl('label',{text:config.txtAll})); - - op.addEventListener('click',()=>{ - op.classList.toggle('checked'); - op.querySelector("input").checked=!op.querySelector("input").checked; - - var ch=op.querySelector("input").checked; - list.querySelectorAll(":scope > div:not(.multiselect-dropdown-all-selector)") - .forEach(i=>{if(i.style.display!=='none'){i.querySelector("input").checked=ch; i.optEl.selected=ch}}); - - el.dispatchEvent(new Event('change')); - }); - ic.addEventListener('click',(ev)=>{ - ic.checked=!ic.checked; - }); - el.addEventListener('change', (ev)=>{ - let itms=Array.from(list.querySelectorAll(":scope > div:not(.multiselect-dropdown-all-selector)")).filter(e=>e.style.display!=='none') - let existsNotSelected=itms.find(i=>!i.querySelector("input").checked); - if(ic.checked && existsNotSelected) ic.checked=false; - else if(ic.checked==false && existsNotSelected===undefined) ic.checked=true; - }); - - list.appendChild(op); - } - - Array.from(el.options).map(o=>{ - var op=newEl('div',{class:o.selected?'checked':'',optEl:o}) - var ic=newEl('input',{type:'checkbox',checked:o.selected}); - op.appendChild(ic); - op.appendChild(newEl('label',{text:o.text})); - - op.addEventListener('click',()=>{ - op.classList.toggle('checked'); - op.querySelector("input").checked=!op.querySelector("input").checked; - op.optEl.selected=!!!op.optEl.selected; - el.dispatchEvent(new Event('change')); - }); - ic.addEventListener('click',(ev)=>{ - ic.checked=!ic.checked; - }); - o.listitemEl=op; - list.appendChild(op); - }); - div.listEl=listWrap; - - div.refresh=()=>{ - div.querySelectorAll('span.optext, span.placeholder').forEach(t=>div.removeChild(t)); - var sels=Array.from(el.selectedOptions); - if(sels.length>(el.attributes['multiselect-max-items']?.value??5)){ - div.appendChild(newEl('span',{class:['optext','maxselected'],text:sels.length+' '+config.txtSelected})); - } - else{ - sels.map(x=>{ - var c=newEl('span',{class:'optext',text:x.text, srcOption: x}); - if((el.attributes['multiselect-hide-x']?.value !== 'true')) - c.appendChild(newEl('span',{class:'optdel',text:'x',title:config.txtRemove, onclick:(ev)=>{c.srcOption.listitemEl.dispatchEvent(new Event('click'));div.refresh();ev.stopPropagation();}})); - - div.appendChild(c); - }); - } - if(0==el.selectedOptions.length) div.appendChild(newEl('span',{class:'placeholder',text:el.attributes['placeholder']?.value??config.placeholder})); - }; - div.refresh(); - } - el.loadOptions(); - - search.addEventListener('input',()=>{ - list.querySelectorAll(":scope div:not(.multiselect-dropdown-all-selector)").forEach(d=>{ - var txt=d.querySelector("label").innerText.toUpperCase(); - d.style.display=txt.includes(search.value.toUpperCase())?'block':'none'; - }); - }); - - div.addEventListener('click',()=>{ - div.listEl.style.display='block'; - search.focus(); - search.select(); - }); - - document.addEventListener('click', function(event) { - if (!div.contains(event.target)) { - listWrap.style.display='none'; - div.refresh(); - } - }); - }); -} - -window.addEventListener('load',()=>{ - MultiselectDropdown(window.MultiselectDropdownOptions); -}); diff --git a/templates/includes/forms/log.html.tera b/templates/includes/forms/log.html.tera index 5de655c..fe1438b 100644 --- a/templates/includes/forms/log.html.tera +++ b/templates/includes/forms/log.html.tera @@ -105,7 +105,7 @@ {% macro rower_select(id, selected, amount_seats='', class='') %}
- {% for user in users %} {% set_global sel = false %} {% for rower in selected %} diff --git a/templates/log.html.tera b/templates/log.html.tera index 90e7d3f..22dbe71 100644 --- a/templates/log.html.tera +++ b/templates/log.html.tera @@ -5,7 +5,9 @@ {% block content %} {% if flash %} - {{ macros::alert(message=flash.1, type=flash.0, class="sm:col-span-2 lg:col-span-3") }} +
+ {{ macros::alert(message=flash.1, type=flash.0, class="sm:col-span-2 lg:col-span-3") }} +
{% endif %}
@@ -42,5 +44,4 @@ {% include "dynamics/sidebar" %} - {% endblock content%}