PageSourceSearch

https://www.umb.edu/media/umassboston/site-assets/javascript/t4-extras-js.js

js umb.edu collected 2026-10-01 08:35:49 UTC 15,550 bytes, 499 lines download raw bytes

1// close search box if clicked out of div
2/*document.addEventListener("DOMContentLoaded", function() {
3    var body = document.body;
4    var searchDiv = document.querySelector('.search');
5
6    if (body.classList.contains('search-active')) {
7        document.addEventListener('click', function(event) {
8          if (!searchDiv.contains(event.target)) {
9            body.classList.remove('search-active');
10          }
11        });
12    }
13});*/
14
15const buttonClose = document.querySelector(".js-remove-alert-urgent");
16if (buttonClose) { buttonClose.focus(); }
17
18
19$(document).ready(function () {
20  $(".js-remove-alert-urgent").on("click", function () {
21    $(".emergencynotice").hide();
22  });
23  /*$(".close-action").on("click", function () {
24    $(".information-alert").hide();
25  });*/
26});
27
28  /*$(".close-action").on("click", function () {
29    $(".information-alert").hide();
30  });*/
31
32window.onload = function() {
33  const urgentButtons = document.querySelectorAll('.js-remove-alert-urgent');
34  const emergencyDiv = document.querySelector('.emergencynotice');
35
36  urgentButtons.forEach(button => {
37    button.addEventListener('click', () => {
38        emergencyDiv.style.display = 'none!important';
39    });
40  });
41};
42
43/*document.addEventListener("DOMContentLoaded", function() {
44  const eventIntroductionMeta = document.querySelector('meta[name="EventIntroduction"]');
45  if (eventIntroductionMeta) {
46    let content = eventIntroductionMeta.getAttribute('content');
47    content = content.replace(/<[^>]+>/g,'');
48    if (content.length > 100) {
49      content = content.substring(0, 200) + '...';
50    }
51    eventIntroductionMeta.removeAttribute('https:');
52    eventIntroductionMeta.setAttribute('content', content);
53}  
54})*/
55
56/*document.addEventListener("DOMContentLoaded", function() {
57let detailsDeg = document.querySelector('#deg-dets'); 
58  if (detailsDeg && detailsDeg.hasAttribute('open')) {
59    document.addEventListener('click', function (e) { 
60      const contentDiv1 = document.querySelector('#deg-dets .content'); 
61
62      if(e.target !== contentDiv1) { 
63        detailsDeg.removeAttribute('open'); 
64      } 
65    });
66  }
67
68let detailsArea = document.querySelector('#area-dets'); 
69  if (detailsArea && detailsArea.hasAttribute('open')) {
70    document.addEventListener('click', function (e) { 
71      const contentDiv2 = document.querySelector('#area-dets .content'); 
72
73      if(e.target !== contentDiv2) { 
74        detailsArea.removeAttribute('open'); 
75      } 
76    });
77  }
78
79function clickOut() {
80let detailsDeg1 = document.querySelector('#deg-dets'); 
81  if (detailsDeg1 && detailsDeg1.hasAttribute('open')) {
82    document.addEventListener('click', function (e) { 
83      const contentDiv1 = document.querySelector('#deg-dets .content'); 
84
85      if(e.target !== contentDiv1) { 
86        detailsDeg1.removeAttribute('open'); 
87      } 
88    });
89  }
90
91let detailsArea1 = document.querySelector('#area-dets'); 
92  if (detailsArea1 && detailsArea1.hasAttribute('open')) {
93    document.addEventListener('click', function (e) { 
94      const contentDiv2 = document.querySelector('#area-dets .content'); 
95
96      if(e.target !== contentDiv2) { 
97        detailsArea1.removeAttribute('open'); 
98      } 
99    });
100  }
101}
102document.addEventListener("t4-after-ajax", clickOut);
103});*/
104
105//for general course search tab closing
106/*function courseSearchTabChange() {
107  var degreeButton = document.getElementById("deg-btn");
108  var areaButton = document.getElementById("area-btn");
109
110  var degreeDetails = document.getElementById("deg-dets");
111  var areaDetails = document.getElementById("area-dets");
112
113  // Event listener for tabs
114  if (typeof degreeButton != "undefined" && degreeButton != null) {
115    degreeButton.addEventListener("click", function () {
116      if (areaDetails.hasAttribute("open") == true) {
117        //remove open attribute
118        areaDetails.removeAttribute("open");
119      } else {
120        console.log("");
121      }
122    });
123  }
124
125  if (typeof areaButton != "undefined" && areaButton != null) {
126    areaButton.addEventListener("click", function () {
127      if (degreeDetails.hasAttribute("open") == true) {
128        //remove open attribute
129        degreeDetails.removeAttribute("open");
130      } else {
131        console.log("");
132      }
133    });
134  }
135}*/
136
137
138
139function checkboxAfter() {
140    var checkboxToRemove = document.querySelector('input[type="checkbox"][value="Category>T4_container"]');
141
142    // Check if the checkbox was found
143    if (checkboxToRemove) {
144        // Remove the checkbox element from its parent div
145        checkboxToRemove.parentNode.remove();
146    }
147}
148document.addEventListener("t4-after-ajax", checkboxAfter);
149
150
151document.addEventListener("DOMContentLoaded", function() {
152    var checkboxToRemove = document.querySelector('input[type="checkbox"][value="Category>T4_container"]');
153
154    // Check if the checkbox was found
155    if (checkboxToRemove) {
156        // Remove the checkbox element from its parent div
157        checkboxToRemove.parentNode.remove();
158    }
159});
160
161/* Remove Quotes Metatag */
162// var tables = document.querySelectorAll('table');
163var tables = document.querySelectorAll("table:not(.table-force-wrap)");
164tables.forEach(function(table) {
165  /*var parentDiv = table.closest('div');
166  if (parentDiv) {
167    parentDiv.style.overflowX = 'auto';
168  }*/
169  var parentDiv = document.createElement('div');
170  parentDiv.appendChild(table.cloneNode(true));
171  parentDiv.style.overflowX = 'auto';
172  table.parentNode.insertBefore(parentDiv, table);
173  table.parentNode.removeChild(table);
174});
175
176
177
178function updateMetaTagContent() {
179  const metaTags = document.querySelector('meta[name="EventIntroduction"]');
180  if (metaTags) {
181    const content = metaTags.getAttribute('content');
182    if (content) {
183      metaTags.setAttribute('content', content.replace(/"/g, '"'));
184    }
185  }
186}
187updateMetaTagContent();
188
189  const currentYear = new Date().getFullYear();
190  
191  const spanElement = document.getElementById('copyrightYear');
192
193if(spanElement) {
194  spanElement.textContent = currentYear;
195}
196
197//JS to resetURL
198//document.getElementById("#resetURL").addEventListener("click", resetURLOnFilterUnset);
199
200function resetURLOnFilterUnset(clicked_button) {
201  //var clicked_button = $(this).val();
202  var clickedButton = clicked_button
203    .replaceAll("+", "%2B")
204    .replaceAll(",", "%2C")
205    .replaceAll("_", "+");
206
207  var currentLocation = location.toString();
208
209  const newUrl = currentLocation.split("?");
210
211  newUrl[1];
212
213  var newloc = newUrl[1].split("&");
214
215  const match = newloc.find((element) => {
216    if (element.includes(clickedButton)) {
217      return true;
218    }
219  });
220
221  const removeDataFromURL = currentLocation.replace(match, "");
222
223  const updatedURL = removeDataFromURL.replace("&&", "&");
224
225  const finalURL = updatedURL.replace(/&\s*$/, "");
226
227  window.location.href = finalURL;
228}
229
230// Wraps all the table elements in a <div> and adds "c-table" and "hscroll" classes to that <div>.
231(function () {
232  //const tables = document.querySelectorAll("table");
233  const tables = document.querySelectorAll("table:not(.table-force-wrap)");
234  const tablesArray = Array.from(tables);
235
236  tables.forEach((table) => {
237    //const parent = table.parentNode;
238    const wrapper = document.createElement("div");
239    wrapper.classList.add("c-table", "hscroll");
240    //wrapper.appendChild(table);
241    //parent.appendChild(wrapper);
242    table.parentNode.insertBefore(wrapper, table)
243    wrapper.appendChild(table)
244  });
245})();
246
247
248
249//for general header video play pause
250var playButton = document.getElementById("play_button");
251var video = document.getElementById("video_lib");
252
253// Event listener for the play/pause button
254
255if (typeof video != "undefined" && video != null) {
256  playButton.addEventListener("click", function () {
257    if (video.paused == true) {
258      // Play the video
259      video.play();
260      playButton.setAttribute("data-playing", "");
261    } else if (video.paused == false) {
262      // Pause the video
263      video.pause();
264      playButton.removeAttribute("data-playing");
265    } else {
266      console.log("no video");
267    }
268  });
269}
270
271
272//for grid and list views
273function courseSearchViewChange() {
274  var listButton = document.getElementById("btn-list-view");
275  var gridButton = document.getElementById("btn-grid-view");
276
277  var programView = document.getElementById("content-main");
278
279  // Event listener for the grid list buttons
280
281  if (typeof listButton != "undefined" && listButton != null) {
282    listButton.addEventListener("click", function () {
283      if (programView.hasAttribute("data-grid") == true) {
284        //remove grid attribute
285        programView.removeAttribute("data-grid");
286      } else {
287        //do nothing
288      }
289    });
290  }
291
292  if (typeof gridButton != "undefined" && gridButton != null) {
293    gridButton.addEventListener("click", function () {
294      if (programView.hasAttribute("data-grid") == false) {
295        //add grid attribute
296        programView.setAttribute("data-grid", "");
297      } else {
298        //do nothing
299      }
300    });
301  }
302}
303
304
305/* automated faculty list order js */
306/* 
307$(".auto-list-1col-group .auto-list-1col, .auto-list-2col-group .auto-list-2col, .auto-list-only-group .auto-list-only").each(function() {
308  $(this).find('div.staff').sort(function(a, b) {
309    var aText = $(a).text(),
310      bText = $(b).text();
311    return aText < bText ? -1 : aText > bText ? 1 : 0;
312  }).appendTo(this);
313});
314*/
315
316
317           
318
319
320
321
322
323
324
325
326
327/* Accordion Javascript */
328document.addEventListener('DOMContentLoaded', function () {
329    const searchResultsDiv = document.querySelector('#search-results');
330
331    if (searchResultsDiv) {
332        searchResultsDiv.addEventListener('click', function (event) {
333            const trigger = event.target.closest('.umass-course-accordion-title');
334
335            if (trigger) {
336                const parentRow = trigger.closest('.umass-course-accordion-header');
337                const isOpen = parentRow.classList.toggle('open');
338                let nextRow = parentRow.nextElementSibling;
339
340                const allAccordionContent = document.querySelectorAll('.umass-course-accordion-content');
341                allAccordionContent.forEach(row => row.classList.remove('last-open'));
342
343                let lastVisibleRow = null;
344
345                while (nextRow && nextRow.classList.contains('umass-course-accordion-content')) {
346                    const contentWrapper = nextRow.querySelector('.accordion-content-wrapper');  
347
348                    if (isOpen) {
349                        nextRow.style.display = 'table-row';  
350                        expandAccordion(contentWrapper); 
351
352                        lastVisibleRow = nextRow;
353                    } else {
354
355                        collapseAccordion(contentWrapper, nextRow);   
356                    }
357                    nextRow = nextRow.nextElementSibling;
358                }
359
360                if (lastVisibleRow) {
361                    lastVisibleRow.classList.add('last-open');
362                }
363            }
364        });
365    }
366
367    function expandAccordion(element) {
368        element.style.height = '0'; 
369        element.style.overflow = 'hidden';  
370        element.style.opacity = '1';  
371
372        const fullHeight = element.scrollHeight + 'px';
373
374        element.offsetHeight;
375
376        element.style.transition = 'height 600ms ease-out, opacity 600ms ease-out';
377        element.style.height = fullHeight; 
378
379        element.addEventListener('transitionend', () => {
380            element.style.height = 'auto'; 
381            element.style.overflow = '';
382        }, { once: true });
383    }
384
385
386    function collapseAccordion(element, nextRow) {
387
388        const startHeight = element.scrollHeight + 'px';
389
390        element.style.height = startHeight;
391
392        element.offsetHeight;
393
394        requestAnimationFrame(() => {
395            element.style.transition = 'height 600ms ease-out, opacity 300ms ease-out';
396            element.style.height = '0px'; 
397            element.style.opacity = '0'; 
398        });
399
400        element.addEventListener('transitionend', () => {
401            nextRow.style.display = 'none'; 
402            element.style.opacity = '1';  
403        }, { once: true });
404    }
405});
406
407
408/* link click to show/hide divs */
409
410$(document).ready(function() {
411    // When any link is clicked
412    $('.social-media-directory-link').click(function(event) {
413        event.preventDefault(); // Prevent default link behavior
414        
415        // Hide all divs
416        $('.social-media-content').hide();
417        
418        // Show the corresponding div based on the link clicked
419        var targetDiv = $(this).data('target');
420        $(targetDiv).show();
421    });
422});
423
424
425/* Open an accordion when it is the target of a fragment link.
426   The id sits on the <details> element itself, so the browser's built-in
427   "reveal ancestor details" behavior does not apply (an element is not its
428   own ancestor) -- the page just scrolls without opening. */
429(function () {
430  const openFromHash = (hash) => {
431    if (!hash || hash === '#') return;
432
433    // Accept both "#1928566" and "#d.en.1928566".
434    let id;
435    try {
436      id = decodeURIComponent(hash.slice(1));
437    } catch (e) {
438      return;
439    }
440
441    let target = document.getElementById(id);
442    if (!target) {
443      const m = id.match(/^d\.en\.(\d+)$/);
444      if (m) target = document.getElementById(m[1]);
445    }
446    if (!target) return;
447
448    // The target is normally the <details>; fall back to a wrapping one, or
449    // to a <details> immediately following a "d.en." marker span.
450    const details =
451      target.closest('details') ||
452      (target.nextElementSibling &&
453       target.nextElementSibling.tagName === 'DETAILS'
454        ? target.nextElementSibling
455        : null);
456    if (!details || details.open) return;
457
458    // Click the <summary> rather than setting .open directly, so the site's
459    // Accordion class (main.js) runs its height animation and keeps its
460    // isClosing/isExpanding state in sync.
461    const summary = details.querySelector('summary');
462    if (summary) {
463      summary.click();
464    } else {
465      details.open = true;
466    }
467
468    // Re-scroll once the 400ms expand has finished.
469    setTimeout(() => {
470      details.scrollIntoView({ behavior: 'smooth', block: 'start' });
471    }, 420);
472  };
473
474  const init = () => {
475    // Deep link on page load.
476    openFromHash(window.location.hash);
477
478    // Back/forward navigation.
479    window.addEventListener('hashchange', () => openFromHash(window.location.hash));
480
481    // Same-page clicks: hashchange does not fire when the hash is already
482    // the current one, so handle the click directly.
483    document.addEventListener('click', (event) => {
484      const link = event.target.closest('a[href]');
485      if (!link || !link.hash) return;
486      if (link.host !== window.location.host) return;
487      if (link.pathname !== window.location.pathname) return;
488      openFromHash(link.hash);
489    });
490  };
491
492  // Guard against DOMContentLoaded having already fired -- e.g. if this file
493  // is ever loaded with defer/async or injected via a tag manager.
494  if (document.readyState === 'loading') {
495    document.addEventListener('DOMContentLoaded', init);
496  } else {
497    init();
498  }
499})();

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.