1// [Mobile] Focus on header search bar when displays 2 3var headerMobileSrcBtn = document.getElementById('headerSearchButton') 4var headerSrcBar = document.getElementById('headerSearchInput') 5 6if (headerMobileSrcBtn) { 7 headerMobileSrcBtn.addEventListener('click', () => { 8 headerSrcBar.focus() 9 }) 10} 11 12 13// On scroll 14 15// var alertTopbar = document.getElementById('alertTopbar') 16var siteHeader = document.getElementById('siteHeader') 17var mobileMenuHelper = document.getElementById('btnNavMobileHelper') 18 19window.addEventListener('scroll', () => { 20 21 if (window.scrollY > 100) { 22 // if (alertTopbar) { 23 // alertTopbar.classList.add('d-none') 24 // } 25 siteHeader.classList.add('sticky') 26 } 27 if (window.scrollY < 99) { 28 // if (alertTopbar) { 29 // alertTopbar.classList.remove('d-none') 30 // } 31 siteHeader.classList.remove('sticky') 32 } 33 34}) 35 36 37// Custom contact form / error accessibility 38 39var alertScrollTo = document.querySelector('.alert-scrollto') 40 41if (alertScrollTo) { 42 alertScrollTo.scrollIntoView() 43} 44 45 46// Load-more button 47 48for (var container of document.querySelectorAll('.loadmore-container')) { 49 50 var loadmoreItems = container.querySelectorAll('.loadmore-item') 51 var loadmoreBtn = container.querySelector('.loadmore-btn') 52 var splitStart = loadmoreBtn.getAttribute('data-split-start') 53 54 if (loadmoreItems.length > splitStart) loadmoreBtn.classList.remove('d-none') 55 56 for (var i in loadmoreItems) { 57 if (i > splitStart - 1) loadmoreItems[i].classList.add('d-none') 58 } 59 60 loadmoreBtn.addEventListener('click', event => { 61 62 var counter = event.target.getAttribute('data-split-size') 63 var eventTargetItems = event.target.closest('.loadmore-container').querySelectorAll('.loadmore-item') 64 65 for (var j in eventTargetItems) { 66 67 if (eventTargetItems[j].classList) 68 { 69 if (eventTargetItems[j].classList.contains('d-none') && (counter > 0)) { 70 eventTargetItems[j].classList.remove('d-none') 71 counter -- 72 } 73 74 if (!eventTargetItems[j].classList.contains('d-none') && j >= eventTargetItems.length -1) { 75 event.target.classList.add('d-none') 76 } 77 } 78 79 } 80 81 }) 82 83} 84 85 86// Quick-Links bar that works with cookies 87 88var quicklinksBar = document.getElementById('quicklinksBar') 89var qlbarToggleButton = document.getElementById('qlbarToggleButton') 90var cookieQuicklinksBar = 'novicityquicklinksbar' 91 92if (quicklinksBar) { 93 94 if (!Cookies.get(cookieQuicklinksBar)) 95 Cookies.set(cookieQuicklinksBar) 96 97 if (Cookies.get(cookieQuicklinksBar) == 'undefined') { 98 var bsCollapse = new bootstrap.Collapse(quicklinksBar, { 99 show: true 100 }) 101 } 102 103 qlbarToggleButton.addEventListener('click', () => { 104 if (Cookies.get(cookieQuicklinksBar) == 'undefined') 105 Cookies.set(cookieQuicklinksBar, true) 106 else 107 Cookies.set(cookieQuicklinksBar) 108 }) 109 110} 111 112 113// Home Hero Card Slider 114 115const homeHeroCardSwiper = new Swiper('.hero-card-slider', { 116 navigation: { 117 nextEl: '.hero-card-wrapper .swiper-button-next', 118 prevEl: '.hero-card-wrapper .swiper-button-prev' 119 }, 120 keyboard: { 121 enabled: true 122 } 123}) 124// checkSwiperNavigation(homeHeroCardSwiper, '.hero-card-navigation') 125 126 127// Home News Slideshow 128 129const homeNewsSwiper = new Swiper('.news-carousel', { 130 slidesPerView: 1, 131 spaceBetween: 10, 132 breakpoints: { 133 576: { 134 slidesPerView: 2 135 }, 136 768: { 137 slidesPerView: 3 138 }, 139 992: { 140 slidesPerView: 3, 141 spaceBetween: 20 142 }, 143 1200: { 144 slidesPerView: 4, 145 spaceBetween: 30 146 } 147 }, 148 navigation: { 149 nextEl: '.news-carousel-wrapper .swiper-button-next', 150 prevEl: '.news-carousel-wrapper .swiper-button-prev' 151 }, 152 keyboard: { 153 enabled: true 154 } 155}) 156 157 158// Park Gallery Slideshow 159 160const parkSlider = new Swiper('.park-slider', { 161 navigation: { 162 nextEl: '.park-slider .swiper-button-next', 163 prevEl: '.park-slider .swiper-button-prev' 164 }, 165 keyboard: { 166 enabled: true 167 }, 168 loop: true 169}) 170// checkSwiperNavigation(parkSlider, '.swiper-navigation') 171 172 173// function checkSwiperNavigation(slider, navigation) { 174 175// if (slider.slides.length <= 1) { 176// var nav = document.querySelector(navigation) 177// if (nav) nav.classList.add('d-none') 178// } 179 180// } 181 182 183// Commission Application Form: show/hide checkboxes 184 185// document.addEventListener('DOMContentLoaded', function() { 186 187// var bcafFieldsets = document.querySelectorAll('#form-4c4e6003-ede6-4950-a62f-ab0f7ea3e154 fieldset') 188 189// for (set of bcafFieldsets) { 190// var inputText = set.querySelector('.shortanswer input') 191// var multiplechoice = set.querySelector('.shortanswer + .multiplechoice') 192 193// if (inputText && multiplechoice) { 194// inputText.addEventListener('input', event => { 195// if (event.target.value.trim() != '') { 196// event.target.closest('.shortanswer').nextElementSibling.classList.add('d-block') 197// } else { 198// event.target.closest('.shortanswer').nextElementSibling.classList.remove('d-block') 199// } 200// }) 201// } 202// } 203 204// }) 205 206 207// Bootstrap Accordion helper script 208 209document.addEventListener('DOMContentLoaded', function() { 210 211 var accordions = document.querySelectorAll('.accordion') 212 213 for (accordion of accordions) { 214 var accordionId = accordion.getAttribute('id') 215 var accordionCollapses = accordion.querySelectorAll('.accordion-collapse') 216 217 for (collapse of accordionCollapses) { 218 collapse.setAttribute('data-bs-parent', `#${accordionId}`) 219 } 220 } 221 222 var tabAccordions = document.querySelectorAll('.accordion-to-tabs') 223 224 for (tab of tabAccordions) { 225 tab.querySelector('.accordion-button').classList.remove('collapsed') 226 tab.querySelector('.accordion-collapse').classList.add('show') 227 } 228 229}) 230 231 232// Search popup 233 234document.addEventListener("DOMContentLoaded", function() { 235 236 var searchForm = document.getElementById('quickSearchModalForm') 237 238 searchForm.addEventListener('submit', function(event) { 239 240 event.preventDefault() 241 242 var query = document.getElementById('quickSearchModalInput').value 243 var filter = document.querySelector('input[name="radioQuickSearch"]:checked').getAttribute('data-filter') 244 245 if (filter == "generic") { 246 // window.location.href = `/search?q=${query}&exactphrase=on&orderby=Most+recently+updated` 247 window.location.href = `/search?query=${query}&mode=Exact+phrase&orderby=Most+recently+updated` 248 } 249 250 if (filter == "meetings") { 251 window.location.href = `/agendas-minutes?query=${query}&q="${query}"&mode=Exact+phrase` 252 } 253 }) 254 255}) 256 257 258// Google quick search 259 260/*var headerSearchForm = document.getElementById('headerSearchForm') 261var headerSearchInput = document.getElementById('headerSearchInput') 262var headerSearchQuery = headerSearchInput.value; 263var siteUrl = 'unovidev.muniweb.com'; 264 265headerSearchInput.addEventListener('change', event => { 266 headerSearchQuery = event.target.value 267}) 268 269headerSearchForm.addEventListener('submit', event => { 270 event.preventDefault() 271 var googleUrl = `https://www.google.com/search?q=${headerSearchQuery}+site%3A${siteUrl}` 272 window.open(googleUrl, '_blank') 273})*/ 274 275 276// Tables 277
278var tables = document.querySelectorAll('table:not([class]):not([id])') 279 280for (table of tables) { 281 if (!table.classList.contains('table')) { 282 table.classList.add('table') 283 } 284} 285 286 287// Fix wrong links to map gallery page 288 289document.querySelectorAll('a[href^="https://novi.maps.arcgis.com/apps/webappviewer"]').forEach(function(a) { // with https 290 a.setAttribute('href', '/community/map-gallery') 291 a.setAttribute('target', '_self') 292}) 293document.querySelectorAll('a[href^="http://novi.maps.arcgis.com/apps/webappviewer"]').forEach(function(a) { // without https 294 a.setAttribute('href', '/community/map-gallery') 295 a.setAttribute('target', '_self') 296}) 297 298 299// Do Not Knock Registry 300 301const txtStreetNumber = document.getElementById('doNotKnock_txtstreetnumber'); 302const selStreetName = document.getElementById('doNotKnock_selstreetname'); 303const doNotKnock_streetname = document.getElementById('doNotKnock_streetname'); 304const doNotKnock_suffix = document.getElementById('doNotKnock_suffix'); 305const doNotKnock_streetdir = document.getElementById('doNotKnock_streetdir'); 306const doNotKnock_apartment = document.getElementById('doNotKnock_apartment'); 307const doNotKnock_city = document.getElementById('doNotKnock_city'); 308const doNotKnock_state = document.getElementById('doNotKnock_state'); 309const doNotKnock_zip = document.getElementById('doNotKnock_zip'); 310const data = localStorage.getItem("residentialtaxable"); 311var taxable_data = JSON.parse(data); 312var select_streetnumber = ""; 313if (txtStreetNumber != null) { 314 txtStreetNumber.addEventListener('change', (event) => { 315 select_streetnumber = event.target.value; 316 var search_result = taxable_data.filter(function (entry) { 317 return entry.Number === event.target.value; 318 }); 319 if (search_result[0] != null) { 320 let ele = selStreetName; 321 removeOptions(selStreetName); 322 for (let i = 0; i < search_result.length; i++) { 323 ele.innerHTML = ele.innerHTML + 324 '<option value="' + search_result[i]['Name'] + '">' + search_result[i]['Name'] + ' ' + search_result[i]['StreetSuffix'] + ' ' + search_result[i]['StreetDir'] + ' ' + search_result[i]['Apartment'] + '</option>'; 325 } 326 } 327 var search_result_value = taxable_data.filter(function (entry) { 328 return entry.Name === selStreetName.value && entry.Number === select_streetnumber; 329 }); 330 if (search_result_value[0] != null) { 331 doNotKnock_streetname.value = search_result_value[0].Name + ' ' + search_result_value[0].StreetSuffix + ' ' + search_result_value[0].StreetDir + ' ' + search_result_value[0].Apartment; 332 doNotKnock_suffix.value = search_result_value[0].StreetSuffix; 333 doNotKnock_streetdir.value = search_result_value[0].StreetDir; 334 doNotKnock_apartment.value = search_result_value[0].Apartment; 335 doNotKnock_city.value = search_result_value[0].City; 336 doNotKnock_state.value = search_result_value[0].State; 337 doNotKnock_zip.value = search_result_value[0].Zip; 338 } 339 }) 340 if (selStreetName != null) { 341 selStreetName.addEventListener('change', (event) => { 342 var search_result = taxable_data.filter(function (entry) { 343 return entry.Name === event.target.value && entry.Number === select_streetnumber; 344 }); 345 if (search_result[0] != null) { 346 doNotKnock_streetname.value = search_result[0].Name + ' ' + search_result[0].StreetSuffix + ' ' + search_result[0].StreetDir + ' ' + search_result[0].Apartment; 347 doNotKnock_suffix.value = search_result[0].StreetSuffix; 348 doNotKnock_streetdir.value = search_result[0].StreetDir; 349 doNotKnock_apartment.value = search_result[0].Apartment; 350 doNotKnock_city.value = search_result[0].City; 351 doNotKnock_state.value = search_result[0].State; 352 doNotKnock_zip.value = search_result[0].Zip; 353 } 354 }) 355 } 356} 357function removeOptions(selectElement) { 358 var i, L = selectElement.options.length - 1; 359 for(i = L; i >= 0; i--) { 360 selectElement.remove(i); 361 } 362} 363 364 365// Search keywords log 366/* 367const quickSearchModalInput = document.getElementById('quickSearchModalInput'); 368 if(quickSearchModalInput != null){ 369 quickSearchModalInput.addEventListener('change', function () { 370 fetch('/?altTemplate=usersearchlog&searchkey='+ quickSearchModalInput.value, { 371 method: 'GET' 372 }); 373 }); 374 } 375 376 const headerSearchInput = document.getElementById('headerSearchInput'); 377 if(headerSearchInput != null){ 378 headerSearchInput.addEventListener('change', function () { 379 fetch('/?altTemplate=usersearchlog&searchkey='+ headerSearchInput.value, { 380 method: 'GET' 381 }); 382 }); 383 } 384 385 const searchInput = document.getElementById('searchInput'); 386 if(searchInput != null){ 387 searchInput.addEventListener('change', function () { 388 fetch('/?altTemplate=usersearchlog&searchkey='+ searchInput.value, { 389 method: 'GET' 390 }); 391 }); 392 }*/
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.