kcc-gem-theme 1.67.69 → 1.70.71

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2c56929492a3b3237fe42b04acb02a49af4668dacba7e67de920a7896b7d9003
4
- data.tar.gz: 326764b32e97866689f82569ba90c343b128d2a0f5dc1c747f26c7d51f8b7a27
3
+ metadata.gz: 24f4acacd0f4a33d8a95da3480fb67c4f958544775c0f5e8194df7c8724b287c
4
+ data.tar.gz: cee877dfe62050535469131681e592d870b1a7f596f6a56f620655bc29e42ef0
5
5
  SHA512:
6
- metadata.gz: e994fa89f53c47df06e33e2707c42703777cd57af0c7137d774a7dfd29edcb2afad0530ce7b76a010b2f072d856ce04d67256bac56a18a3dfb7999d2bcf4b2e6
7
- data.tar.gz: 4eaabeee123627fbdfa541c465b9769ac9ae2e0ce66f7c43a40db57c92472440b31a0d09d141132430f09fdaa13997f2c1b40d807420849f064d0f2235a4e43a
6
+ metadata.gz: 68475fcde0d91e47be7e4d2dd60a58e9edf9d34aa12eed453b5f53cea6b78f1882bc41a2b5a0700f92af41bcc297198186a5a92cbdf11a655f4bc0e6ff9098b2
7
+ data.tar.gz: 867cd775d7a83fd93636d5cb63f983c03fcdce208140c17cd58c3534ea36cdf2c31fa7f52a835ba3312b51f58d1f1e07f9c71aaa0d5e1454b7b25981ac22170c
@@ -1 +1 @@
1
- 680d788e5a9ab08cc7f2
1
+ 37746a1db9406814aa58
@@ -1,8 +1,8 @@
1
- {% assign sorted_contacts = site.contacts | sort: "display_order" %}
1
+ {%- assign sorted_contacts = site.contacts | sort: "display_order" -%}
2
2
  <section>
3
3
  <div class="container">
4
4
  <div class="row">
5
- <div class="col margins__col--top home__col--heading-underline-tan">
5
+ <div class="col mt-1 home__col--heading-underline home__col--heading-underline-tan">
6
6
  <h3 id="contact" class="typography__section--heading margins__heading--btm links__offset">Contacts</h3>
7
7
  </div>
8
8
  </div>
@@ -14,15 +14,15 @@
14
14
  </div>
15
15
  </div>
16
16
  <div class="row">
17
- {% for contact in sorted_contacts %}
18
- {% assign contact_name = contact.name | split: " " %}
19
- {% assign first = contact_name[0] %}
20
- {% assign last = contact_name[1] %}
21
- {% if contact.portrait != 'For departments with no contact photos, do not change this field.' and contact.portrait != 'none' %}
17
+ {%- for contact in sorted_contacts -%}
18
+ {%- assign contact_name = contact.name | split: " " -%}
19
+ {%- assign first = contact_name[0] -%}
20
+ {%- assign last = contact_name[1] -%}
21
+ {% if contact.portrait_image != "For departments with no contact photos, do not change this field." %}
22
22
  <div class="col-md-6 contacts__col-bottom-margin">
23
23
  <div class="row">
24
24
  <div class="col-4 contacts__col--img">
25
- <img src="assets/img/blank-contact.svg" data-src="{{ page.baseurl }}{{ contact.portrait }}" alt="{{ contact.name }}" class="img-fluid contacts__portrait" />
25
+ {% if contact.portrait_image != 'none' %}<img src="{{ page.baseurl }}assets/img/placeholder_square.jpg" data-src="{{ page.baseurl }}{{ contact.portrait_image }}" alt="Photo of {{ contact.name }}" class="img-fluid contacts__portrait" />{% endif %}
26
26
  </div>
27
27
  <div class="col-8 float-right">
28
28
  <h5 class="typography__contacts--name notranslate">{{ contact.name }}</h5>
@@ -30,24 +30,8 @@
30
30
  <p class="notranslate">
31
31
  {% if contact.phone %}<a href="tel:1{{ contact.phone | remove: '-' }}" class="links__darker-link">{{ contact.phone }}</a><br>{% endif %}
