feat(projects): replace numeric Intern inputs with picker
This commit is contained in:
@@ -37,4 +37,57 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
try { localStorage.setItem('labtimesheet-sidebar', collapsed ? 'collapsed' : 'expanded'); }
|
||||
catch (_) { /* Collapse still works for this page. */ }
|
||||
});
|
||||
|
||||
document.querySelectorAll('[data-intern-picker]').forEach((picker) => {
|
||||
const open = picker.querySelector('[data-picker-open]');
|
||||
const dialog = picker.querySelector('[data-picker-dialog]');
|
||||
const search = picker.querySelector('[data-picker-search]');
|
||||
const summary = picker.querySelector('[data-picker-summary]');
|
||||
const empty = picker.querySelector('[data-picker-empty]');
|
||||
const cancel = picker.querySelector('[data-picker-cancel]');
|
||||
const apply = picker.querySelector('[data-picker-apply]');
|
||||
const options = [...picker.querySelectorAll('[data-picker-option]')];
|
||||
let initialSelection = [];
|
||||
|
||||
const inputs = () => options.map((option) => option.querySelector('input'));
|
||||
const updateSummary = () => {
|
||||
const selected = options
|
||||
.filter((option) => option.querySelector('input').checked)
|
||||
.map((option) => option.querySelector('[data-picker-label]').textContent.trim());
|
||||
summary.textContent = selected.length === 0
|
||||
? `No Intern${inputs()[0]?.type === 'radio' ? '' : 's'} selected`
|
||||
: `${selected.length} Intern${selected.length === 1 ? '' : 's'} selected: ${selected.join(', ')}`;
|
||||
};
|
||||
const filter = () => {
|
||||
const query = search.value.trim().toLocaleLowerCase();
|
||||
let visible = 0;
|
||||
options.forEach((option) => {
|
||||
option.hidden = !option.dataset.pickerSearch.toLocaleLowerCase().includes(query);
|
||||
if (!option.hidden) visible += 1;
|
||||
});
|
||||
empty.hidden = visible !== 0;
|
||||
};
|
||||
const restore = () => {
|
||||
inputs().forEach((input, index) => { input.checked = initialSelection[index]; });
|
||||
updateSummary();
|
||||
};
|
||||
|
||||
inputs().forEach((input) => input.addEventListener('change', updateSummary));
|
||||
search.addEventListener('input', filter);
|
||||
open.addEventListener('click', () => {
|
||||
initialSelection = inputs().map((input) => input.checked);
|
||||
search.value = '';
|
||||
filter();
|
||||
dialog.showModal();
|
||||
search.focus();
|
||||
});
|
||||
cancel.addEventListener('click', () => {
|
||||
restore();
|
||||
dialog.close();
|
||||
});
|
||||
dialog.addEventListener('cancel', restore);
|
||||
dialog.addEventListener('close', () => open.focus());
|
||||
apply.addEventListener('click', () => dialog.close());
|
||||
updateSummary();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user