1document.addEventListener('DOMContentLoaded', () => { 2 const appElement = document.getElementById('app'); 3 const initialEvents = JSON.parse(appElement.dataset.initialEvents || '[]'); 4 const initialFilter = JSON.parse(appElement.dataset.initialFilter || '{}'); 5 const showMore = appElement.dataset.showMore === 'true'; 6 7 const { createApp } = Vue; 8 9 createApp({ 10 data() { 11 return { 12 cityFilter: { 13 defaultFilterText: "ÐÑе гоÑода", 14 multipleChoiceText: "ÐÑбÑано гоÑодов ", 15 filterText: "ÐÑе гоÑода", 16 data: [], 17 }, 18 locationFilter: { 19 defaultFilterText: "ÐÑе ÑÑадионÑ", 20 multipleChoiceText: "ÐÑбÑано ÑÑадионов ", 21 filterText: "ÐÑе ÑÑадионÑ", 22 data: [], 23 }, 24 eventTypesFilter: { 25 defaultFilterText: "ÐÑе каÑегоÑии", 26 multipleChoiceText: "ÐÑбÑано каÑегоÑий ", 27 filterText: "ÐÑе каÑегоÑии", 28 data: [], 29 }, 30 liguesFilter: { 31 defaultFilterText: "ÐÑе лиги", 32 multipleChoiceText: "ÐÑбÑано лиг ", 33 filterText: "ÐÑе лиги", 34 data: [], 35 }, 36 date: { 37 defaultText: { from: "ÐеÑиод оÑ", to: "до" }, // ÑекÑÑ Ð¿Ð¾ ÑмолÑÐ°Ð½Ð¸Ñ Ð´Ð»Ñ ÑилÑÑÑов даÑÑ 38 text: { from: "ÐеÑиод оÑ", to: "до" }, 39 data: { from: "", to: "" }, 40 }, 41 events: initialEvents, 42 page: 1, 43 showSelects: { 44 CITY: true, 45 LOCATION: true, 46 EVENT_TYPE: true, 47 LIGA: false, 48 }, 49 showTestEvents: false, 50 noEvents: false, 51 saveFilterObj: {}, // обÑÐµÐºÑ Ð´Ð»Ñ ÑÐ¾Ñ ÑÐ°Ð½ÐµÐ½Ð¸Ñ Ñого ÑилÑÑÑа, по коÑоÑÐ¾Ð¼Ñ Ð¿ÑоиÑÑ Ð¾Ð´Ð¸Ñ Ð¿Ð¾Ð¸Ñк 52 searchInput: "", // ÑÑÑ Ñ ÑанÑÑÑÑ Ð´Ð°Ð½Ð½Ñе о ÑекÑÑовом поле поиÑка 53 filterResetButtonEnable: false, // пеÑеклÑÑаÑÐµÐ»Ñ Ð°ÐºÑивноÑÑи кнопки ÑбÑоÑа ÑилÑÑÑов 54 typingTimer: null, // ÑÐ°Ð¹Ð¼ÐµÑ Ð´Ð»Ñ Ð¾ÑÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð²Ð²Ð¾Ð´Ð° в ÑекÑÑовое поле поиÑка 55 showMoreButtonEnable: showMore, // ÑвойÑÑво конÑÑолиÑÑÐµÑ Ð¿Ð¾ÐºÐ°Ð·ÑваÑÑ Ð»Ð¸ ÐºÐ½Ð¾Ð¿ÐºÑ "ÐÐÐÐÐÐТЬ ÐЩÐ" 56 toAllEventsButtonEnable: false, // ÑвойÑÑво конÑÑолиÑÑÐµÑ Ð¿Ð¾ÐºÐ°Ð·ÑваÑÑ Ð»Ð¸ ÐºÐ½Ð¾Ð¿ÐºÑ "ÐÐ ÐСÐÐ ÐÐÐ ÐÐÐ ÐЯТÐЯÐ" 57 checkFirstClickToDatepicker: true, // пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð´Ð»Ñ Ð¾ÑÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¿ÐµÑвого нажаÑÐ¸Ñ Ð½Ð° календаÑÑ Ð½Ð° новом дизайне 58 eventsNotFound: false, // показÑваÑÑ\ÑкÑÑваÑÑ ÑообÑение о Ñом, ÑÑо ÑобÑÑий не найдено 59 preLoader: false, // ÐÐÐ\ÐЫÐРоÑобÑажение пÑелоÑдеÑа 60 dateRange: { 61 // ÑекÑÑ Ð½Ð° ÑилÑÑÑе по даÑам на новом дизайне 62 defaultText: "ÐÑбеÑиÑе даÑÑ", // ÑекÑÑ Ð¿Ð¾ ÑмолÑÐ°Ð½Ð¸Ñ Ð´Ð»Ñ ÑилÑÑÑа даÑÑ Ð½Ð¾Ð²Ð¾Ð³Ð¾ дизайне 63 text: "ÐÑбеÑиÑе даÑÑ", 64 }, 65 }; 66 }, 67 methods: { 68 // ÐÐÐ ÐÐÐЯЮ ÐÐÐÐЫРФÐÐЬТРРРPHP Ð ÐÐ ÐÐÐÐÐЮ ÐÐÐÐЫРÐÐÐ ÐТÐÐ 69 fetchEvents() { 70 if (document.getElementById("bx-panel-top")) 71 this.showTestEvents = true; 72 73 this.preLoader = true; 74 data = this.getFilterData(); 75 // ÐºÐ»Ð°Ð´Ñ Ð² даннÑе инÑоÑмаÑÐ¸Ñ Ð¾ адÑеÑе Ñой ÑÑÑаниÑÑ Ñ ÐºÐ¾ÑоÑой пÑоиÑÑ Ð¾Ð´Ð¸Ñ Ð·Ð°Ð¿ÑÐ¾Ñ 76 data.LOCATION_HREF = window.location.href; 77 78 // console.log('ajax query!'); 79 // console.log(data); 80 81 $.ajax({ 82 url: "/api/controllers/filter/get/", 83 type: "POST", 84 data: data, 85 success: (res) => { 86 try { 87 if (res.status == "success") res = res.data[0]; 88 else return false;
89 90 this.drawFilterForm(res.FILTER); 91 this.preLoader = false; 92 this.showMoreButtonEnable = res.SHOW_MORE_BUTTON; 93 this.noEvents = res.NO_EVENT; 94 this.events = res.EVENTS; 95 this.showSelects = res.SHOW_SELECTS; 96 97 // console.log( res ) 98 // console.log( '---------' ) 99 } catch (error) { 100 console.error("ÐÑибка", error.message); 101 console.log(res); 102 } 103 }, 104 error: function (xhr, status, error) { 105 console.error("ÐÑибка AJAX:", error); 106 }, 107 }); 108 }, 109 110 getSelectData(target) { 111 if (Object.keys(target).length === 0) { 112 return []; 113 } else { 114 return target 115 .filter((data) => data.selected) // ФилÑÑÑÑем обÑекÑÑ, где selected Ñавно true 116 .map((data) => data.value); // Ðзвлекаем знаÑÐµÐ½Ð¸Ñ value 117 } 118 }, 119 120 getFilterData() { 121 return { 122 CITY: this.getSelectData(this.cityFilter.data), 123 LOCATION: this.getSelectData(this.locationFilter.data), 124 CATEGORY: this.getSelectData(this.eventTypesFilter.data), 125 LIGA: this.getSelectData(this.liguesFilter.data), 126 Q: this.searchInput, 127 DATE_FROM: this.date.data.from, 128 DATE_TO: this.date.data.to, 129 PAGE: this.page, 130 SHOW_TEST: this.showTestEvents, 131 }; 132 }, 133 134 // Ð ÐСУЮ ФÐÐ ÐУ ФÐÐЬТРР135 drawFilterForm(data) { 136 // console.log('draw filter form') 137 // console.log(data) 138 this.cityFilter.data = data.CITY; 139 this.locationFilter.data = data.LOCATION; 140 this.eventTypesFilter.data = data.EVENT_TYPE; 141 this.liguesFilter.data = data.LIGA; 142 143 // еÑли еÑÑÑ ÑÐ¾Ñ ÑанÑÐ½Ð½Ð°Ñ Ð°ÐºÑÐ¸Ð²Ð½Ð°Ñ ÑоÑма, Ñо пÑиÑваиваем ÐµÑ Ð½ÑÐ¶Ð½Ð¾Ð¼Ñ Ð¾Ð±ÑекÑÑ 144 if (JSON.stringify(this.saveFilterObj) !== "{}") { 145 [ 146 this.cityFilter, 147 this.locationFilter, 148 this.eventTypesFilter, 149 this.liguesFilter, 150 ].forEach((filter, index) => { 151 if ( 152 this.saveFilterObj.defaultFilterText == filter.defaultFilterText 153 ) 154 Object.assign(filter, this.saveFilterObj); 155 }); 156 } 157 158 [ 159 this.cityFilter, 160 this.locationFilter, 161 this.eventTypesFilter, 162 this.liguesFilter, 163 ].forEach((filter, index) => { 164 this.writeTextOnFilter(filter); 165 }); 166 167 // еÑли даннÑÑ Ð½Ðµ пÑиÑло, Ñо иниÑиализиÑоваÑÑ datepicker не ÑÑÐ¾Ð¸Ñ 168 if (Array.isArray(data.DATE.DATA) && data.DATE.DATA.length !== 0) 169 this.initDatepickers( 170 data.DATE.DATE_MAX, 171 data.DATE.DATE_MIN, 172 data.DATE.DATA.map((dateTime) => dateTime.split(" ")[0]), 173 ); 174 175 this.eventsNotFound = this.locationFilter.data.length === 0; 176 177 if (window.location.pathname == "/") 178 this.toAllEventsButtonEnable = true; 179 180 this.changeUrl(); 181 }, 182 183 // ÐТСÐÐÐÐÐÐЮ ÐÐÐÐ ÐÐ ÐÐÐÐÐÐТ ФÐÐЬТРР184 selectorClick(e) { 185 const exceptionArray = [ 186 "ui-icon-circle-triangle-w", 187 "ui-icon-circle-triangle-e", 188 ]; 189 if ( 190 exceptionArray.some((str) => e.target.outerHTML.includes(str)) && 191 !["search-form__selector--date-range"].some((str) => 192 e.target.outerHTML.includes(str), 193 ) 194 ) { 195 return false; 196 } 197 // показаÑÑ\ÑбÑаÑÑ Ð¾ÐºÐ½Ð¾ вÑбоÑа в ÑилÑÑÑе 198 const clickedListElement = e.currentTarget.querySelector( 199 ".search-form__selector-list", 200 ); 201 // добавлÑÑ ÑкÑолл, еÑли ÑлеменÑов в ÑилÑÑÑе > 5 202 if ( 203 clickedListElement.querySelectorAll(".search-form__selector-option") 204 .length > 5 205 ) { 206 clickedListElement.classList.add("scroll"); 207 } 208 // ÑбиÑÐ°Ñ Ð¾ÑобÑажение ÑилÑÑа Ñ Ð²ÑÐµÑ , кÑоме Ñого на коÑоÑÑй кликнÑли 209 document 210 .querySelectorAll("div.search-form__selector-list") 211 .forEach((element) => { 212 if (element !== clickedListElement) 213 element.classList.remove("show"); 214 }); 215 clickedListElement.classList.toggle("show"); 216 }, 217 218 // ÐÐÐÐÐÐТЬ СÐРЫТЫРФÐÐЬТРЫ Ð ÐÐÐÐÐЬÐÐÐ ÐÐРСÐÐ ÐÐÐÐÐÐ ÐÐÐÐÐÐÐ 219 shoeMoreButton(e) { 220 if (e.target.classList.contains("show")) { 221 e.target.classList.remove("show"); 222 document 223 .querySelector(".search-form__row-select") 224 .classList.remove("show"); 225 } else { 226 e.target.classList.add("show"); 227 document 228 .querySelector(".search-form__row-select") 229 .classList.add("show"); 230 } 231 }, 232 233 // ÐÐÐ ÐÐÐТЧÐÐ ÐÐÐÐШÐÐÐЫРРHTML 234 selectFilter(pieceObj, fullObj) { 235 if (!pieceObj) { 236 fullObj.data.forEach((data) => (data.selected = false)); 237 this.saveFilterObj = {}; 238 } else { 239 pieceObj.selected = !pieceObj.selected; 240 this.saveFilterObj = Object.assign({}, fullObj); 241 } 242 this.fetchEvents(); 243 }, 244 245 // ÐÐÐÐÐРСÐÐÐЫ ТÐÐСТРÐРФÐÐЬТРР246 writeTextOnFilter(target) { 247 let selectedCount = target.data.filter( 248 (data) => data.selected, 249 ).length; 250 if (selectedCount == 0) { 251 target.filterText = target.defaultFilterText; 252 } else if (selectedCount == 1) { 253 target.filterText = target.data.find((data) => data.selected).name; 254 } else { 255 target.filterText = 256 target.multipleChoiceText + selectedCount + "ÑÑ."; 257 } 258 259 if (target.data.length == 1) target.filterText = target.data[0].name; 260 }, 261 262 onSearchInputChange() { 263 // ÐÑиÑÑка пÑедÑдÑÑего ÑаймеÑа, еÑли он бÑл задан 264 clearTimeout(this.typingTimer); 265 // УÑÑановка нового ÑаймеÑа 266 this.typingTimer = setTimeout(() => { 267 if (this.searchInput.trim() == "") this.searchInput = ""; 268 this.fetchEvents(); 269 }, 1000); 270 }, 271 272 checkAllSelectedFalse(target) { 273 return (allSelectedFalse = !target.every( 274 (city) => city.selected === false, 275 )); 276 }, 277 278 checkFiltersFull() { 279 return ( 280 this.checkAllSelectedFalse(this.cityFilter.data) || 281 this.checkAllSelectedFalse(this.locationFilter.data) || 282 this.checkAllSelectedFalse(this.eventTypesFilter.data) || 283 this.checkAllSelectedFalse(this.liguesFilter.data) || 284 this.searchInput.trim() !== "" || 285 this.date.data.from !== "" || 286 this.date.data.to !== "" || 287 this.page > 1 288 ); 289 }, 290 291 resetButtonSwitch() { 292 this.filterResetButtonEnable = this.checkFiltersFull(); 293 }, 294 295 resetFilter() { 296 if (this.filterResetButtonEnable && this.checkFiltersFull()) { 297 this.filterResetButtonEnable = false;
298 this.page = 1; 299 this.checkFirstClickToDatepicker = true; 300 this.dateRange.text = this.dateRange.defaultText; 301 this.saveFilterObj = {}; 302 this.searchInput = ""; 303 this.date.data.from = ""; 304 this.date.data.to = ""; 305 this.date.text.from = this.date.defaultText.from; 306 this.date.text.to = this.date.defaultText.to; 307 this.cityFilter.filterText = this.cityFilter.defaultFilterText; 308 this.locationFilter.filterText = 309 this.locationFilter.defaultFilterText; 310 this.eventTypesFilter.filterText = 311 this.eventTypesFilter.defaultFilterText; 312 this.liguesFilter.filterText = this.liguesFilter.defaultFilterText; 313 this.cityFilter.data.forEach((city) => { 314 city.selected = false; 315 }); // УÑÑанавливаем Ñ Ð³Ð¾Ñодов поле selected в false 316 this.locationFilter.data.forEach((location) => { 317 location.selected = false; 318 }); // УÑÑанавливаем Ñ ÑÑадионов поле selected в false 319 this.eventTypesFilter.data.forEach((eventType) => { 320 eventType.selected = false; 321 }); // УÑÑанавливаем Ñ ÐºÐ°ÑегоÑий поле selected в false 322 this.liguesFilter.data.forEach((ligue) => { 323 ligue.selected = false; 324 }); // УÑÑанавливаем Ñ Ð»Ð¸Ð³ поле selected в false 325 this.fetchEvents(); 326 } 327 }, 328 329 // ÐТРÐÐÐТЫÐÐЮ ÐÐÐÐТÐÐ ÐÐ ÐÐÐУÐÐÐТ ÐÐРСÐÐÐÐ¥ ФÐÐЬТРÐÐ 330 clickOutsideFilters(e) { 331 const isClickInside = e.target.closest(".search-form__row-select"); 332 var classAttr = $(e.target).attr("class"); 333 if (!isClickInside && classAttr && classAttr.indexOf("ui-") < 0) { 334 document 335 .querySelectorAll(".search-form__selector-list") 336 .forEach((element) => { 337 element.classList.remove("show"); 338 }); 339 } 340 }, 341 342 // ÐÐÐÐÐÐЯÐÐ Ð ÐÐÐ ÐСÐУЮ СТРÐÐУ ÐÐÐÐЫРÐРФÐÐЬТРР343 changeUrl() { 344 let url = window.location, 345 params = new URLSearchParams(window.location.search), 346 data = this.getFilterData(); 347 348 if (params.has("PAGE")) params.delete("PAGE"); 349 if (data.PAGE == 1) delete data.PAGE; 350 351 if (params.has("SHOW_TEST")) params.delete("SHOW_TEST"); 352 delete data.SHOW_TEST; 353 354 for (const key in data) { 355 if (data[key].length == 0 || params.has(key)) params.delete(key); 356 if (data[key].length != 0) params.append(key, data[key]); 357 } 358 359 const new_url = new URL( 360 `${url.origin}${url.pathname}?${params.toString()}`, 361 ); 362 // ÑÑÑ ÑбиÑаем знако вопÑоÑа в конÑе ÑÑÑоки, еÑли он поÑвлÑеÑÑÑ 363 if (new_url.href.endsWith("?")) 364 new_url.href = new_url.href.slice(0, -1); 365 history.pushState({ url: url.search }, null, new_url.href); 366 }, 367 368 // ФÐÐЬТРÐЦÐЯ ÐÐÐÐÐÐТÐÐ ÐÐÐÐ ÐЯСЬ ÐÐ ÐÐÐ ÐÐÐТРЫ ÐÐ URL 369 filterByUrl() { 370 let checkUrlParam = false, 371 url = new URL(window.location.href), 372 keys = url.searchParams.keys(); 373 374 Array.from(keys).forEach((key) => { 375 if ( 376 [ 377 "CITY", 378 "LOCATION", 379 "CATEGORY", 380 "LIGA", 381 "Q", 382 "DATE_FROM", 383 "DATE_TO", 384 "PAGE", 385 ].includes(key) 386 ) { 387 let value = url.searchParams.get(key).split(","); 388 for (const res of value) { 389 if (key == "CITY") 390 this.cityFilter.data.push({ 391 name: res, 392 value: res, 393 selected: true, 394 }); 395 if (key == "LOCATION") 396 this.locationFilter.data.push({ 397 name: res, 398 value: res, 399 selected: true, 400 }); 401 if (key == "CATEGORY") 402 this.eventTypesFilter.data.push({ 403 name: res, 404 value: res, 405 selected: true, 406 }); 407 if (key == "LIGA") 408 this.liguesFilter.data.push({ 409 name: res, 410 value: res, 411 selected: true, 412 }); 413 if (key == "Q") this.searchInput = res; 414 415 if (key == "PAGE") this.page = res; 416 417 if (key == "DATE_FROM") { 418 this.date.text.from = this.formatDate(res); 419 this.date.data.from = res; 420 } 421 if (key == "DATE_TO") { 422 this.date.text.to = this.formatDate(res); 423 this.date.data.to = res; 424 } 425 checkUrlParam = true; 426 } 427 } 428 }); 429 430 if (this.date.data.from && this.date.data.to) { 431 this.dateRange.text = this.date.text.from + " - " + this.date.text.to; 432 } 433 434 return !checkUrlParam; 435 }, 436 437 formatDate(dateString) { 438 const parts = dateString.split("-"); 439 return `${parts[2]}.${parts[1]}.${parts[0]}`; 440 }, 441 442 showMoreButton() { 443 this.page = this.page + 1; 444 this.fetchEvents(); 445 }, 446 447 toAllEventsButton(e) { 448 let url = window.location, 449 params = new URLSearchParams(window.location.search), 450 data = this.getFilterData(); 451 452 for (const key in data) { 453 if (data[key].length == 0 || params.has(key)) params.delete(key); 454 if (data[key].length != 0) params.append(key, data[key]); 455 } 456 457 if (params.has("PAGE")) params.delete("PAGE"); 458 459 if (params.has("SHOW_TEST")) params.delete("SHOW_TEST"); 460 461 const new_url = new URL( 462 `${url.origin}/${e.currentTarget.getAttribute("data-iss")}/?${params.toString()}`, 463 ); 464 // ÑÑÑ ÑбиÑаем знако вопÑоÑа в конÑе ÑÑÑоки, еÑли он поÑвл
464ÑеÑÑÑ 465 if (new_url.href.endsWith("?")) 466 new_url.href = new_url.href.slice(0, -1); 467 468 window.location.href = new_url.href; 469 }, 470 471 fastDateFilter(e) { 472 this.date.data.from = e.target.dataset.start; 473 this.date.data.to = e.target.dataset.end; 474 this.date.text.from = this.formatDate(e.target.dataset.start); 475 this.date.text.to = this.formatDate(e.target.dataset.end); 476 this.checkFirstClickToDatepicker = true; 477 this.dateRange.text = 478 this.date.text.from + " - " + this.date.text.to; 479 this.fetchEvents(); 480 }, 481 482 // ÐÑеобÑазÑÐµÑ Ð´Ð°ÑÑ ÑилÑÑÑа из YYYY-MM-DD в локалÑнÑй обÑÐµÐºÑ Date. 483 parseFilterDate(dateString) { 484 const [year, month, day] = dateString.split("-").map(Number); 485 return new Date(year, month - 1, day); 486 }, 487 488 // ÐолÑÑÐ°ÐµÑ Ð´Ð°ÑÑ Ð¸Ð· DOM-ÑÑейки, коÑоÑÑÑ ÑгенеÑиÑовал jQuery UI Datepicker. 489 getDatepickerCellDate(cell) { 490 const day = Number(cell.querySelector("a")?.textContent); 491 const year = Number(cell.dataset.year);
492 const month = Number(cell.dataset.month); 493 494 if (!day || Number.isNaN(year) || Number.isNaN(month)) return null; 495 496 return new Date(year, month, day); 497 }, 498 499 // РаÑÑÑавлÑÐµÑ CSS-клаÑÑÑ Ð½Ð°Ñала, конÑа и пÑомежÑÑка диапазона. 500 // previewDate иÑполÑзÑеÑÑÑ Ð´Ð»Ñ Ð¿ÑедпÑоÑмоÑÑа диапазона до вÑоÑого клика. 501 paintDateRange(datepickerRange, previewDate = null) { 502 const cells = datepickerRange.find("td[data-handler='selectDay']"); 503 cells.removeClass("dp-highlight dp-range-start dp-range-end"); 504 505 if (!this.date.data.from) return; 506 507 const startDate = this.parseFilterDate(this.date.data.from); 508 const endDate = previewDate || 509 (this.date.data.to 510 ? this.parseFilterDate(this.date.data.to) 511 : startDate); 512 const rangeStart = Math.min(startDate.getTime(), endDate.getTime()); 513 const rangeEnd = Math.max(startDate.getTime(), endDate.getTime()); 514 515 cells.each((index, cell) => { 516 const cellDate = this.getDatepickerCellDate(cell); 517 if (!cellDate) return; 518 519 const cellTime = cellDate.getTime(); 520 if (cellTime >= rangeStart && cellTime <= rangeEnd) 521 cell.classList.add("dp-highlight"); 522 if (cellTime === startDate.getTime()) 523 cell.classList.add("dp-range-start"); 524 if ( 525 cellTime === endDate.getTime() && 526 endDate.getTime() !== startDate.getTime() 527 ) 528 cell.classList.add("dp-range-end"); 529 }); 530 }, 531 532 initDatepickers(dateMax, dateMin, datesWithEvents) { 533 var datepickerContainer = $(".search-form__selector-list--date"), 534 datepickerStart = $(".search-form__date-selector--start"), 535 datepickerEnd = $(".search-form__date-selector--end"), 536 datepickerRange = $(".search-form__date-selector--range"), 537 activeFilterTextColor = "#233550"; 538 539 // еÑли datepicker-Ñ Ñже иниÑиализиÑованÑ, Ñо ÑÐ±Ð¸Ð²Ð°Ñ Ð¸Ñ 540 if ($(datepickerStart).datepicker("option") !== undefined) 541 datepickerStart.datepicker("destroy"); 542 if ($(datepickerEnd).datepicker("option") !== undefined) 543 datepickerEnd.datepicker("destroy"); 544 if ($(datepickerRange).datepicker("option") !== undefined) 545 datepickerRange.datepicker("destroy"); 546 547 let startSettings = { 548 regional: "ru", 549 minDate: dateMin, 550 maxDate: dateMax, 551 beforeShowDay: this.beforeShowDay(datesWithEvents, "from"), 552 onSelect: (date, datepicker) => { 553 datepickerStart.datepicker("setDate", date); 554 // ÑоÑмаÑиÑÑем полÑÑеннÑÑ Ð´Ð°ÑÑ Ð² нÑжном Ð´Ð»Ñ ÐиÑÑÐ¸ÐºÑ ÑоÑÐ¼Ð°Ñ 555 let selectedDate = new Date( 556 datepicker.selectedYear, 557 datepicker.selectedMonth, 558 datepicker.selectedDay, 559 ); 560 this.date.data.from = $.datepicker.formatDate( 561 "yy-mm-dd", 562 selectedDate, 563 ); 564 // ÑÑигеÑим ÑÑнкÑÐ¸Ñ Ð¿ÑинÑдиÑелÑно, Ñак как beforeUpdate() не ÑÑигеÑиÑÑÑ Ð¿Ñи изменении даннÑÑ ÑÑÑ 565 this.resetButtonSwitch(); 566 // менÑем надпиÑÑ Ð² ÑоÑме 567 this.date.text.from = date; 568 datepickerEnd.datepicker( 569 "option", 570 "minDate", 571 new Date( 572 datepicker.selectedYear, 573 datepicker.selectedMonth, 574 datepicker.selectedDay, 575 ), 576 ); 577 datepickerContainer.removeClass("show"); 578 // когда вÑбиÑаеÑÑÑ/менÑеÑÑÑ ÑекÑÑ Ð½Ð°ÑалÑной даÑÑ Ð² ÑилÑÑÑе, Ñо ÑекÑÑ Ð² поле вÑбоÑа даÑÑ Ð¼ÐµÐ½ÑеÑÑÑ Ð½Ð° дÑÑгой 579 $(".search-form__selector--start-date").css( 580 "color", 581 activeFilterTextColor, 582 ); 583 this.fetchEvents(); 584 }, 585 }; 586 587 let endSettings = { 588 regional: "ru", 589 minDate: dateMin, 590 maxDate: dateMax, 591 beforeShowDay: this.beforeShowDay(datesWithEvents, "to"), 592 onSelect: (date, datepicker) => { 593 datepickerEnd.datepicker("setDate", date); 594 // ÑоÑмаÑиÑÑем полÑÑеннÑÑ Ð´Ð°ÑÑ Ð² нÑжном Ð´Ð»Ñ ÐиÑÑÐ¸ÐºÑ ÑоÑÐ¼Ð°Ñ 595 let selectedDate = new Date( 596 datepicker.selectedYear, 597 datepicker.selectedMonth, 598 datepicker.selectedDay, 599 ); 600 this.date.data.to = $.datepicker.formatDate( 601 "yy-mm-dd", 602 selectedDate, 603 ); 604 // менÑем надпиÑÑ Ð² ÑоÑме 605 this.date.text.to = date; 606 // ÑÑигеÑим ÑÑнкÑÐ¸Ñ Ð¿ÑинÑдиÑелÑно, Ñак как beforeUpdate() не ÑÑигеÑиÑÑÑ Ð¿Ñи изменении даннÑÑ ÑÑÑ 607 this.resetButtonSwitch(); 608 datepickerStart.datepicker( 609 "option", 610 "maxDate", 611 new Date( 612 datepicker.selectedYear, 613 datepicker.selectedMonth, 614 datepicker.selectedDay, 615 ), 616 ); 617 datepickerContainer.removeClass("show"); 618 // когда вÑбиÑаеÑÑÑ/менÑеÑÑÑ ÑекÑÑ ÐºÐ¾Ð½ÐµÑной даÑÑ Ð² ÑилÑÑÑе, Ñо ÑекÑÑ Ð² поле вÑбоÑа даÑÑ Ð¼ÐµÐ½ÑеÑÑÑ Ð½Ð° дÑÑгой
619 $(".search-form__selector--end-date").css( 620 "color", 621 activeFilterTextColor, 622 ); 623 this.fetchEvents(); 624 }, 625 }; 626 627 let rangeSettings = { 628 regional: "ru", 629 minDate: dateMin, 630 maxDate: dateMax, 631 numberOfMonths: 2, 632 beforeShowDay: this.beforeShowDayRange(datesWithEvents), 633 onSelect: (date, datepicker) => { 634 let selectedDate = new Date( 635 datepicker.selectedYear, 636 datepicker.selectedMonth, 637 datepicker.selectedDay, 638 ); 639 const selectedDateValue = $.datepicker.formatDate( 640 "yy-mm-dd", 641 selectedDate, 642 ); 643 644 if (this.checkFirstClickToDatepicker) { 645 this.date.data.from = selectedDateValue; 646 this.date.text.from = date; 647 this.date.data.to = ""; 648 this.date.text.to = this.date.defaultText.to; 649 this.checkFirstClickToDatepicker = false; 650 this.resetButtonSwitch(); 651 // Datepicker пеÑеÑиÑовÑÐ²Ð°ÐµÑ DOM поÑле onSelect, поÑÑÐ¾Ð¼Ñ Ð¶Ð´Ñм завеÑÑÐµÐ½Ð¸Ñ Ð¿ÐµÑеÑиÑовки. 652 setTimeout(() => this.paintDateRange(datepickerRange), 0); 653 } else { 654 const firstDateValue = this.date.data.from; 655 const firstDateText = this.date.text.from; 656 657 if (selectedDate < this.parseFilterDate(firstDateValue)) { 658 this.date.data.from = selectedDateValue; 659 this.date.text.from = date; 660 this.date.data.to = firstDateValue; 661 this.date.text.to = firstDateText; 662 } else { 663 this.date.data.to = selectedDateValue; 664 this.date.text.to = date; 665 } 666 667 this.checkFirstClickToDatepicker = true; 668 this.dateRange.text = 669 this.date.text.from + " - " + this.date.text.to; 670 datepickerContainer.removeClass("show"); 671 this.fetchEvents(); 672 } 673 }, 674 onChangeMonthYear: () => { 675 setTimeout(() => this.paintDateRange(datepickerRange), 0); 676 }, 677 selectOtherMonths: true, 678 }; 679 680 datepickerStart.datepicker(startSettings).val(""); 681 datepickerEnd.datepicker(endSettings).val(""); 682 datepickerRange.datepicker(rangeSettings).val(""); 683 684 datepickerRange 685 .off(".dateRangePreview") 686 .on( 687 "mouseenter.dateRangePreview", 688 "td[data-handler='selectDay']", 689 (event) => { 690 if (this.checkFirstClickToDatepicker) return; 691 692 const previewDate = this.getDatepickerCellDate( 693 event.currentTarget, 694 ); 695 if (previewDate) 696 this.paintDateRange(datepickerRange, previewDate); 697 }, 698 ) 699 .on( 700 "mouseleave.dateRangePreview", 701 ".ui-datepicker-calendar", 702 () => { 703 if (!this.checkFirstClickToDatepicker) 704 this.paintDateRange(datepickerRange); 705 }, 706 ); 707 708 if (this.date.data.from) 709 datepickerStart.datepicker("setDate", this.date.data.from); 710 if (this.date.data.to) 711 datepickerEnd.datepicker("setDate", this.date.data.to); 712 if (this.date.data.from) 713 datepickerRange.datepicker("setDate", this.date.data.from); 714 715 // ÐакладÑваем ÑоÑÑоÑние диапазона поÑле полной иниÑиализаÑии календаÑей. 716 setTimeout(() => this.paintDateRange(datepickerRange), 0); 717 }, 718 719 // ФУÐÐЦÐЯ ÐÐЯ ÐЫÐÐÐÐÐÐЯ ÐÐÐÐ Ð ÐÐÐÐÐÐÐÐ Ð, ÐÐТÐÐ ÐÐ ÐУÐÐРСÐÐÐ ÐÐТЬ ÐÐССÐРС ÐÐÐÐÐÐТÐÐÐ ÐÐÐÐ [11.07.2025] 720 beforeShowDay(datesWithEvents, dateField) { 721 return (date) => { 722 let className = ""; 723 var dateString = $.datepicker.formatDate("dd.mm.yy", date); 724 if (datesWithEvents.includes(dateString)) { 725 className = "calendar_hasdate"; 726 } 727 // jQuery UI Ñам вÑделÑÐµÑ minDate, пока даÑа не вÑбÑана, â гаÑим ÑÑо вÑделение 728 if (!this.date.data[dateField]) { 729 className += " calendar_first"; 730 } 731 return [true, className]; 732 }; 733 }, 734 735 beforeShowDayRange(datesWithEvents) { 736 return (date) => { 737 let className = "", 738 dateString = $.datepicker.formatDate("dd.mm.yy", date); 739 740 if (datesWithEvents.includes(dateString)) 741 className = "calendar_hasdate"; 742 743 if (this.date.data.from) { 744 const from = this.parseFilterDate(this.date.data.from); 745 const to = this.date.data.to 746 ? this.parseFilterDate(this.date.data.to) 747 : from; 748 const dateTime = date.getTime(); 749 750 if (dateTime >= from.getTime() && dateTime <= to.getTime()) 751 className += " dp-highlight"; 752 if (dateTime === from.getTime()) 753 className += " dp-range-start"; 754 if (dateTime === to.getTime() && to.getTime() !== from.getTime()) 755 className += " dp-range-end"; 756 } 757 758 return [true, className]; 759 }; 760 }, 761 }, 762 763 mounted() { 764 document.querySelector(".event-cards.preloaded")?.remove(); 765 766 document.querySelectorAll(".no-events").forEach((el) => { 767 el.style.display = ""; 768 }); 769 770 document.querySelectorAll(".event__elem--show-more").forEach((el) => { 771 el.style.display = ""; 772 }); 773 774 if (window.__INITIAL__?.events?.length) { 775 // Ð¡Ð¸Ð½Ñ ÑонизаÑÐ¸Ñ ÑоÑÑоÑÐ½Ð¸Ñ ÑилÑÑÑов 776 this.filterByUrl(); 777 778 this.drawFilterForm(window.__INITIAL__.filter); 779 this.showMoreButtonEnable = window.__INITIAL__.showMore; 780 this.noEvents = window.__INITIAL__.noEvents; 781 this.events = window.__INITIAL__.events; 782 } else { 783 this.fetchEvents(this.filterByUrl()); 784 } 785 786 document.addEventListener("click", this.clickOutsideFilters); 787 }, 788 789 beforeUpdate() { 790 this.resetButtonSwitch(); // ÐÑи обновлении модели запÑÑÐºÐ°Ñ Ð»Ð¾Ð³Ð¸ÐºÑ 791 }, 792 }).mount("#app"); 793});
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.