32
32
  {% if contact.email %}<a class="links__darker-link" target="_blank" href="https://secure.jotform.com/90435102482954?to[first]={{ first }}&amp;to[last]={{ last }}&amp;submitEmail={{ contact.email | remove: '@kcc.edu' }}%40kcc.edu">Email</a><br>{% endif %}
33
- {% if contact.fax %}Fax: {{ contact.fax }}{% endif %}
34
- </p>
35
- </div>
36
- </div>
37
- </div>
38
- {% elsif contact.portrait == 'none' %}
39
- <div class="col-md-6 contacts__col-bottom-margin">
40
- <div class="row">
41
- <div class="col-4 contacts__col--img">
42
- <!-- Contact has no portrait -->
43
- </div>
44
- <div class="col-8 float-right">
45
- <h5 class="typography__contacts--name notranslate">{{ contact.name }}</h5>
46
- {% if contact.contacts_title %}<h6 class="typography__contacts--title">{{ contact.contacts_title }}</h6>{% endif %}
47
- <p class="notranslate">
48
- {% if contact.phone %}<a href="tel:1{{ contact.phone | remove: '-' }}" class="links__darker-link">{{ contact.phone }}</a><br>{% endif %}
49
- {% if contact.email %}<a class="links__darker-link" target="_blank" href="https://secure.jotform.com/90435102482954?to[first]={{ first }}&amp;to[last]={{ last }}&amp;submitEmail={{ contact.email | remove: '@kcc.edu' }}%40kcc.edu">Email</a><br>{% endif %}
50
- {% if contact.fax %}Fax: {{ contact.fax }}{% endif %}
33
+ {%- if contact.fax -%}Fax: {{ contact.fax }}{% endif %}
34
+ {%- if contact.bio == true -%}<button type="button" class="btn btn-primary mt-2" data-toggle="modal" data-target="#{{ contact.name | downcase | replace: ' ', '-' | remove: '.' | remove: '/' | remove: "'" | remove: '’' }}">View Bio</button>{% endif %}
51
35
  </p>
52
36
  </div>
53
37
  </div>
@@ -60,10 +44,37 @@
60
44
  {% if contact.phone %}<a href="tel:1{{ contact.phone | remove: '-' }}" class="links__darker-link">{{ contact.phone }}</a><br>{% endif %}
61
45
  {% if contact.email %}<a class="links__darker-link" target="_blank" href="https://secure.jotform.com/90435102482954?to[first]={{ first }}&amp;to[last]={{ last }}&amp;submitEmail={{ contact.email | remove: '@kcc.edu' }}%40kcc.edu">Email</a><br>{% endif %}
62
46
  {% if contact.fax %}Fax: {{ contact.fax }}{% endif %}
47
+ {% if contact.bio == true %}<button type="button" class="btn btn-primary mt-2" data-toggle="modal" data-target="#{{ contact.name | downcase | replace: ' ', '-' | remove: '.' | remove: '/' | remove: "'" | remove: '’' }}">View Bio</button>{% endif %}
63
48
  </p>
64
49
  </div>
65
- {% endif %}
66
- {% endfor %}
50
+ {%- endif -%}
51
+ {%- endfor -%}
67
52
  </div>
68
53
  </div>
69
54
  </section>
