-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbirds.js
268 lines (227 loc) · 8.77 KB
/
birds.js
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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
/*
* Declaring variables
*/
const birdDataUrl = "./data/nzbird.json";
const container = document.getElementById('flex-container');
const numBirds = document.getElementById('results');
let birdArr = [];
const statusArr = new Array(
"Not Threatened",
"Naturally Uncommon",
"Relict",
"Recovering",
"Declining",
"Nationally Increasing",
"Nationally Vulnerable",
"Nationally Endangered",
"Nationally Critical",
"Data Deficient"
);
/**
* Fetching data
*/
async function fetchData() {
const response = await fetch(birdDataUrl);
// in the case that we are not able to fetch the data we need to handel the error
if (!response.ok) {
console.error(response.status);
const errorMessage = document.createElement('p');
errorMessage.setAttribute('class', 'error');
errorMessage.textContent = "ERROR: unable to load birds from server.";
container.append(errorMessage);
}
const birdData = await response.json();
// for loop to go through and create a panel for each bird
for (let j = 0; j < birdData.length; j++) {
birdPanel(birdData[j]);
}
}
// birdPanel function to go through and create pandels for each bird using the data
function birdPanel(bird) {
const birdNum = bird.scientific_name.replaceAll(" ", ""); // getting rid of the spaces
// panel for each bird
const panel = `<div class="panel" id = "${birdNum}">
<img src=${bird.photo.source} alt="Photo of ${bird.english_name}" class="bird-imag">
<div class="overlay">
<div class="circle" style="background-color:var(--${bird.status.replaceAll(' ', '-')})";> </div>
</div>
<h2 class="maori-name" id = "maori-name">${bird.primary_name}</h2>
<p class="photographer">Photo by ${bird.photo.credit}</p>
<h2 class = "english-name" id = "english-name">${bird.english_name}</h2>
<div class="eachPanel">
<p class="panel-text" id = panel-id >Scientific Name</p> <p>${bird.scientific_name}</p>
<p class="panel-text" id = panel-id>Family</p> <p>${bird.family} </p>
<p class="panel-text" id = panel-id>Order</p> <p>${bird.order} </p>
<p class="panel-text" id = panel-id>Status</p> <p>${bird.status} </p>
<p class="panel-text" id = panel-id>Length</p> <p>${bird.size.length.value + ' ' + bird.size.length.units} </p>
<p class="panel-text" id = panel-id>Weight</p> <p>${bird.size.weight.value + ' ' + bird.size.weight.units} </p>
</div>
<div class="button-container">
<a class="ved-button" id = view href="/birds/${birdNum}">View</a><br>
<a class="ved-button" id = edit href="/birds/${birdNum}/Edit">Edit</a><br>
<a class="ved-button" id = delete href="/birds/${birdNum}/Delete">Delete</a>
</div>
</div>`;
// adding the panel into the container
container.insertAdjacentHTML("beforeend", panel);
bird.element = document.getElementById(birdNum);
birdArr.push(bird);
}
/**
* matching the name with the search word function
*/
function match(searchWord, bird) {
const englishName = bird.english_name.toLowerCase();
const maoriName = bird.primary_name.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase(); // normalised so maori words can be found
const scientificName = bird.scientific_name.toLowerCase();
//need to return true if any of the maori name or english names or scientific names are contain search word
if (englishName.includes(searchWord) || maoriName.includes(searchWord) || scientificName.includes(searchWord)) {
return true;
} else {
return false;
}
}
/**
* Function to add birds to container that match search terms
* also should checks if the serach term is valid
*/
function addBirds(currentBirds) {
// need to start off with nothing in the innerHMTL and then we need to append
container.innerHTML = "";
currentBirds.forEach(bird => {
container.append(bird.element);
});
// changing the birds found to the number that we get from currentBirds that meet the citeria
numBirds.textContent = currentBirds.length + " results found.";
// if we can't find the search term then this error message should show up
if (currentBirds.length === 0) {
const errorMessage = document.createElement('h1');
errorMessage.textContent = "There are no birds that match the search term!";
container.append(errorMessage);
}
}
/**
* sort-by functions
* will need to compare x to y for each characterstic
*/
// simple comparator function
function createComparator(key, reverse = false) {
return (x, y) => {
const a = x[key];
const b = y[key];
// if the keys are in reverse
if (reverse) {
return a < b ? 1 : (a > b ? -1 : 0);
}
return a < b ? -1 : (a > b ? 1 : 0);
};
}
//creating a nested comparator
function createComparatorNested(key1, key2, reverse = false) {
return (x, y) => {
const a = x[key1][key2].value;
const b = y[key1][key2].value;
if (reverse) {
return a < b ? 1 : (a > b ? -1 : 0);
}
return a < b ? -1 : (a > b ? 1 : 0);
};
}
// matching up using createComparatorfunctions
const alphabeticalEnglish = createComparator('english_name');
const alphabeticalMaori = createComparator('primary_name');
const lightestToHeaviest = createComparatorNested('size', 'weight');
const heaviestToLightest = createComparatorNested('size', 'weight', true);
const shortestToLongest = createComparatorNested('size', 'length');
const longestToShortest = createComparatorNested('size', 'length', true);
// when teh filter button is pressed
document.getElementById("filter-button").addEventListener('click', function () {
const searchTerm = document.querySelector("#search-bar").value;
let currentBirdsArr = birdArr.slice();
// if search filter is nothing
if (searchTerm === "") {
currentBirdsArr = birdArr.slice();
} else {
// else there is something in the search query and we want to create and array of birds to hold the birds
currentBirdsArr = [];
let query = searchTerm.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase();
birdArr.forEach(bird => {
// if the name matches then we want to push the specific bird onto the currentBirdArray
if (match(query, bird)) {
currentBirdsArr.push(bird);
}
});
}
// conservation status checker
const conservStatus = document.querySelector("#status-sort").selectedIndex;
if (conservStatus > 0) {
const selectedStatus = statusArr[conservStatus - 1];
currentBirdsArr = currentBirdsArr.filter(bird => bird.status === selectedStatus);
}
// array of sorting functions
const sortingFunctions = [
alphabeticalEnglish,
alphabeticalMaori,
lightestToHeaviest,
heaviestToLightest,
shortestToLongest,
longestToShortest
];
//getting the idvalue via index
const idValue = document.querySelector("#by-sort").selectedIndex;
// makes sure that the selected index is legitimate and sorts using the corresponding function
if (idValue >= 0 && idValue < sortingFunctions.length) {
currentBirdsArr.sort(sortingFunctions[idValue]);
}
// finally we are adding the current bird
addBirds(currentBirdsArr);
});
// function to show birds that are of the same type in terms of conservation status using circles
document.addEventListener("DOMContentLoaded", function () {
const statusContainers = document.querySelectorAll('.status-container');
statusContainers.forEach((container, index) => {
container.addEventListener('click', function () {
filterBirdsByStatus(index);
});
});
});
function filterBirdsByStatus(statusIndex) {
// gets the corresponding status from the statusArr using index
const status = statusArr[statusIndex];
const currentBirdsArr = birdArr.filter(bird => bird.status === status);
// updating the container with the filtered birds
addBirds(currentBirdsArr);
}
// call to the fetchData func
fetchData()
/*
* Darkmode function
*/
let darkMode = localStorage.getItem('darkMode');
const darkModeToggle = document.querySelector('#dark-mode-toggle');
const enableDarkMode = () => {
// adding the class to the body and updating local storage
document.body.classList.add('darkmode');
localStorage.setItem('darkMode', 'enabled');
}
// disable dark mode function
const disableDarkMode = () => {
// removing the class from the body and updating the darkmode in local storage
document.body.classList.remove('darkmode');
localStorage.setItem('darkMode', null);
}
//if the user left on darkmode then they should start on darkmode
if (darkMode === 'enabled') {
enableDarkMode();
}
// eventListener for the darkmode button
darkModeToggle.addEventListener('click', () => {
//getting the stored settings
darkMode = localStorage.getItem('darkMode');
if (darkMode !== 'enabled') {
enableDarkMode();
// if enabled, we turn it off
} else {
disableDarkMode();
}
});