uiFilter.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. $(() => {
  2. const INPUT_CONTAINER_CLASSES = "col-12 col-xl-3 col-md-4 col-sm-6";
  3. function makeDoubleSlider(minValue, maxValue, actualMin, actualMax, serialize) {
  4. if (!serialize)
  5. serialize = i => i;
  6. let resultContainer = document.createElement("div");
  7. resultContainer.className = `slider-container ${INPUT_CONTAINER_CLASSES}`;
  8. let sliderDiv = document.createElement("div");
  9. sliderDiv.className = "container";
  10. resultContainer.appendChild(sliderDiv);
  11. let labelRow = document.createElement("div");
  12. labelRow.className = "container justify-content-between";
  13. let minValueLabel = document.createElement("input");
  14. minValueLabel.className = "slider-value slider-min-value form-control";
  15. minValueLabel.type = "text";
  16. minValueLabel.value = serialize(actualMin);
  17. labelRow.appendChild(minValueLabel);
  18. let maxValueLabel = document.createElement("input");
  19. maxValueLabel.className = "slider-value slider-max-value form-control";
  20. maxValueLabel.type = "text";
  21. maxValueLabel.value = serialize(actualMax);
  22. labelRow.appendChild(maxValueLabel);
  23. sliderDiv.appendChild(labelRow);
  24. let inputContainer = document.createElement("div");
  25. inputContainer.className = "container";
  26. sliderDiv.appendChild(inputContainer);
  27. let sliderCol = document.createElement("div");
  28. sliderCol.className = "col slider-col";
  29. inputContainer.appendChild(sliderCol);
  30. let input = document.createElement("input");
  31. input.type = "text";
  32. input.className = "col";
  33. input.dataset.sliderMin = minValue ?? 0;
  34. input.dataset.sliderMax = maxValue ?? 100;
  35. input.dataset.sliderValue = `[${actualMin},${actualMax}]`;
  36. input.dataset.sliderTooltip = "hide";
  37. sliderCol.appendChild(input);
  38. let jQueryInput = $(input);
  39. jQueryInput.slider();
  40. let onChange = () => {};
  41. jQueryInput.on('slideStop', evt => onChange({ min: evt.value[0], max: evt.value[1] }));
  42. jQueryInput.on('slide', evt => {
  43. minValueLabel.value = serialize(evt.value[0]);
  44. maxValueLabel.value = serialize(evt.value[1]);
  45. });
  46. $(minValueLabel).datepicker({
  47. format: "dd/mm/yyyy",
  48. todayBtn: "linked",
  49. autoclose: true,
  50. startDate: serialize(minValue),
  51. endDate: serialize(maxValue)
  52. }).on('changeDate', e => {
  53. let maxDate = jQueryInput.slider('getValue')[1];
  54. jQueryInput.slider("setValue", [ e.date.getTime(), maxDate ]);
  55. onChange({ min: e.date.getTime(), max: maxDate });
  56. });
  57. $(maxValueLabel).datepicker({
  58. format: "dd/mm/yyyy",
  59. todayBtn: "linked",
  60. autoclose: true,
  61. startDate: serialize(minValue),
  62. endDate: serialize(maxValue)
  63. }).on('changeDate', e => {
  64. let min = jQueryInput.slider('getValue')[0];
  65. jQueryInput.slider("setValue", [ min, e.date.getTime() ]);
  66. onChange({ min: min, max: e.date.getTime() });
  67. });
  68. return {
  69. container: resultContainer,
  70. minValueLabel: minValueLabel,
  71. maxValueLabel: maxValueLabel,
  72. input: jQueryInput,
  73. getInputValue: () => { const val = jQueryInput.slider('getValue'); return { min: val[0], max: val[1] }; },
  74. onChange: (fnc) => { onChange = fnc; }
  75. };
  76. }
  77. const EMPTY_STRING = "(Empty)";
  78. window.ReloadFilters = function(mediaManager, onNewData) {
  79. document.UiFullPageRefreshMetaDatalistes();
  80. let buildFilterBar = (labelText, canBeEmpty, possibleValues) => {
  81. let result = document.createElement("div");
  82. result.className = INPUT_CONTAINER_CLASSES;
  83. let label = document.createElement('label');
  84. result.appendChild(label);
  85. label.textContent = labelText;
  86. label.className = "container";
  87. let select = document.createElement('select');
  88. select.multiple = 'multiple';
  89. label.appendChild(select);
  90. let allPossibleValues = [].concat(canBeEmpty ? [undefined] : [], possibleValues);
  91. let currentSelection = window.FilterManager.getFilterValues(labelText);
  92. let existingValue = currentSelection.include.filter(x => allPossibleValues.indexOf(x) >= 0);
  93. if (existingValue.length != currentSelection.include.length)
  94. window.FilterManager.setFilterValue(labelText, existingValue);
  95. existingValue = currentSelection.exclude.filter(x => allPossibleValues.indexOf(x) >= 0);
  96. if (existingValue.length != currentSelection.exclude.length)
  97. window.FilterManager.setExclusionFilter(labelText, existingValue);
  98. for (let i of allPossibleValues) {
  99. let opt = document.createElement("option");
  100. opt.textContent = i ? i : EMPTY_STRING;
  101. opt.value = i ?? "";
  102. if (currentSelection.include.indexOf(opt.value) >= 0)
  103. opt.selected = true;
  104. else if (currentSelection.exclude.indexOf(opt.value) >= 0)
  105. opt.selected = opt.indeterminate = true;
  106. select.appendChild(opt);
  107. }
  108. let multiselect = makeMultiselect(select);
  109. multiselect.addEventListener(e => {
  110. let val = e.filter(i => i.checked && !i.indeterminate).map(i => i.value === EMPTY_STRING ? "" : i.value);
  111. window.FilterManager.setFilterValue(labelText, val);
  112. val = e.filter(i => i.checked && i.indeterminate).map(i => i.value === EMPTY_STRING ? "" : i.value);
  113. window.FilterManager.setExclusionFilter(labelText, val);
  114. window.FilterManager.updateFilter();
  115. });
  116. return {
  117. content: result
  118. };
  119. };
  120. let container = document.getElementById('pch-filterbar');
  121. if (container.children.length && !onNewData)
  122. return;
  123. container.textContent = '';
  124. if (MediaStorage.Instance.isLoading())
  125. return;
  126. for (let i of Object.keys(mediaManager.allMetaTypes).filter(i => mediaManager.allMetaTypes[i].type === 'string' ||
  127. [].indexOf(i) >= 0)) {
  128. let filterUi = buildFilterBar(i, mediaManager.allMetaTypes[i].canBeEmpty, Array.from(mediaManager.allMeta[i]).sort());
  129. container.appendChild(filterUi.content);
  130. }
  131. let filterUi = buildFilterBar("Tags", true, Array.from(mediaManager.allTags).sort());
  132. container.appendChild(filterUi.content);
  133. if (window.chronology.isInitialized()) {
  134. let range = window.chronology.getRange();
  135. let filteredChronology = window.FilterManager.getChronologyRange();
  136. let minChronology = Math.max(filteredChronology.min, range.min.getTime());
  137. let maxChronology = Math.min(filteredChronology.max, range.max.getTime());
  138. let timeSlider = makeDoubleSlider(range.min.getTime(), range.max.getTime(), minChronology, maxChronology, i => (new Date(i)).toLocaleDateString());
  139. timeSlider.onChange(val => window.FilterManager.setChronologyRange(val.min, val.max));
  140. container.appendChild(timeSlider.container);
  141. }
  142. }
  143. document.getElementById('pch-navbar-filterToggle').addEventListener('click', e => {
  144. e.preventDefault();
  145. let filterBarDom = document.getElementById('pch-filterbarContainer');
  146. if (filterBarDom.style.display)
  147. filterBarDom.style.display = "";
  148. else
  149. filterBarDom.style.display = "flex"
  150. });
  151. document.onClosePopinRequested(() => {
  152. document.getElementById('pch-filterbarContainer').style.display = "";
  153. });
  154. });