133 lines
No EOL
5 KiB
JavaScript
133 lines
No EOL
5 KiB
JavaScript
function toggleSidebar(){document.body.classList.add('sidebar-open');}
|
||
function closeSidebar(){document.body.classList.remove('sidebar-open');}
|
||
function openModal(id){
|
||
document.getElementById(id).classList.add('open');
|
||
document.body.classList.add('modal-open');
|
||
}
|
||
function closeModal(id){
|
||
document.getElementById(id).classList.remove('open');
|
||
if(!document.querySelector('.modal-backdrop.open'))document.body.classList.remove('modal-open');
|
||
}
|
||
function closeOnBackdrop(e,id){
|
||
if(e.target===e.currentTarget)closeModal(id);
|
||
}
|
||
document.addEventListener('keydown',e=>{
|
||
if(e.key==='Escape'){
|
||
document.querySelectorAll('.modal-backdrop.open').forEach(m=>m.classList.remove('open'));
|
||
document.body.classList.remove('modal-open');
|
||
}
|
||
});
|
||
function switchTab(btn,panelId){
|
||
const tabList=btn.closest('.tab-list');
|
||
tabList.querySelectorAll('button').forEach(b=>b.classList.remove('active'));
|
||
btn.classList.add('active');
|
||
const tabs=btn.closest('.tabs');
|
||
tabs.querySelectorAll('.tab-panel').forEach(p=>p.classList.remove('active'));
|
||
document.getElementById(panelId).classList.add('active');
|
||
}
|
||
function toggleNavDd(btn){
|
||
const li=btn.closest('li');
|
||
const isOpen=li.classList.contains('open');
|
||
document.querySelectorAll('.topnav-links li.open').forEach(l=>l.classList.remove('open'));
|
||
if(!isOpen)li.classList.add('open');
|
||
}
|
||
function toggleDropdown(id){
|
||
const dd=document.getElementById(id);
|
||
const isOpen=dd.classList.contains('open');
|
||
document.querySelectorAll('.dropdown.open').forEach(d=>d.classList.remove('open'));
|
||
if(!isOpen)dd.classList.add('open');
|
||
}
|
||
function dismissAlert(btn){
|
||
const alert=btn.closest('.alert');
|
||
alert.classList.add('is-dismissing');
|
||
alert.addEventListener('transitionend',()=>alert.remove(),{once:true});
|
||
}
|
||
function sortTable(th){
|
||
const table=th.closest('table');
|
||
const col=[...th.parentElement.children].indexOf(th);
|
||
const dir=th.dataset.sort==='asc'?'desc':'asc';
|
||
table.querySelectorAll('th[data-sort]').forEach(t=>{
|
||
if(t!==th)t.dataset.sort='';
|
||
});
|
||
th.dataset.sort=dir;
|
||
const tbody=table.querySelector('tbody');
|
||
[...tbody.querySelectorAll('tr')]
|
||
.sort((a,b)=>{
|
||
const aVal=a.cells[col].textContent.trim();
|
||
const bVal=b.cells[col].textContent.trim();
|
||
const aNum=parseFloat(aVal.replace(/[^0-9.-]/g,''));
|
||
const bNum=parseFloat(bVal.replace(/[^0-9.-]/g,''));
|
||
if(!isNaN(aNum)&&!isNaN(bNum))
|
||
return dir==='asc'?aNum-bNum:bNum-aNum;
|
||
return dir==='asc'
|
||
?aVal.localeCompare(bVal,'de')
|
||
:bVal.localeCompare(aVal,'de');
|
||
})
|
||
.forEach(r=>tbody.appendChild(r));
|
||
}
|
||
function showToast(message,type='info'){
|
||
const icons={success:'✓',warning:'⚠',danger:'✕',info:'ℹ'};
|
||
if(!(type in icons))type='info';
|
||
const id='toast-'+Date.now()+'-'+Math.random().toString(36).slice(2,7);
|
||
const toast=document.createElement('div');
|
||
toast.className='toast';
|
||
toast.id=id;
|
||
toast.setAttribute('role','status');
|
||
const icon=document.createElement('span');
|
||
icon.className='toast-icon toast-icon-'+type;
|
||
icon.textContent=icons[type];
|
||
const content=document.createElement('div');
|
||
content.className='toast-content';
|
||
const title=document.createElement('p');
|
||
title.className='toast-title';
|
||
title.textContent=message;
|
||
content.appendChild(title);
|
||
const close=document.createElement('button');
|
||
close.className='toast-close';
|
||
close.type='button';
|
||
close.setAttribute('aria-label','Schließen');
|
||
close.dataset.action='toast-close';
|
||
close.textContent='×';
|
||
toast.append(icon,content,close);
|
||
document.getElementById('toast-container').appendChild(toast);
|
||
setTimeout(()=>removeToast(id),4000);
|
||
}
|
||
function removeToast(id){
|
||
const el=document.getElementById(id);
|
||
if(el){
|
||
el.classList.add('is-leaving');
|
||
setTimeout(()=>el.remove(),200);
|
||
}
|
||
}
|
||
function applyProgress(root){
|
||
(root||document).querySelectorAll('[data-progress]').forEach(el=>{
|
||
const wert=Math.max(0,Math.min(100,parseFloat(el.dataset.progress)||0));
|
||
el.style.width=wert+'%';
|
||
});
|
||
}
|
||
document.addEventListener('DOMContentLoaded',()=>applyProgress());
|
||
document.addEventListener('htmx:load',e=>applyProgress(e.target));
|
||
const frameworkActions={
|
||
'sidebar-open':()=>toggleSidebar(),
|
||
'sidebar-close':()=>closeSidebar(),
|
||
'modal-open':el=>openModal(el.dataset.target),
|
||
'modal-close':el=>closeModal(el.dataset.target||el.closest('.modal-backdrop').id),
|
||
'modal-backdrop':(el,e)=>{if(e.target===el)closeModal(el.id);},
|
||
'tab':el=>switchTab(el,el.dataset.target),
|
||
'nav-dropdown':el=>toggleNavDd(el),
|
||
'dropdown':el=>toggleDropdown(el.dataset.target||el.closest('.dropdown').id),
|
||
'alert-dismiss':el=>dismissAlert(el),
|
||
'sort':el=>sortTable(el),
|
||
'toggle-class':el=>el.classList.toggle(el.dataset.class),
|
||
'toast':el=>showToast(el.dataset.message,el.dataset.type),
|
||
'toast-close':el=>removeToast(el.closest('.toast').id),
|
||
};
|
||
document.addEventListener('click',e=>{
|
||
const el=e.target.closest('[data-action]');
|
||
const action=el&&frameworkActions[el.dataset.action];
|
||
if(action)action(el,e);
|
||
if(!e.target.closest('.topnav-links li'))
|
||
document.querySelectorAll('.topnav-links li.open').forEach(l=>l.classList.remove('open'));
|
||
if(!e.target.closest('.dropdown'))
|
||
document.querySelectorAll('.dropdown.open').forEach(d=>d.classList.remove('open'));
|
||
}); |