1 2 3$(document).ready(function () { 4 5 WireFilterEvents(); 6 CustomDatesValidInit(); 7 8}); 9 10function WireFilterEvents() { 11 12 campusNewsdata.jqObjects.newsForm.find(".filter-category input:checkbox").click(function () { 13 /*FilterCategories(); */ 14 FilterGrid(); 15 }); 16 17 campusNewsdata.jqObjects.newsForm.find("button.filter-search-btn").click(function () { 18 FilterGrid(); 19 }); 20 21 22 campusNewsdata.jqObjects.newsForm.find('.filter-search input[type=search]').on('search', function () { 23 FilterGrid(); 24 }); 25 26 27 28 campusNewsdata.jqObjects.newsForm.find('#GroupCampusNewsFilterDays input[type=radio]').click(function () { 29 event.stopPropagation(); 30 let days = $(this).val(); 31 ClearCustomDates(); 32 // let days = $(this).find("input[type=radio]").val(); 33 let gotDataFromServer = FilterNumberOfDaysGetDataFromServer(days); 34 35 if (!gotDataFromServer)// if got data from server than the grid was already filtered 36 FilterGrid(); 37 38 }); 39 40 campusNewsdata.jqObjects.newsForm.find(".filter-audience input:checkbox").click(function () { 41 event.stopPropagation(); 42 FilterGrid(); 43 44 }); 45 46 campusNewsdata.jqObjects.newsForm.find(".subscribe-choice input:checkbox").click(function () { 47 event.stopPropagation(); 48 SubscribeChecked($(this).val()); 49 }); 50 51 52 //wire enter key when search textbox is in focus 53 document.addEventListener('keyup', (e) => { 54 if ( (e.key === 'Enter' ) && e.target.classList.contains('filter-search-input')) { 55 e.preventDefault(); 56 FilterGrid(); 57 } 58 59 }); 60 61 campusNewsdata.jqObjects.newsForm.find("input[type=search].filter-search-input").on("focusout", function () { 62 FilterGrid(); 63 }); 64 65 campusNewsdata.jqObjects.newsForm.find("button.filter-reset-btn").click(function () { 66 FilterFormReset(); 67 }); 68 69 70 campusNewsdata.jqObjects.newsForm.find("#chkCampusNewsFilterMyOwn").click(function () { 71 FilterGrid(); 72 }); 73 74 campusNewsdata.jqObjects.newsForm.find("#chkCampusNewsFilterPending").click(function () { 75 FilterGrid(); 76 }); 77 78 campusNewsdata.jqObjects.newsForm.find(".filter-sort").hide(); //hide the sort for now 79 80} 81 82 83function SubscribeChecked(checkedVal) { 84 85 let subList = ""; 86 if (checkedVal == "0") { 87 //uncheck all others 88 campusNewsdata.jqObjects.newsForm.find(".subscribe-choice input:checkbox").each(function () { 89 if ($(this).val() != "0" && $(this).is(':checked')) 90 $(this).prop("checked", false); 91 }); 92 93 subList = checkedVal; 94 } else { 95 campusNewsdata.jqObjects.newsForm.find(".subscribe-choice input:checkbox").each(function () { 96 if ($(this).is(':checked')) { 97 if ($(this).val() == "0") 98 $(this).prop("checked", false); //uncheck none 99 else 100 subList += "," + $(this).val(); 101 } 102 103 }); 104 } 105 106 if (subList.length == 0 || subList == null || subList == "") 107 subList = "0"; 108 else 109 if (subList.charAt(0) === ',') 110 subList = subList.slice(1); 111 112 SubscribeToNews(subList); 113 114} 115 116 117 118function FilterFormReset() { 119 120 campusNewsdata.jqObjects.newsForm.find("#GroupCampusNewsFilterDays [type=radio]").each(function () { 121 if (parseInt($(this).val()) == campusNewsdata.defaultRetrieveDays) { 122 //$(this).trigger("click"); 123 CheckRadioButton("GroupCampusNewsFilterDays", $(this).val()); 124 } 125 }); 126 127 128 129 130 131 132 FilterNumberOfDaysGetDataFromServer(campusNewsdata.defaultRetrieveDays); 133 134 135 campusNewsdata.jqObjects.newsForm.find(".filter-category input:checkbox").each(function () { 136 if (!$(this).is(':checked')) 137 $(this).prop("checked", true); 138 }); 139 140 141 campusNewsdata.jqObjects.newsForm.find(".filter-audience input:checkbox").each(function () { 142 let div = $(this).closest("div.form-check"); 143 if (div.is(":visible")) { 144 if (!$(this).is(':checked')) 145 $(this).prop("checked", true); 146 } 147 148 });
149 150 campusNewsdata.jqObjects.newsForm.find("#chkCampusNewsFilterMyOwn").prop("checked", false); 151 campusNewsdata.jqObjects.newsForm.find("#chkCampusNewsFilterPending").prop("checked", false); 152 153 campusNewsdata.jqObjects.newsForm.find(".filter-search input[type='search']").val(""); 154 155 ClearCustomDates(); 156 FilterGrid(); 157 158 159} 160 161 162function FilterNumberOfDaysGetDataFromServer(days) { 163 164 165 let daysNum = getNumberOfDaysIgnoreTime(new Date(), campusNewsdata.dataMaxDate) + 1; //add one because GetDefaultData() substracts one becausee it includes the end 166 let needGetDataFromServer = daysNum < days; 167 168 if (needGetDataFromServer) { 169 let endDate = new Date(); 170 endDate.setDate(endDate.getDate() + parseInt(days)); 171 GetData(new Date(), endDate); //will method calls filter grid 172 } 173 174 175 return needGetDataFromServer; 176 177 178} 179 180 181function FilterGrid(lastVisibleId) { 182 183 campusNewsdata.jqObjects.newsGrid.find(".no-data-alert").remove(); 184 185 186 let listCategory = GetFilterCategoryList(); 187 let listAudience = GetFilterAudienceList(); 188 let strSearch = $("#txtFilterSearch").val(); 189 let isMyOwn = $("#chkCampusNewsFilterMyOwn").is(':checked'); 190 let pending = $("#chkCampusNewsFilterPending").is(':checked');
191 let days = parseInt($("#hidCampusNewsFilterDays").val()); 192 193 let startDate, endDate; 194 195 if (campusNewsdata.jqObjects.newsForm.find("#txtPickDateStart").val() != "") { 196 startDate = ConvertToDate(campusNewsdata.jqObjects.newsForm.find("#txtPickDateStart").val()); 197 endDate = ConvertToDate(campusNewsdata.jqObjects.newsForm.find("#txtPickDateEnd").val()); 198 } else { 199 endDate = new Date((new Date()).setDate((new Date()).getDate() + days)); 200 startDate = new Date();//only using 201 } 202 203 204 205 let visibleCount = 0; 206 for (let a of campusNewsdata.newsList.Articles) { 207 208 let catMatch = listCategory.includes(a.category); 209 let audMatch = FilterAudienceInList(listAudience, a.restrictedTo) 210 211 212 let hasString = HasSearchString(a, strSearch); 213 214 let eventEndDate= ConvertToDate(a.expiration); 215 let eventStartDate = ConvertToDate(a.eventStart); 216 let withinDate = eventEndDate >= startDate && eventStartDate <= endDate; 217 218 219 let id = GetArticleHtmlElementId(a.id); 220 221 let myOwnMatch = !isMyOwn || a.myArticle; //not checked or article belongs to usr 222 let pendingMatch = !pending || a.published == "-1"; 223 224 if (catMatch && hasString && withinDate && audMatch && myOwnMatch && pendingMatch) { 225 ShowHidden($(id)); 226 visibleCount++; 227 } 228 else { 229 HideVisible($(id)); 230 //console.log(id); 231 } 232 } 233 234 if (visibleCount == 0) { 235 DisplayNoDataOnGrid();//display no data message 236 } 237 238 ScrollUpAfterFilter(lastVisibleId); 239 240 241 242 243} 244 245 246function FilterAudienceInList(selectedList, articleList) { 247 for (let selected of selectedList) { 248 if (articleList.includes(selected)) 249 return true; 250 } 251 252 return false; 253} 254 255function ScrollUpAfterFilter(lastVisibleId) { 256 /* 257 let offset; 258 259 if (ArgHasValue(lastVisibleId)) { 260 offset = $(lastVisibleId).offset(); 261 } else { 262 offset = campusNewsdata.jqObjects.newsGrid.offset(); 263 } 264 */ 265 if (campusNewsdata.firstLoad) { 266 campusNewsdata.firstLoad = false; 267 return; // do not scroll down on the first load because then users won't see submit button 268 } 269 let el; 270 271 if (ArgHasValue(lastVisibleId)) { 272 el = $(lastVisibleId)[0]; 273 el.scrollIntoView({}); 274 } 275 276 else { 277 scrollIntoViewWithOffset("#" + campusNewsdata.jqObjects.newsGrid[0].id, 150); 278 } 279 280 281 282 283 /* 284 offset = campusNewsdata.jqObjects.newsGrid.offset(); 285 286 287 $('html, body').animate({ 288 scrollTop: offset.top-200 , 289 scrollLeft: offset.left 290 }, 800); 291 292*/ 293} 294 295 296const scrollIntoViewWithOffset = (selector, offset) => { 297 window.scrollTo({ 298 behavior: 'smooth', 299 top: 300 document.querySelector(selector).getBoundingClientRect().top - document.body.getBoundingClientRect().top - offset, 301 }) 302} 303 304function HasSearchString(article, strSearch) { 305 306 307 strSearch = strSearch.trim(); 308 309 if (!ArgHasValue(strSearch) || strSearch.length < 3) // assume true if search string is null or very short 310 return true; 311 312 let terms = strSearch.split(" "); 313 314 let matchCount = 0; 315 for (let i = 0; i < terms.length; i++) { 316 317 if (article.hasStringTerm(terms[i])) { 318 matchCount++ 319 } 320 321 } 322 if (matchCount > 0) { 323 if (matchCount / terms.length >= 0.3) 324 return true; 325 else 326 return false; 327 } 328 329 return false; 330 331} 332 333 334 335function SearchPosts(strSearch) { 336 337 let terms = strSearch.split(" "); 338 339 for (var n = 0; n < campusNewsdata.newsList.Articles.length; n++) { 340 let include = false; 341 let title = campusNewsdata.newsList.Articles[n].title.toLowerCase(); 342 let summary = campusNewsdata.newsList.Articles[n].summary.toLowerCase(); 343 344 for (let i = 0; i < terms.length; i++) { 345 346 let term = terms[i].toLowerCase(); 347 348 if (ArgHasValue(term) && term.length>
3481 && (title.indexOf(term) >= 0 || summary.indexOf(term) >= 0)) { 349 include = true; 350 break; 351 } 352 353 } 354 355 let id = GetArticleHtmlElementId(campusNewsdata.newsList.Articles[n].id); 356 357 if (include) { 358 ShowHidden($(id)) 359 } else { 360 HideVisible($(id)); 361 } 362 363 364 } 365} 366 367function FilterCategories() { 368 369 let list = GetFilterCategoryList(); 370 371 372 $(".CampusNewsArticleGridContainer").each(function () { 373 let category = $(this).attr("data-category"); 374 if (category == "2") 375 category = "2"; 376 if (list.includes(category)) { 377 if (!$(this).is(":visible")) 378 $(this).show('slow'); 379 } 380 381 else { 382 if ($(this).is(":visible")) 383 $(this).hide('slow'); 384 } 385 386 }); 387 388 389} 390 391function GetFilterCategoryList() { 392 let list = []; 393 $(".filter-category input:checkbox").each(function () { 394 if ($(this).is(':checked')) 395 list.push($(this).val()) 396 }); 397 return list; 398} 399 400function GetFilterAudienceList() { 401 let list = []; 402 campusNewsdata.jqObjects.newsForm.find(".filter-audience input:checkbox").each(function () { 403 if ($(this).is(':checked')) 404 list.push($(this).val()) 405 }); 406 return list; 407} 408 409 410 411function ShowSubscribeOptions () { 412 let div = campusNewsdata.jqObjects.newsForm.find(".campus-news-subscribe"); 413 if (campusNewsdata.user.isGuest) 414 HideVisible(div, 'fast'); 415 else { 416 ShowHidden(div, 'slow'); 417 418 campusNewsdata.jqObjects.newsForm.find(".campus-news-subscribe input:checkbox").each(function () { 419 let thisChkVal = $(this).val(); 420 let subscribed = campusNewsdata.user.containsSubscribedCategory(thisChkVal);; 421 422 423 $(this).prop("checked", subscribed); 424 }); 425 426 427 428 429 430 } 431 432} 433 434function HideIfGuest(ctr) { 435 if (ctr == null || !(ctr instanceof jQuery)) 436 return; 437 438 if (campusNewsdata.user.isGuest) 439 HideVisible(ctr, 'fast'); 440 else 441 ShowHidden(ctr, 'slow'); 442} 443 444function HideMyPostsIfNeeded() 445{ 446 HideIfGuest(campusNewsdata.jqObjects.newsForm.find(".filter-myown")) 447 448 /* 449 let chk = campusNewsdata.jqObjects.newsForm.find(".filter-myown"); 450 if (campusNewsdata.user.isGuest) 451 HideVisible(chk, 'fast'); 452 else 453 ShowHidden(chk, 'slow'); 454 */ 455} 456 457 458function HidePendingIfNeeded() { 459 HideIfGuest(campusNewsdata.jqObjects.newsForm.find(".filter-pending")); 460} 461 462 463 464function PopulateFilterRestrictedTo() { 465 let visiblCount = 0; 466 467 if (campusNewsdata.user.isGuest) 468 return; // do not show the filter group if guest 469 470 campusNewsdata.jqObjects.newsForm.find(".filter-audience input:checkbox").each(function () { 471 if (campusNewsdata.user.containsFilterCategory($(this).val())) { 472 visiblCount++; 473 ShowHidden($(this).closest('div')); 474 } 475 else 476 HideVisible($(this).closest('div')); 477 }); 478 479 480 let groupDiv = $(".filter-audience-row"); 481 482 if (visiblCount == 0) 483 HideVisible(groupDiv, 'fast'); 484 else 485 ShowHidden(groupDiv, 'slow'); 486 487 488} 489 490function SubscribeToNews(subscribeTo) { 491 let genericError = "There was a problem saving your subscription changes.";
492 let callUri = "/ICS/rpc/CusWcgaCampusNews/SubscribeToNews/" + subscribeTo; 493 494 $.ajax({ 495 type: "GET", 496 url: callUri, 497 success: function (response) { 498 if (response=="true") //if response has value it comes with error 499 SubscribeToNewsSuccess(subscribeTo); 500 else { 501 console.log(response); 502 DisplayErrorAlert(genericError); 503 } 504 505 }, 506 error: function (response) { 507 508 if (!isString(response)) { 509 510 if (isObject(response) && response.hasOwnProperty('responseText')) { 511 console.log(response.responseText); 512 } 513 514 response = genericError; 515 } 516 517 DisplayErrorAlert(response); 518 519 } 520 }); 521} 522 523function SubscribeToNewsSuccess(subscribedTo) { 524 525 if (!ArgHasValue(subscribedTo)) 526 subscribedTo = "0"; 527 528 let firstTemplate = "<p>The @@period email subscription is confirmed!<\p>" 529 530 const msgList = [ 531 {cde: "d", period: "daily", msg: "You will receive one email a day with the summary of all announcements and events for the next day."}, 532 {cde: "w", period: "weekly", msg: "You will receive one email a week with the summary of all announcements and events for the upcoming week."}, 533 //{cde: "b", period: "daily & weekly", msg: "You have successfully subscribed to daily and weekly emails with a summary of all upcoming events and current announcements." } 534 ]; 535 536 //build clean list of subscriptions 537 let displayMsg = ""; 538 let period = ""; 539 const inputList = subscribedTo.split(","); 540 let list = []; 541 for (let i = 0; i < inputList.length; i++) { 542 for (let n = 0; n < msgList.length; n++) { 543 if (msgList[n].cde == inputList[i]) { 544 displayMsg += "<li>" + msgList[n].msg + "</li>"; 545 period += "& " + msgList[n].period + " "; 546 } 547 } 548 } 549 550 551 552 553 displayMsg = "<ul class=''>" + displayMsg + "</ul>"; 554 555 if (period.charAt(0) === '&') 556 period = period.slice(1); 557 558 559 firstTemplate = firstTemplate.replace("@@period", period); 560 561 displayMsg = "<div>" + firstTemplate + displayMsg + "<div>"; 562 563 564 565 DisplayInfoAlert("Subscribed successfully!", displayMsg); 566} 567 568 569 570function CustomDatesValidInit() { 571 572 const today = new Date().toISOString().split('T')[0]; 573 document.getElementById('txtPickDateStart').setAttribute('min', today); 574 document.getElementById('txtPickDateEnd').setAttribute('min', today); 575 576 document.getElementById('btnCampusNewsFilterDateRangeGo').addEventListener('click', function () { 577 if (CustomDatesValie()) { 578 579 ClearAllCheckBoxes("GroupCampusNewsFilterDays") 580 let startDate = document.getElementById('txtPickDateStart').value; 581 let endDate = document.getElementById('txtPickDateEnd').value; 582 // Clear previous grid content 583 campusNewsdata.jqObjects.newsGrid.empty(); 584 // Get data with the new date range 585 startDate = getFormattedDate(startDate); 586 endDate = getFormattedDate(endDate); 587 588 const triggerButton = document.querySelector('.btn-pick-dates'); 589 triggerButton.textContent = `${startDate} â ${endDate}`; 590 //add active class to the button 591 triggerButton.classList.add('active'); 592 593 const dropdown = triggerButton.closest('sl-dropdown'); 594 if (dropdown && typeof dropdown.hide === 'function') { 595 dropdown.hide(); 596 } 597 598 599 600 GetData(startDate, endDate); 601 FilterGrid(); 602 } 603 604 }); 605 606 document.getElementById('txtPickDateStart').addEventListener('change', function () { 607 CustomDatesValie(); 608 }); 609 610 document.getElementById('txtPickDateEnd').addEventListener('change', function () { 611 CustomDatesValie(); 612 }); 613 614 615} 616 617 618function ClearCustomDates() { 619 const triggerButton = document.querySelector('.btn-pick-dates'); 620 triggerButton.textContent = "Pick Dates"; 621 triggerButton.classList.remove('active'); 622 document.getElementById('txtPickDateStart').value = ""; 623 document.getElementById('txtPickDateEnd').value = ""; 624 625 626} 627 628 629function CustomDatesValie() { 630 const startDateInput = document.getElementById('txtPickDateStart'); 631 const endDateInput = document.getElementById('txtPickDateEnd'); 632 const errorContainer = document.querySelector('.date-range-container-errors'); 633 634 // Clear previous errors and error classes 635 errorContainer.innerHTML = ''; 636 errorContainer.style.display = 'none'; 637 startDateInput.classList.remove('error'); 638 endDateInput.classList.remove('error'); 639 640 const startDateValue = startDateInput.value; 641 const endDateValue = endDateInput.value; 642 643 const errors = []; 644 645 // Validate presence 646 if (!startDateValue) { 647 errors.push('Start date is required.'); 648 startDateInput.classList.add('error'); 649 } 650 651 if (!endDateValue) { 652 errors.push('End date is required.'); 653 endDateInput.classList.add('error'); 654 } 655 656 // Validate range only if both values are present 657 if (startDateValue && endDateValue) { 658 const startDate = new Date(startDateValue); 659 const endDate = new Date(endDateValue); 660 if (endDate < startDate) { 661 errors.push('End date must be greater than or equal to the start date.'); 662 startDateInput.classList.add('error'); 663 endDateInput.classList.add('error'); 664 } 665 } 666 667 // Display errors if any 668 if (errors.length > 0) { 669 errorContainer.innerHTML = errors.map(err => `<div>${err}</div>`).join(''); 670 errorContainer.style.display = 'block'; 671 return false; 672 } 673 674 return true; 675}
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.