55
+ {% for contact in sorted_contacts %}
56
+ {%- if contact.bio == true -%}
57
+ <!-- Modal -->
58
+ <div class="modal fade" id="{{ contact.name | downcase | replace: ' ', '-' | remove: '.' | remove: '/' | remove: "'" | remove: '’' }}" tabindex="-1" aria-labelledby="{{ contact.name | downcase | replace: ' ', '-' | remove: '.' | remove: '/' | remove: "'" | remove: '’' }}-label" aria-hidden="true">
59
+ <div class="modal-dialog">
60
+ <div class="modal-content">
61
+ <div class="modal-header">
62
+ <h5 class="typography__h6" id="{{ contact.name | downcase | replace: ' ', '-' | remove: '.' | remove: '/' | remove: "'" | remove: '’' }}-label">{{ contact.name }} Bio</h5>
63
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
64
+ <span aria-hidden="true">&times;</span>
65
+ </button>
66
+ </div>
67
+ <div class="modal-body">
68
+ {% if contact.portrait_image != 'For departments with no contact photos, do not change this field.' and contact.portrait_image != 'none' %}<img src="{{ page.baseurl }}assets/img/placeholder_square.jpg" data-src="{{ page.baseurl }}{{ contact.portrait_image }}" class="img-fluid float-left mr-2 mb-2" alt="Photo of {{ contact.name }} KCC's {{ contact.contacts_title }}">{% endif %}
69
+ <h5 class="typography__contacts--name notranslate">{{ contact.name }}</h5>
70
+ {% if contact.contacts_title %}<h6 class="typography__contacts--title">{{ contact.contacts_title }}</h6>{% endif %}
71
+ {{ contact.content }}
72
+ </div>
73
+ <div class="modal-footer">
74
+ <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
75
+ </div>
76
+ </div>
77
+ </div>
78
+ </div>
79
+ {%- endif -%}
80
+ {% endfor %}
@@ -2,10 +2,12 @@
2
2
  <section>
3
3
  <div class="container">
4
4
  <div class="row">
5
- <div class="col mt-1 home__col--heading-underline">
5
+ <div class="col mt-1 home__col--heading-underline{% if page.contacts_background_tan == true %} home__col--heading-underline-tan{% endif %}">
6
6
  <h3 id="contact" class="typography__section--heading margins__heading--btm links__offset">Contacts</h3>
7
7
  </div>
8
8
  </div>
9
+ {% if page.contacts_background_tan == true %}</div>
10
+ <div class="container contacts__padding-top background__color--tan">{% endif %}
9
11
  <div class="row editor-link">
10
12
  <div class="col editor-link mb-3">
11
13
  <a href="cloudcannon:collections/_contacts/" class="btn btn-success editor-button">Edit Contacts</a>
@@ -16,29 +18,11 @@
16
18
  {%- assign contact_name = contact.name | split: " " -%}
17
19
  {%- assign first = contact_name[0] -%}
18
20
  {%- assign last = contact_name[1] -%}
19
- {% if contact.portrait != "For departments with no contact photos, do not change this field." and contact.portrait != 'none' %}
21
+ {% if contact.portrait_image != "For departments with no contact photos, do not change this field." %}
20
22
  <div class="col-md-6 contacts__col-bottom-margin">
21
23
  <div class="row">
22
24
  <div class="col-4 contacts__col--img">
23
- <img src="{{ page.baseurl }}assets/img/blank-contact.svg" data-src="{{ page.baseurl }}{{ contact.portrait }}" alt="Photo of {{ contact.name }}" class="img-fluid contacts__portrait" />
24
- </div>
25
- <div class="col-8 float-right">
26
- <h5 class="typography__contacts--name notranslate">{{ contact.name }}</h5>
27
- {% if contact.contacts_title %}<h6 class="typography__contacts--title">{{ contact.contacts_title }}</h6>{% endif %}
28
- <p class="notranslate">
29
- {% if contact.phone %}<a href="tel:1{{ contact.phone | remove: '-' }}" class="links__darker-link">{{ contact.phone }}</a><br>{% endif %}
30
- {% if contact.email %}<a class="links__darker-link" target="_blank" href="https://secure.jotform.com/90435102482954?to[first]={{ first }}&amp;to[last]={{ last }}&amp;submitEmail={{ contact.email | remove: '@kcc.edu' }}%40kcc.edu">Email</a><br>{% endif %}
31
- {%- if contact.fax -%}Fax: {{ contact.fax }}{% endif %}
32
- {%- if contact.bio == true -%}<button type="button" class="btn btn-primary mt-2" data-toggle="modal" data-target="#{{ contact.name | downcase | replace: ' ', '-' | remove: '.' | remove: '/' | remove: "'" | remove: '’' }}">View Bio</button>{% endif %}
33
- </p>
34
- </div>
35
- </div>
36
- </div>
37
- {% elsif contact.portrait == 'none' %}
38
- <div class="col-md-6 contacts__col-bottom-margin">
39
- <div class="row">
40
- <div class="col-4 contacts__col--img">
41
- <!-- No contact portrait -->
25
+ {% if contact.portrait_image != 'none' %}<img src="{{ page.baseurl }}assets/img/placeholder_square.jpg" data-src="{{ page.baseurl }}{{ contact.portrait_image }}" width="150px" height="150px" alt="Photo of {{ contact.name }}" class="img-fluid contacts__portrait" />{% endif %}
42
26
  </div>
