-
Notifications
You must be signed in to change notification settings - Fork 0
/
page-search_reserves.html
182 lines (172 loc) · 7.36 KB
/
page-search_reserves.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
<!--begin search/reserves
Last Modified: 2022-04-11 16:37:27
INSTRUCTIONS: Copy and paste the contents of this file into the “Embed Code”
section of the appropriate “Media / Widget” container for Course Reserves.
-->
<style>
#cl-cr h2 ~ *,
#cl-cr h3 ~ *,
#cl-cr h4 ~ * {
margin-left: 1rem;
}
#cl-cr h2,
#cl-cr h3,
#cl-cr h4 {
margin-top: 2rem;
}
#cl-cr h4 {
font-style: italic;
}
</style>
<div id="cl-cr"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-csv/1.0.21/jquery.csv.min.js" integrity="sha512-Y8iWYJDo6HiTo5xtml1g4QqHtl/PO1w+dmUpQfQSOTqKNsMhExfyPN2ncNAe9JuJUSKzwK/b6oaNPop4MXzkwg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
noReservesCsv = "https://docs.google.com/spreadsheets/d/1OSw7FlliVic4VJCJmTPpFvF6DagigXgnRTiaWN_zAmE/export?format=csv&id=1OSw7FlliVic4VJCJmTPpFvF6DagigXgnRTiaWN_zAmE&gid=0"
reservesCsv = "https://docs.google.com/spreadsheets/d/1TY5Mq8Yu2qHXjTKOJeAXGtKbsfMCv1F4P7kuOORqX-g/export?format=csv&id=1TY5Mq8Yu2qHXjTKOJeAXGtKbsfMCv1F4P7kuOORqX-g&gid=1559271636"
// https://gomakethings.com/waiting-for-multiple-all-api-responses-to-complete-with-the-vanilla-js-promise.all-method/
// With the Promise.all() method, we can pass in an array of promises. When all of them have resolved (or one fails), it will run our callback functions.
// When they’re all completed, Promise.all() passes along an array of promises to our first .then() callback.
// To get a text object from each one to pass on, we can use the Array.map() method to create a new array. We also need to wrap that in Promise.all(), since response.text() returns a promise as well.
// The data argument in our second then() callback is an array of CSV data, with each item matching the corresponding fetch call in the Promise.all() array. In this example, the item at index 0 is for `noReservesCsv`, and the item at index 1 is for `reservesCsv`.
Promise.all([
fetch(noReservesCsv),
fetch(reservesCsv)
]).then(function (responses) {
// get a text object from each of the responses
return Promise.all(responses.map(function (response) {
return response.text();
}));
}).then(function (data) {
// convert CSV strings to single array of objects
noReservesObjects = csvStringToObjects(data[0])
reservesObjects = csvStringToObjects(data[1])
allObjects = reservesObjects.concat(noReservesObjects)
// groupBy CourseNumber
var groupedCourses = groupBy2(allObjects, 'CourseNumber', 'Name')
// sort by the CourseNumber [https://stackoverflow.com/a/51725400]
var groupedCourses = Object.keys(groupedCourses).sort().reduce((a, c) => (a[c] = groupedCourses[c], a), {})
var courseReservesDiv = document.getElementById("cl-cr");
for (const course in groupedCourses) {
const courseDiv = document.createElement("div")
const courseH2 = document.createElement("h2")
const name = document.createTextNode(course)
courseH2.appendChild(name)
courseDiv.appendChild(courseH2)
const reqDiv = document.createElement("div")
const reqH3 = document.createElement("h3")
const reqText = document.createTextNode("Required for Student Purchase")
reqH3.appendChild(reqText)
reqDiv.appendChild(reqH3)
const optDiv = document.createElement("div")
const optH3 = document.createElement("h3")
const optText = document.createTextNode("Not Required for Student Purchase")
optH3.appendChild(optText)
optDiv.appendChild(optH3)
var titles = [];
groupedCourses[course].forEach(element => {
if (titles.includes(element.Title)) {
// skip duplicates
return;
}
else {
titles.push(element.Title);
}
if (element.ItemInfo3 == "Required for Student Purchase") {
itemDiv = createItemDiv(element)
itemDiv.className = "cl-cr-req"
reqDiv.appendChild(itemDiv)
}
else if (element.ItemInfo3 == "Not Required for Student Purchase") {
itemDiv = createItemDiv(element)
itemDiv.className = "cl-cr-opt"
optDiv.appendChild(itemDiv)
}
else if ("ItemInfo3" in element === false) {
const noneP = document.createElement("p")
const noneText = document.createTextNode("No course reserves this term.")
noneP.appendChild(noneText)
courseDiv.appendChild(noneP)
}
});
// if req or opt have items
if (reqDiv.querySelectorAll(".cl-cr-req").length > 0) {
courseDiv.appendChild(reqDiv)
}
if (optDiv.querySelectorAll(".cl-cr-opt").length > 0) {
courseDiv.appendChild(optDiv)
}
courseReservesDiv.appendChild(courseDiv)
}
}).catch(function (error) {
// if there’s an error, log it
console.log(error);
});
function csvStringToObjects(csvString) {
// 1) find the end of the header row
const endOfHeaders = csvString.indexOf("\r\n")
// 2) remove spaces from the header names
const headers = csvString.slice(0, endOfHeaders).split(" ").join("");
// 3) capture the values after the headers
const values = csvString.slice("\r\n".length + endOfHeaders);
// 4) recombine headers and values
const data = [headers, values].join('\n');
// 5) convert csv string to array of objects
const csvObjects = $.csv.toObjects(data)
return csvObjects
}
function groupBy2(objectArray, property1, property2) {
return objectArray.reduce(function (acc, obj) {
let key = obj[property1].trim() + ": " + obj[property2].trim()
if (!acc[key]) {
acc[key] = []
}
acc[key].push(obj)
return acc
}, {})
}
function createItemDiv(element) {
const itemDiv = document.createElement("div")
const itemH4 = document.createElement("h4")
const title = document.createTextNode(element["Title"])
itemH4.appendChild(title)
itemDiv.appendChild(itemH4)
if (element.ItemFormat == "BookChapter") {
const selectedChaptersDiv = document.createElement("div")
const selectedChapters = document.createTextNode("(Selected Chapters)")
selectedChaptersDiv.appendChild(selectedChapters)
itemDiv.appendChild(selectedChaptersDiv)
}
if (element.Author) {
const authorDiv = document.createElement("div")
const author = document.createTextNode(`Author: ${element.Author}`)
authorDiv.appendChild(author)
itemDiv.appendChild(authorDiv)
}
if (element.Publisher) {
const publisherDiv = document.createElement("div")
const publisher = document.createTextNode(`Publisher: ${element.Publisher}`)
publisherDiv.appendChild(publisher)
itemDiv.appendChild(publisherDiv)
}
if (element.Edition) {
const editionDiv = document.createElement("div")
const edition = document.createTextNode(`Edition: ${element.Edition}`)
editionDiv.appendChild(edition)
itemDiv.appendChild(editionDiv)
}
if (element.PubDate) {
const yearDiv = document.createElement("div")
const year = document.createTextNode(`Year: ${element.PubDate}`)
yearDiv.appendChild(year)
itemDiv.appendChild(yearDiv)
}
if (element.ISXN) {
const isxnDiv = document.createElement("div")
const isxn = document.createTextNode(`ISXN: ${element.ISXN}`)
isxnDiv.appendChild(isxn)
itemDiv.appendChild(isxnDiv)
}
return itemDiv
}
</script>
<!--end search/reserves-->