1jQuery3_4_1(document).ready(function($){ 2 class BoligShopFilters { 3 constructor(parent) { 4 const self = this; 5 if(parent.boligShopFilters){ 6 return; 7 } 8 parent.boligShopFilters = this; 9 this.parent = $(parent); 10 this.filters = {}; 11 this.sessionKey = 'dd-platform-bolig-filters'; 12 this.filterKeys = [ 13 'area-min', 14 'area-max', 15 'rooms-min', 16 'rooms-max', 17 'cost-min', 18 'cost-max', 19 ] 20 this.filterKeys = this.filterKeys.concat(this.parent.data("categories")); 21 this.awake(); 22 setTimeout(function(){ 23 self.start(); 24 },0); 25 } 26 27 awake(){ 28 const self = this; 29 self.filters = self.getFiltersFromUrl(); 30 self.setSliders(); 31 } 32 33 start(){ 34 const self = this; 35 // Cache controllers 36 const shopElement = self.parent.closest(".dd-bolig-shop"); 37 self.shopController = shopElement[0].boligShop; 38 const listElement = shopElement.find(".dd-bse-list"); 39 self.listController = listElement[0].boligShopList; 40 // const mapElement = shopElement.find(".dd-bse-map .dd-statemachine"); 41 // self.mapController = mapElement[0].statemachine; 42 43 44 self.listController.setInitialFilters(self.filters); 45 46 self.registerClosebutton(); 47 self.registerSliders(); 48 self.registerCheckButtons(); 49 self.registerButtons(); 50 self.registerHistoryEvents(); 51 } 52 53 getMapController(){ 54 const self = this; 55 if(self.mapController){ 56 return self.mapController; 57 } 58 const shopElement = self.parent.closest(".dd-bolig-shop"); 59 const mapElement = shopElement.find(".dd-bse-map .dd-statemachine"); 60 self.mapController = mapElement[0].statemachine; 61 return self.mapController; 62 } 63 64 reset(){ 65 const self = this; 66 self.filters = {}; 67 self.resetSliders(); 68 self.resetCheckbuttons(); 69 self.preCalculateFilters(); 70 self.applyFilters(); 71 self.saveFilters(); 72 } 73 74 open( caller = null ){ 75 const self = this; 76 self.parent.addClass('active'); 77 self.returnFocusTo = caller; 78 self.trapFocus(); 79 } 80 81 close(){ 82 const self = this; 83 self.parent.removeClass('active'); 84 self.returnFocus(); 85 } 86 87 trapFocus(){ 88 const self = this; 89 const focusables = self.parent.find('a, button, input, textarea, select, [tabindex]:not([tabindex="-1"])').filter(':visible:not(:disabled)'); 90 if ( focusables.length === 0 ) { 91 return 92 }; 93 const first = focusables.first(); 94 const last = focusables.last(); 95 first.trigger('focus'); 96 97 function handleKeydown(event) { 98 if (event.key === 'Tab') { 99 if (event.shiftKey) { 100 if (document.activeElement === first[0]) { 101 event.preventDefault(); 102 last.trigger('focus'); 103 } 104 } else { 105 if (document.activeElement === last[0]) { 106 event.preventDefault(); 107 first.trigger('focus'); 108 } 109 } 110 } 111 112 if (event.key === 'Escape') { 113 close(); // your close logic 114 } 115 } 116 117 self.parent.on('keydown.trapFocus', handleKeydown); 118 } 119 120 returnFocus(){ 121 const self = this; 122 self.parent.off('keydown.trapFocus'); 123 if(self.returnFocusTo){ 124 if ( ! ( self.returnFocusTo && typeof self.returnFocusTo === 'object' && 'jquery' in self.returnFocusTo ) ) { 125 self.returnFocusTo = $(self.returnFocusTo); 126 } 127 self.returnFocusTo.trigger('focus'); 128 } else { 129 console.warn("Caller not defined. No place to return focus to."); 130 } 131 self.returnFocusTo = null; 132 } 133 134 saveFilters(){ 135 const self = this; 136 const filters = self.getFiltersFromUrl(); 137 if(objectEqual(filters, self.filters)){ 138 return; 139 } 140 const historySettings = self.getHistorySettings();
141 DDPlatform.history.push(historySettings); 142 } 143 144 getHistorySettings(){ 145 const self = this; 146 const result = {}; 147 this.filterKeys.forEach(key => { 148 result[key] = self.filters[key]; 149 }); 150 return result; 151 } 152 153 getFiltersFromUrl(){ 154 const self = this; 155 const filters = self.parseUrlParameters(); 156 // console.log("Filters from URL:", filters); 157 return filters; 158 } 159 160 parseUrlParameters() { 161 const self = this; 162 const result = {}; 163 let url = new URL(window.location); 164 self.filterKeys.forEach(key => { 165 let paramValue = url.searchParams.get(key); 166 if(paramValue !== null) { 167 if(paramValue.includes("~")){ 168 paramValue = paramValue.split("~"); 169 result[key] = paramValue; 170 } else if ( isNumeric(paramValue) ) { 171 paramValue = parseInt(paramValue); 172 result[key] = paramValue; 173 } else if ( paramValue.toLowerCase() == 'false' ) { 174 175 } else if ( paramValue.toLowerCase() == 'true' ) { 176 paramValue = true; 177 result[key] = paramValue; 178 } 179 } 180 }); 181 return result; 182 } 183 184 preCalculateFilters(){ 185 const self = this; 186 // const list = self.parent.closest(".dd-bolig-shop").find(".dd-bse-list"); 187 // const controller = list[0].boligShopList; 188 // const count = controller.preCalculateFilters(self.filters); 189 // console.log("self.filters", self.filters); 190 const preFilteredResidencies = self.shopController.prefilterResidenciesDataset(self.filters); 191 // console.log("preFilteredResidencies:", preFilteredResidencies); 192 self.filteredCount = preFilteredResidencies.length; 193 self.updatePrecalculatedFilteredCount(self.filteredCount); 194 } 195 196 syncSlidersToFilters(){ 197 const self = this; 198 ["cost", "rooms", "area"].forEach(function(type){ 199 const el = self.parent.find(".dd-filter-slider-" + type); 200 if ( !el.length || !el[0].rangeSlider ) return; 201 const rs = el[0].rangeSlider; 202 if ( rs.currentMin !== rs.min || rs.currentMax !== rs.max ) { 203 self.filters[type + "-min"] = rs.currentMin; 204 self.filters[type + "-max"] = rs.currentMax; 205 } else { 206 delete self.filters[type + "-min"]; 207 delete self.filters[type + "-max"]; 208 } 209 }); 210 } 211 212 applyFilters(){ 213 const self = this; 214 self.syncSlidersToFilters(); 215 self.preCalculateFilters(); 216 const isFiltering = Object.keys(self.filters).length !== 0; 217 self.shopController.toggleIsFiltering(isFiltering); 218 self.getMapController().applyFilters(self.filters); 219 self.listController.applyFilters(self.filters); 220 self.listController.resetPaginationValues(self.filteredCount); 221 self.applyBadgeCountToButtons(); 222 // self.updateFilteredCount(self.filteredCount); 223 } 224 225 // applyFiltersToList(){ 226 // const self = this; 227 // // const list = self.parent.closest(".dd-bolig-shop").find(".dd-bse-list"); 228 // // const controller = list[0].boligShopList; 229 // self.listController.applyFilters(self.filters); 230 // // const count = controller.applyFilters(self.filters); 231 // // self.updateFilteredCount(count); 232 // } 233 234 // applyFiltersToMap(){ 235 // const self = this; 236 // // const statemachine = self.parent.closest(".dd-bolig-shop").find(".dd-bse-map .dd-statemachine"); 237 // // const controller = statemachine[0].statemachine; 238 // // controller.applyFilters(self.filters); 239 // self.mapController.applyFilters(self.filters); 240 // } 241 242 applyBadgeCountToButtons(){ 243 const self = this; 244 // const count = Object.keys(self.filters).length; 245 const count = Object.keys(self.filters).filter(key => !key.includes('-max')).length; 246 if( count > 0 ){ 247 $(".dd-button.dd-action-open-filtrer").attr("data-badge-count", count); 248 } else { 249 $(".dd-button.dd-action-open-filtrer").removeAttr("data-badge-count"); 250 } 251 } 252 253 updatePrecalculatedFilteredCount(count){ 254 const self = this; 255 self.parent.find(".dd-filter-button-show .dd-bse-filtermenu-result-count").html(count); 256 } 257 258 // updateFilteredCount(count){ 259 // const self = this; 260 // self.parent.closest(".dd-bolig-shop").find(".dd-bse-list-counter").data("value", count).attr("data-value", count).find(".dd-value").html(count); 261 // self.parent.closest(".dd-bolig-shop").find(".dd-filtered-boliger-value").html(count); 262 // } 263 264 setCheckButtons(){ 265 const self = this; 266 self.parent.find(".dd-checkbutton input").prop("checked", false); 267 for (let key in self.filters) { 268 if (self.filters.hasOwnProperty(key)) { 269 const value = self.filters[key] ? true : false; 270 self.parent.find(".dd-checkbutton input[data-slug='"+key+"']").prop("checked", value); 271 } 272 } 273 } 274 275 setSliders(){ 276 const self = this; 277 self.resetSliders(); 278 self.setSlider("cost"); 279 self.setSlider("rooms"); 280 self.setSlider("area"); 281 } 282 283 setSlider(type){ 284 const self = this; 285 const elements = self.parent.find(".dd-filter-slider-"+type); 286 if(elements.length == 0){ 287 console.warn("No slider found in filters."); 288 return; 289 } 290 const controller = elements[0].rangeSlider; 291 const args = {};
292 if(self.filters[type+"-min"]) { 293 args["min"] = self.filters[type+"-min"]; 294 } 295 if(self.filters[type+"-max"]) { 296 args["max"] = self.filters[type+"-max"]; 297 } 298 if( typeof args === 'object' && args.min !== undefined && args.max !== undefined ) { 299 controller.set(args); 300 } 301 } 302 303 resetSliders(){ 304 const self = this; 305 const elements = self.parent.find(".dd-rangeslider"); 306 elements.each(function(){ 307 const controller = this.rangeSlider; 308 controller.reset(); 309 }); 310 } 311 312 resetCheckbuttons(){ 313 const self = this; 314 const elements = self.parent.find(".dd-checkbutton input"); 315 elements.each(function(){ 316 $(this).prop("checked", false); 317 }); 318 } 319 320 // EVENTS 321 registerClosebutton(){ 322 const self = this; 323 self.parent.find(".dd-popup-menu-closebutton").on('click', function(event){ 324 // self.saveFilters(); 325 self.close(); 326 }); 327 self.parent.find(".dd-popup-menu-bg").on('click', function(event){ 328 // self.saveFilters(); 329 self.close(); 330 }); 331 } 332 333 registerButtons(){ 334 const self = this; 335 self.parent.find(".dd-filter-button-clear").on('click', function(event){ 336 self.reset(); 337 self.close(); 338 }); 339 self.parent.find(".dd-filter-button-show").on('click', function(event){ 340 self.applyFilters(); 341 self.saveFilters(); 342 self.close(); 343 }); 344 } 345 346 registerHistoryEvents(){ 347 const self = this; 348 DDPlatform.history.on("pop", function(event){ 349 const filters = self.getFiltersFromUrl(); 350 if(objectEqual(filters, self.filters)){ 351 return; 352 } 353 self.filters = self.getFiltersFromUrl(); 354 self.setSliders(); 355 self.setCheckButtons(); 356 self.applyFilters(); 357 }); 358 } 359 360 registerCheckButtons(){ 361 const self = this; 362 self.parent.find(".dd-checkbutton input").on('change', function(event){ 363 const input = event.currentTarget; 364 const category = $(input).data("slug"); 365 if(input.checked){ 366 self.filters[category] = input.checked; 367 } else { 368 delete self.filters[category]; 369 } 370 self.preCalculateFilters(); 371 // self.applyFilters(); 372 }); 373 374 } 375 376 registerSliders(){ 377 const self = this; 378 self.registerSlider("cost"); 379 self.registerSlider("rooms"); 380 self.registerSlider("area"); 381 } 382 383 registerSlider(type){ 384 const self = this; 385 const elements = self.parent.find(".dd-filter-slider-"+type); 386 if(elements.length == 0){ 387 return; 388 } 389 const controller = elements[0].rangeSlider; 390 controller.on('change', function(min, max){ 391 self.filters[type+"-min"] = min; 392 self.filters[type+"-max"] = max; 393 self.preCalculateFilters(); 394 // self.applyFilters(); 395 }); 396 } 397 } 398 399 registerOnLoadEvent(function(){ 400 $(".dd-bse-filtermenu").each(function(){ 401 new BoligShopFilters(this); 402 }) 403 }); 404});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.