43
27
  <div class="col-8 float-right">
44
28
  <h5 class="typography__contacts--name notranslate">{{ contact.name }}</h5>
@@ -81,7 +65,7 @@
81
65
  </button>
82
66
  </div>
83
67
  <div class="modal-body">
84
- {% if contact.portrait %}<img src="{{ page.baseurl }}assets/img/blank-contact.svg" data-src="{{ page.baseurl }}{{ contact.portrait }}" class="img-fluid float-left mr-2 mb-2" alt="Photo of {{ contact.name }} KCC's {{ contact.contacts_title }}">{% endif %}
68
+ {% if contact.portrait_image != 'For departments with no contact photos, do not change this field.' and contact.portrait_image != 'none' %}<img src="{{ page.baseurl }}assets/img/placeholder_square.jpg" data-src="{{ page.baseurl }}{{ contact.portrait_image }}" class="img-fluid float-left mr-2 mb-2" width="150px" height="150px" alt="Photo of {{ contact.name }} KCC's {{ contact.contacts_title }}">{% endif %}
85
69
  <h5 class="typography__contacts--name notranslate">{{ contact.name }}</h5>
86
70
  {% if contact.contacts_title %}<h6 class="typography__contacts--title">{{ contact.contacts_title }}</h6>{% endif %}
87
71
  {{ contact.content }}
@@ -12,7 +12,7 @@
12
12
  </div>
13
13
  {% else %}
14
14
  <div>
15
- <a {% if slide.url contains "https://" or slide.url contains "http://" %}href="{{ slide.url }}"{% elsif url_first_char == "." or url_first_char == "/" %}href="{{ slide.url }}"{% else %}href="{{ page.baseurl }}{{ slide.url }}{% endif %}"{% if slide.new_tab == true %} target="_blank" rel="noopener noreferrer"{% endif %}><img src="{{ page.baseurl }}assets/img/kcc-placeholder.png" data-src="{{page.baseurl}}{{slide.image}}" class="img-fluid hero-slider__slider--slide-img {% if slide.white_background %} hero-slider__slide-img--border{% endif %}" alt="{{slide.alt-text}}" /></a>
15
+ <a {% if slide.url contains "https://" or slide.url contains "http://" %}href="{{ slide.url }}"{% elsif url_first_char == "." or url_first_char == "/" %}href="{{ slide.url }}"{% else %}href="{{ page.baseurl }}{{ slide.url }}{% endif %}"{% if slide.new_tab == true %} target="_blank" rel="noopener noreferrer"{% endif %}><img src="{{ page.baseurl }}assets/img/placeholder_16to9.jpg" data-src="{{page.baseurl}}{{slide.image}}" class="img-fluid hero-slider__slider--slide-img {% if slide.white_background %} hero-slider__slide-img--border{% endif %}" alt="{{slide.alt-text}}" /></a>
16
16
  {% if slide.text and slide.text != "" %}<div class="hero-slider__slider--heading-container text-center">
17
17
  <h3 class="hero-slider__slider--slide-heading">{{slide.text}}</h3>
18
18
  </div>{% endif %}
@@ -14,7 +14,7 @@
14
14
  {% include scripts/google-noscript.html %}
15
15
  {% if site.translate == true %}{% include translate.html %}{% endif %}
16
16
  {% include header-global.html %}
17
- {% if site.core_root != true %}{% include emergency-alerts.html %}{% endif %}
17
+ {% if site.core_root != true and page.no_alert != true %}{% include emergency-alerts.html %}{% endif %}
18
18
  {{ content }}
