$(() => { const INPUT_CONTAINER_CLASSES = "col-12 col-xl-3 col-md-4 col-sm-6"; function makeDoubleSlider(minValue, maxValue, serialize) { if (!serialize) serialize = i => i; let resultContainer = document.createElement("div"); resultContainer.className = `slider-container ${INPUT_CONTAINER_CLASSES}`; let sliderDiv = document.createElement("div"); sliderDiv.className = "container"; resultContainer.appendChild(sliderDiv); let labelRow = document.createElement("div"); labelRow.className = "container justify-content-between"; let minValueLabel = document.createElement("input"); minValueLabel.className = "slider-value slider-min-value form-control"; minValueLabel.type = "text"; minValueLabel.value = serialize(minValue); labelRow.appendChild(minValueLabel); let maxValueLabel = document.createElement("input"); maxValueLabel.className = "slider-value slider-max-value form-control"; maxValueLabel.type = "text"; maxValueLabel.value = serialize(maxValue); labelRow.appendChild(maxValueLabel); sliderDiv.appendChild(labelRow); let inputContainer = document.createElement("div"); inputContainer.className = "container"; sliderDiv.appendChild(inputContainer); let sliderCol = document.createElement("div"); sliderCol.className = "col slider-col"; inputContainer.appendChild(sliderCol); let input = document.createElement("input"); input.type = "text"; input.className = "col"; input.dataset.sliderMin = minValue ?? 0; input.dataset.sliderMax = maxValue ?? 100; input.dataset.sliderValue = `[${input.dataset.sliderMin},${input.dataset.sliderMax}]`; input.dataset.sliderTooltip = "hide"; sliderCol.appendChild(input); let jQueryInput = $(input); jQueryInput.slider(); let onChange = () => {}; jQueryInput.on('slideStop', evt => onChange({ min: evt.value[0], max: evt.value[1] })); jQueryInput.on('slide', evt => { minValueLabel.value = serialize(evt.value[0]); maxValueLabel.value = serialize(evt.value[1]); }); $(minValueLabel).datepicker({ format: "dd/mm/yyyy", todayBtn: "linked", autoclose: true, startDate: serialize(minValue), endDate: serialize(maxValue) }).on('changeDate', e => { let maxDate = jQueryInput.slider('getValue')[1]; jQueryInput.slider("setValue", [ e.date.getTime(), maxDate ]); onChange({ min: e.date.getTime(), max: maxDate }); }); $(maxValueLabel).datepicker({ format: "dd/mm/yyyy", todayBtn: "linked", autoclose: true, startDate: serialize(minValue), endDate: serialize(maxValue) }).on('changeDate', e => { let min = jQueryInput.slider('getValue')[0]; jQueryInput.slider("setValue", [ min, e.date.getTime() ]); onChange({ min: min, max: e.date.getTime() }); }); return { container: resultContainer, minValueLabel: minValueLabel, maxValueLabel: maxValueLabel, input: jQueryInput, getInputValue: () => { const val = jQueryInput.slider('getValue'); return { min: val[0], max: val[1] }; }, onChange: (fnc) => { onChange = fnc; } }; } const EMPTY_STRING = "(Empty)"; window.ReloadFilters = function(mediaManager, onNewData) { let buildFilterBar = (labelText, canBeEmpty, possibleValues) => { let result = document.createElement("div"); result.className = INPUT_CONTAINER_CLASSES; let label = document.createElement('label'); result.appendChild(label); label.textContent = labelText; label.className = "container"; let select = document.createElement('select'); select.multiple = 'multiple'; label.appendChild(select); let allPossibleValues = [].concat(canBeEmpty ? [undefined] : [], possibleValues); let currentSelection = window.FilterManager.getFilterValues(labelText); let existingValue = currentSelection.include.filter(x => allPossibleValues.indexOf(x) >= 0); if (existingValue.length != currentSelection.include.length) window.FilterManager.setFilterValue(labelText, existingValue); existingValue = currentSelection.exclude.filter(x => allPossibleValues.indexOf(x) >= 0); if (existingValue.length != currentSelection.exclude.length) window.FilterManager.setExclusionFilter(labelText, existingValue); for (let i of allPossibleValues) { let opt = document.createElement("option"); opt.textContent = i ? i : EMPTY_STRING; opt.value = i ?? ""; if (currentSelection.include.indexOf(opt.value) >= 0) opt.selected = true; else if (currentSelection.exclude.indexOf(opt.value) >= 0) opt.selected = opt.indeterminate = true; select.appendChild(opt); } let multiselect = makeMultiselect(select); multiselect.addEventListener(e => { let val = e.filter(i => i.checked && !i.indeterminate).map(i => i.value === EMPTY_STRING ? "" : i.value); window.FilterManager.setFilterValue(labelText, val); val = e.filter(i => i.checked && i.indeterminate).map(i => i.value === EMPTY_STRING ? "" : i.value); window.FilterManager.setExclusionFilter(labelText, val); window.FilterManager.updateFilter(); }); return { content: result }; }; let container = document.getElementById('pch-filterbar'); if (container.children.length && !onNewData) return; container.textContent = ''; if (MediaStorage.Instance.isLoading()) return; for (let i of Object.keys(mediaManager.allMetaTypes).filter(i => mediaManager.allMetaTypes[i].type === 'string' || [].indexOf(i) >= 0)) { let filterUi = buildFilterBar(i, mediaManager.allMetaTypes[i].canBeEmpty, Array.from(mediaManager.allMeta[i]).sort()); container.appendChild(filterUi.content); } let filterUi = buildFilterBar("Tags", true, Array.from(mediaManager.allTags).sort()); container.appendChild(filterUi.content); if (window.chronology.isInitialized()) { let range = window.chronology.getRange(); let timeSlider = makeDoubleSlider(range.min.getTime(), range.max.getTime(), i => (new Date(i)).toLocaleDateString()); timeSlider.onChange(val => window.FilterManager.setChronologyRange(val.min, val.max)); container.appendChild(timeSlider.container); } } document.getElementById('pch-navbar-filterToggle').addEventListener('click', e => { e.preventDefault(); let filterBarDom = document.getElementById('pch-filterbarContainer'); if (filterBarDom.style.display) filterBarDom.style.display = ""; else filterBarDom.style.display = "flex" }); document.onClosePopinRequested(() => { document.getElementById('pch-filterbarContainer').style.display = ""; }); });