19
19
  {% include footer.html %}
20
20
  {% include scripts/vendor-cdn.html %}
@@ -15,7 +15,7 @@
15
15
  {% if site.translate == true %}{% include translate.html %}{% endif %}
16
16
  {% include nav-global.html %}
17
17
  {% if page.no_local_nav != true %}{% include nav-local.html %}{% endif %}
18
- {% include emergency-alerts.html %}
18
+ {% if page.no_alert != true %}{% include emergency-alerts.html %}{% endif %}
19
19
  {{ content }}
20
20
  {% include footer.html %}
21
21
  {% include scripts/vendor-cdn.html %}
@@ -0,0 +1,6 @@
1
+ ---
2
+ layout: default-core
3
+ ---
4
+
5
+ {% include nav-sub.html %}
6
+ {{ content }}
@@ -1,5 +1,12 @@
1
+ /*
2
+ // Custom JS | written by https://github.com/wdzajicek
3
+ // © 2020 Kankakee Community College
4
+ // =================================================== */
1
5
  import start from './campusAlertsSheetsAPI.js';
6
+ import getCachedResponse from './getCachedResponse.js';
2
7
 
3
- document.addEventListener('DOMContentLoaded', function() {
4
- gapi.load('client', start);
8
+ document.addEventListener('DOMContentLoaded', () => {
9
+ ! window.sessionStorage.getItem('Alert-Content') ? // Checks if our cached alert is already in sessionStorage
10
+ gapi.load('client', start) // If not, build the alert from a new Google API response
11
+ : getCachedResponse(); // Otherwise, build the alert from our cached response
5
12
  });
@@ -0,0 +1,23 @@
1
+ /*
2
+ // Custom JS | written by https://github.com/wdzajicek
3
+ // © 2020 Kankakee Community College
4
+ // =================================================== */
5
+ // Modules' default function stores our Google Sheet response in sessionStorage to be retrieved later
6
+ // Each key gets set to a column in our data
7
+ // Each key's value gets set to the corresponding cell in the row below
8
+ // ====================================================================
9
+ function cacheResponse(response) { // response from Google API's spreadsheet.values.get() method
10
+ const VALUES = response.result.values; // This is where the table's data is in a Sheets response in Sheets API V4
11
+ const TABLE_HEADER_ROW = VALUES[1]; // 2nd row in the sheet (first row is instructions to the user)
12
+ const TABLE_BODY_ROW = VALUES[2]; // The only row of data in our table
13
+
14
+ for (let i = 0, len = TABLE_BODY_ROW.length; i < len; i++ ) {
15
+ const cell = TABLE_BODY_ROW[i];
16
+ const column = TABLE_HEADER_ROW[i];
17
+
18
+ window.sessionStorage.setItem(column.replace(' ', '-'), cell);
19
+ }
20
+ //window.sessionStorage.clear();
21
+ }
22
+
23
+ export default cacheResponse;
@@ -1,40 +1,52 @@
1
+ /*
2
+ // Custom JS | written by https://github.com/wdzajicek
3
+ // © 2020 Kankakee Community College
4
+ // =================================================== */
5
+ // 1. Execute Google API call to grab Google Sheet data from:
6
+ // https://docs.google.com/spreadsheets/d/1plXBiZY5pVbhNT-mszxEuqCl4zy8wMnz9gXXbbT_yLs/edit#gid=0
7
+ // 2. Build & inject the alert message into the page
8
+ // 3. Run the `tabLink.js` module after alert has painted into DOM (and altered documents hight)
9
+ // 4. Cache the API response in sessionStorage
10
+ // =================================================== //
1
11
  import setSheetParameters from './simpleSetSheetParameters.js';
2
12
  import createAlertsHtml from './createAlertsHtml.js';
13
+ import makeTabsLinkable from './tabLink.js';
14
+ import cacheResponse from './cacheResponse.js';
3
15
 
4
16
  const SHEET_KEY = '1plXBiZY5pVbhNT-mszxEuqCl4zy8wMnz9gXXbbT_yLs';
5
17
  const SHEET_TAB_NAME = 'Alerts';
6
18
  const EMERGENCY_ALERT_DIV_ID = 'emergencyAlerts'
19
+ const SHEET_PARAMS = setSheetParameters(SHEET_KEY, SHEET_TAB_NAME);
20
+ const PARAMS = { // This is configuration for API call with spreadsheets that are setup as readonly
21
+ 'apiKey': 'AIzaSyCEBsbXfFcdbkASlg-PodD1rT_Fe3Nw62A',
22
+ 'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/sheets/v4/rest']
23
+ };
24
+
25
+ function init() {
26
+ gapi.client.init(PARAMS).then(function() { // Executes an API request, and returns a Promise.
27
+ return gapi.client.sheets.spreadsheets.values.get(SHEET_PARAMS)
28
+ .then((response) => {
29
+ createAlertsHtml(response); // Build the html & inject it into the DOM
30
+ return response;
31
+ }).then((response) => {
32
+ makeTabsLinkable(); // Handle hash & query URI's to target accordion and tabbed-nav content
33
+ cacheResponse(response); // Cache the Google API response for subsequent page loads in the site
34
+ },
35
+ function(err) {
36
+ console.error("Execute error", err);
37
+ makeTabsLinkable();
38
+ });
39
+ });
40
+ }
7
41
 
8
42
  function start() {
9
43
  if ( ! document.getElementById(EMERGENCY_ALERT_DIV_ID) )
10
- return;
44
+ return makeTabsLinkable();
11
45
 
12
- //var t0 = performance.now();
13
46
  init();
14
47
  //var t1 = performance.now();
15
48
  //console.info("Call to 'init' took " + (t1 - t0) + " milliseconds.");
16
49
  }
17
-
18
- function init() {
19
- const params = {
20
- 'apiKey': 'AIzaSyCEBsbXfFcdbkASlg-PodD1rT_Fe3Nw62A',
21
- 'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/sheets/v4/rest']
22
- };
23
- const sheetParams = setSheetParameters(SHEET_KEY, SHEET_TAB_NAME);
24
-
25
- gapi.client.init(params).then(function() { // Executes an API request, and returns a Promise.
26
- function execute() {
27
- return gapi.client.sheets.spreadsheets.values.get(sheetParams)
28
- .then(function(response) {
29
- createAlertsHtml(response);
30
- },
31
- function(err) {
32
- console.error("Execute error", err);
33
- });
34
- }
35
- execute();
36
- });
37
- }
38
50
  // Loads the JavaScript client library and invokes `start` afterwards.
39
51
  // Usage:
40
52
  // gapi.load('client', start);
@@ -1,9 +1,13 @@
1
- // Custom JS to build an alert message using data coming from a Google Sheets (Using the Sheets API v4)
2
- // ==================================================================================
3
- // This exported module requires you pass the function the `response` object from the API call,
4
- // and `resolve()` from the Promise that the function call is wrapped in (see './campusAlertsSheetsAPI.js')
1
+ /*
2
+ // Custom JS | written by https://github.com/wdzajicek
3
+ // © 2020 Kankakee Community College
4
+ // =================================================== */
5
+ // JS module to build alert message using data from Google Sheets API v4
6
+ //
7
+ // This exported module requires you pass it's default-function the `response` object from the API call, as the only argument
8
+ import makeTabsLinkable from './tabLink.js';
5
9
  import parseMarkdownToHTML from './parseMarkdownToHTML.js';
6
-
10
+ //
7
11
  const CAMPUS_ALERTS_DIV_ID_STRING = 'emergencyAlerts'; // ID of the div to house campus alerts - already built into the page.
8
12
  const BOOTSTRAP_CONTAINER_CLASS = 'container'; // Class used in Bootstrap 4
9
13
  const BOOTSTRAP_ROW_CLASS = 'row'; // Class used in Bootstrap 4
@@ -12,7 +16,6 @@ const BOOTSTRAP_CLOSE_CLASS = 'close'; // Class used in Bootstrap 4
12
16
  const TRUE_FROM_SHEETS = 'TRUE'; // Because Google Sheets does 'TRUE' & 'FALSE' in all caps, unlike JavaScript
13
17
  const FALSE_FROM_SHEETS = 'FALSE'; // Because Google Sheets does 'TRUE' & 'FALSE' in all caps, unlike JavaScript
14
18
  const BOOTSTRAP_ALERT_CLASS_ARRAY = ['alert', 'alert-warning']; // BS4 classes for alerts
15
- const PARAGRAPH_CLASS_ARRAY = ['typography__alert', 'mb-0']; // KCC Gem Theme & Bootstrap 4 class strings in an array
16
19
  const ALERTS_VISIBLE_CLASS = 'position__offset-alert--visible';
17
20
 
18
21
  function addClassesToEl(el, classArr) {
@@ -67,7 +70,7 @@ function init(SHEET_DATA) {
67
70
  }
68
71
 
69
72
  function checkAlertPages(SHEET_DATA) {
70
- const DISPLAY_ALERT_ON_ALL_PAGES = SHEET_DATA[1] === TRUE_FROM_SHEETS; // Second cell toggles if it displayes on just homepages or all pages of the sites
73
+ const DISPLAY_ALERT_ON_ALL_PAGES = SHEET_DATA[1] === TRUE_FROM_SHEETS; // Second cell toggles if it displays on just homepages or all pages of the sites
71
74
  const pathname = window.location.pathname;
72
75
  const locationIsHomepage = pathname === '/';
73
76
 
@@ -79,11 +82,13 @@ function checkAlertPages(SHEET_DATA) {
79
82
  }
80
83
 
81
84
  function createAlertsHtml(response) { // Incoming response from our Google Sheet via the Sheets API
85
+ if ( ! document.getElementById(CAMPUS_ALERTS_DIV_ID_STRING) )
86
+ return makeTabsLinkable();
87
+
82
88
  // This is where the cell values hide in the response object from the Google API.
83
89
  const SHEET_CELL_VALUES_ARRAY = response.result.values; // `values` is an array consisting of an array for each row (i.e an array of arrays)
84
90
  const SHEET_DATA = SHEET_CELL_VALUES_ARRAY[2]; // Selecting the third row of the values array. This is where all the important options/data are in the Google Sheet
85
91
  const ALERT_VISIBILITY_IS_FALSE = SHEET_DATA[0] === FALSE_FROM_SHEETS; // First cell(SHEET_DATA[0]) is to toggle the alert's visibility.
86
-
87
92
  if ( ALERT_VISIBILITY_IS_FALSE )
88
93
  return;
89
94
 
@@ -0,0 +1,41 @@
1
+ /*
2
+ // Custom JS | written by https://github.com/wdzajicek
3
+ // © 2020 Kankakee Community College
4
+ // =================================================== */
5
+ // Module to retrieve our cached Google Sheet response from sessionStorage
6
+ // 1. Create an object that replicates an API response where `response.result.values`
7
+ // is an array containing an array representing each row in the sheet.
8
+ // 2. Then we pass our mock-sheet response object to the `createAlertsHtml` module to
9
+ // build and inject the alert into the DOM.
10
+ import createAlertsHtml from './createAlertsHtml.js';
11
+ import makeTabsLinkable from './tabLink.js';
12
+ const cache = window.sessionStorage;
13
+
14
+ function processCachedResponse(response, callback) {
15
+ createAlertsHtml(response);
16
+ return callback();
17
+ }
18
+
19
+ function createCachedResponseObject() {
20
+ let cachedResponse = { // Reconstructing our own Google Sheet-like response from the sessionStorage items
21
+ result: {
22
+ values: [
23
+ 0, // First two rows aren't used by the `createAlertsHtml()` function
24
+ 0,
25
+ [ cache.Visible, cache.getItem('All-Pages'), cache.getItem('Alert-Content'), cache.getItem('Alert-Expiration'), cache.Start, cache.End ]
26
+ ]
27
+ }
28
+ }
29
+ processCachedResponse(cachedResponse, makeTabsLinkable);
30
+ }
31
+
32
+ function getCachedResponse() {
33
+ try {
34
+ createCachedResponseObject();
35
+ } catch (error) {
36
+ makeTabsLinkable();
37
+ console.error(`Error retrieving cached response in sessionStorage:\nName: ${error.name}\nMessage: ${error.message}\n${error}`);
38
+ }
39
+ }
40
+
41
+ export default getCachedResponse;
@@ -0,0 +1,81 @@
1
+ // Custom JS to do cool stuff with BS accordions and tabs by manipulating URL hashes and query's
2
+ // EXAMPLE:
3
+ // https://<ORIGIN>/?id=course-withdrawals#tuition-payment-and-deadlines
4
+ // The above URL will:
5
+ // 1. Open the #tuition-payment-and-deadlines accordion if it exists
6
+ // 2. The ?id=course-withdrawals query will:
7
+ // - look inside the opened accordion for an element with the id 'course-withdrawals', and
8
+ // - scroll that matching element into the user's viewport (in this case it's a heading within that accordion card)
9
+ //
10
+ // This JS will allow us to link to a specific area of content in a page where a traditional hash link wouldn't work
11
+ // In this case hash links won't work because the element with he matching ID is "stuck" in a closed accordion or tab.
12
+ //
13
+ const idRegex = /^id=/g; // Lets just cache these reused regex's here
14
+ const queryStartRegex = /^\?/g;
15
+ const endingSlashRegex = /\/$/g;
16
+
17
+ function processIdQuery(query, hash) {
18
+ let id = query.replace(idRegex, '');
19
+ const parentEl = document.querySelector(hash);
20
+ const heading = parentEl.querySelector(`#${id}`);
21
+
22
+ heading.scrollIntoView()
23
+ heading.focus();
24
+ }
25
+
26
+ function checkForQuery(query, hash) {
27
+ query.search(idRegex) !== -1 ?
28
+ processIdQuery(query, hash)
29
+ : null;
30
+ }
31
+
32
+ function checkForMatchingTabOrAccordion(hash) {
33
+ if ( document.querySelector(`.nav-tabs a[href="${hash}"]`) ) { // Looks for a matching BS4 tab element
34
+ let tab = $(`.nav-tabs a[href="${hash}"]`); // **SIGH**, BS4 requires JQuery
35
+
36
+ tab
37
+ .on('shown.bs.tab', () => { // Bootstrap 4 method for tab events // Must be defined before the tab is activated
38
+ window.location.search ?
39
+ checkForQuery(window.location.search.replace(queryStartRegex, ''), hash)
40
+ : null; })
41
+ .tab('show'); // Bootstrap 4 Tab method
42
+ } else if ( document.querySelector(`${hash}.collapse`) ) { // Looks for a matching BS4 collapse element
43
+ let card = $(hash); // **SIGH**, BS4 requires JQuery
44
+
45
+ card
46
+ .on('shown.bs.collapse', () => { // Bootstrap 4 Collapse method // Must be defined before the collapse is activated
47
+ window.location.search ?
48
+ checkForQuery(window.location.search.replace(queryStartRegex, ''), hash)
49
+ : null; })
50
+ .collapse('show'); // Bootstrap 4 Collapse method
51
+ const target = document.querySelector(hash);
52
+
53
+ target.scrollIntoView();
54
+ target.focus(); // For screen readers
55
+ }
56
+ }
57
+
58
+ function checkForHash(e) {
59
+ // Select the node that will be observed for mutations
60
+
61
+ if (window.location.hash) {
62
+ let hash = window.location.hash.replace(endingSlashRegex, '');
63
+
64
+ checkForMatchingTabOrAccordion(hash);
65
+ }
66
+ return;
67
+ }
68
+
69
+ function initTabs() {
70
+ checkForHash();
71
+ window.addEventListener('hashchange', checkForHash, false);
72
+ }
73
+
74
+ function makeTabsLinkable() {
75
+ if (!document.querySelector('#accordion') && !document.querySelector('.nav.nav-tabs'))
76
+ return;
77
+
78
+ initTabs();
79
+ }
80
+
81
+ export default makeTabsLinkable;