Skip to content

Commit bc239ad

Browse files
committed
Changes behavior of Filter checkboxes so each column allows 1 selection.
- For Expertise, Language, TargetDevice, only 1 option allowed; like radio buttons - Upon selection/deselection for Filter checkboxes, DOM state is reset ... - ...and reflects that last-checked checkbox, where app states auto-refreshes - Changes layout of Filter dropdown to remove empty space below it; add space after toolkit-cards - Adds home button in navbar, upper left, to improve user nav and ... - ... adds JS functions to manage and reload state when home clicked or filter reset clicked. - Fixes Defect #4, reported date 07/21/2023, assigned 10/3/2023 to michael vincerra, app developer Signed-off-by: michael vincerra <[email protected]>
1 parent 0f439d0 commit bc239ad

File tree

3 files changed

+216
-121
lines changed

3 files changed

+216
-121
lines changed

src/docs/_static/script.js

Lines changed: 134 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,62 @@
11
"use strict";
2+
23
const state = {
3-
data: [],
4-
search: [],
4+
data: [],
5+
search: [],
56
pageSize: 15,
67
totalPages: +Infinity,
78
pageIndex: 1,
89
paginatedData: [],
910
checkedFilters: [],
11+
checkBoxMap: {
12+
getStart: /.*getting\sstarted.*/ig,
13+
tutorial: /.*tutorial.*/ig,
14+
conFunc: /.*concepts\sand\sfunctionality.*/ig,
15+
refDesEnd2End: /.*reference\sdesigns\sand\send\sto\send.*/ig,
16+
codeOpt: /.*code\soptimization.*/ig,
17+
cpp: /.*cpp.*/ig,
18+
fortran: /.*fortran.*/ig,
19+
python: /.*python.*/ig,
20+
cpu: /.*cpu.*/ig,
21+
gpu: /.*gpu.*/ig,
22+
fpga: /.*fpga.*/ig
23+
}
1024
}
1125

12-
function reloadDocs() {
13-
const reload = new Event('DOMContentLoaded');
14-
document.dispatchEvent(reload)
15-
}
26+
HTMLElement.prototype.onEvent = function (eventType, callBack, useCapture) { // est eventListener for all HTML Objs.
27+
this.addEventListener(eventType, callBack, useCapture);
28+
if (!this.myListeners) {
29+
this.myListeners = []; // create empty arr to hold event type, callbacks, captures in DOM
30+
}
31+
this.myListeners.push({ eType: eventType, callBack: callBack }); // populate same arr
32+
return this;
33+
};
34+
35+
HTMLElement.prototype.removeListeners = function () {
36+
if (this.myListeners) { // If myListeners arr exists, run for loop over all eventListeners
37+
for (let i = 0; i < this.myListeners.length; i++) {
38+
this.removeEventListener(this.myListeners[i].eType, this.myListeners[i].callBack);
39+
}
40+
delete this.myListeners; // clear all eventListeners in arr before next func inits state
41+
}
42+
};
1643

1744
document.addEventListener('DOMContentLoaded', function () {
1845
console.log('document is ready.');
19-
fetchData().then((data) => { /* changed fr 'state' to 'data'*/
20-
renderUi(data.paginatedData); /* changed fr 'state' to 'data'*/
46+
fetchData().then((data) => {
47+
renderUi(data.paginatedData);
2148
showTotalRecords();
2249
attachSearch();
2350
filterPaginatedData();
24-
lastUpdated()
25-
});
26-
51+
lastUpdated();
52+
})
2753
});
2854

55+
2956
function reloadData() {
3057
const reload = new Event('DOMContentLoaded');
31-
document.dispatchEvent(reload)
58+
document.dispatchEvent(reload)
59+
console.log(reload)
3260
}
3361

3462
function lastUpdated() {
@@ -92,95 +120,110 @@ function lastPage() {
92120
renderUi(state.paginatedData);
93121
}
94122

123+
function resetFiltersGoHome(){
124+
destroyView();
125+
resetFilters();
126+
reloadData();
127+
}
128+
129+
// function closeCollapsibleFilters(){
130+
// //
131+
// }
132+
133+
95134
function resetFilters() {
96135
const checkboxes = document.querySelectorAll('input[name=data-filter]');
97136
console.log("NodeList:", checkboxes);
98137
checkboxes.forEach(c => {
99-
if(c.checked == true) {
138+
if (c.checked == true) {
100139
c.checked = false;
101140
const change = new Event('change');
102141
c.dispatchEvent(change);
103-
}else{
142+
} else {
104143
console.log(c.checked);
105144
}
106145
});
107-
};
146+
}
108147

109148
function resetSearcher() {
110149
const input = document.getElementById('textInput');
111-
input.value="";
150+
input.value = "";
112151
destroyView();
113152
resetFilters();
114153
reloadData();
115154
// input.focus();
116-
};
117-
155+
}
118156

119-
function showTotalRecords () {
157+
function showTotalRecords() {
120158
const records = document.getElementById("total-records");
121159
records.innerHTML = `Total Records: ${[...state.data].length}`;
122160
}
123161

124162
function renderUi(data) {
125-
const filtered = state.checkedFilters.length === 0 ? data: data.filter(item => {
163+
const filtered = state.checkedFilters.length === 0 ? data : data.filter(item => {
126164
const languages = item.languages.reduce((acc, value) => {
127165
const keys = Object.keys(value);
128166
return [...acc, ...keys];
129167
}, []);
130-
const filters = [...state.checkedFilters]
131-
const conditions = filters.map((regex) => {
132-
const condition = regex.test(item.expertise) ||
133-
regex.test(languages.join(',')) ||
134-
regex.test(item.targetDevice.join(','));
135-
return condition
136-
})
137-
return conditions.reduce((acc, condition) =>{
168+
const filters = [...state.checkedFilters]
169+
const conditions = filters.map((checkboxValue) => {
170+
const regex = state.checkBoxMap[checkboxValue]
171+
const condition = regex.test(item.expertise) ||
172+
regex.test(languages.join(',')) ||
173+
regex.test(item.targetDevice.join(','));
174+
175+
console.log(typeof (filters))
176+
console.log(filters)
177+
return condition
178+
})
179+
return conditions.reduce((acc, condition) => {
138180
return acc && condition
139-
}, true)
140-
181+
}, true)
182+
141183
})
142184
noResultsSwitch(filtered)
143185
qtyFilteredResults(filtered)
144186
renderCards(filtered)
145187
printPaginatorState()
146188
}
147189

148-
function qtyFilteredResults(filtered){
190+
function qtyFilteredResults(filtered) {
149191
const qtyResults = filtered.length;
150192
const dataTotalLength = [...state.data].length;
151-
console.log("Total len",dataTotalLength)
152-
const results = document.getElementById("qty-show-results") || {};
193+
console.log("Total len", dataTotalLength)
194+
const results = document.getElementById("qty-show-results") || {};
153195
results.innerHTML = `${qtyResults} Results`;
154-
if (qtyResults === undefined || qtyResults == 15 || qtyResults == dataTotalLength) {
155-
results.style.display="none";
196+
if (qtyResults === undefined || qtyResults == 15 || qtyResults == dataTotalLength) {
197+
results.style.display = "none";
156198
} else {
157-
results.style.display="block";
199+
results.style.display = "block";
158200
}
159201
}
160202

161203
function attachSearch() {
162204
const searchInput = document.querySelector("[data-search]")
163-
searchInput.addEventListener("input", e => {
205+
const handler = e => {
164206
const value = e.target.value.replace(/\+/g, "\\+")
165207
const regex = new RegExp('.*' + saniStrings(value) + '.*', 'ig');
166-
// const cleaned = noExtraSpc(regex) /*rm extra empty spcs in search string*/
167208
search(regex);
168-
})
169-
};
170-
171-
function noResultsSwitch(data){
209+
}
210+
searchInput.removeListeners()
211+
searchInput.onEvent("input", handler)
212+
}
213+
214+
function noResultsSwitch(data) {
172215
const noResults = document.getElementById("hide")
173-
if (data === undefined || data.length == 0) {
174-
noResults.style.display="block";
216+
if (data === undefined || data.length == 0) {
217+
noResults.style.display = "block";
175218
} else {
176-
noResults.style.display="none";
219+
noResults.style.display = "none";
177220
}
178221
}
179222

180223
function saniStrings(str) {
181224
/* remove reg/trademarks and all empty spaces */
182-
const reg_no_spcl = /[\u00ae\u2122\u2120\*]/g;
183-
const result = str.replace(reg_no_spcl, "");
225+
const regNoSpecial = /[\u00ae\u2122\u2120*]/g;
226+
const result = str.replace(regNoSpecial, "");
184227
return result.trim().replace(/\s+/g, " ");
185228
}
186229

@@ -191,12 +234,12 @@ function search(regex) {
191234
const keys = Object.keys(value);
192235
return [...acc, ...keys];
193236
}, []);
194-
let result =
195-
regex.test(saniStrings(item.name)) ||
196-
regex.test(saniStrings(item.description)) ||
197-
regex.test(languages.join(',')) ||
198-
regex.test(item.targetDevice.join(',')) ||
199-
regex.test(item.expertise);
237+
let result =
238+
regex.test(saniStrings(item.name)) ||
239+
regex.test(saniStrings(item.description)) ||
240+
regex.test(languages.join(',')) ||
241+
regex.test(item.targetDevice.join(',')) ||
242+
regex.test(item.expertise);
200243
return result
201244
});
202245
noResultsSwitch(data)
@@ -205,60 +248,79 @@ function search(regex) {
205248
state.paginatedData = [...data].slice(0, state.pageSize);
206249
destroyView();
207250
renderUi(data);
208-
209251
}
210252

211-
212-
function onlyAlphaNumInput(e){
253+
function onlyAlphaNumInput(e) {
213254
let regex1 = new RegExp("^[a-z-A-Z0-9\-\r|\n ]+|[\u00ae\u2122\u2120]+|[+]+$")
214255
let str = String.fromCharCode(!e.fromCharCode ? e.which : e.fromCharCode);
215256
saniStrings(str)
216257
const errormsg = document.getElementById("errormsg");
217-
if(regex1.test(str)) {
218-
errormsg.style.display="none";
258+
if (regex1.test(str)) {
259+
errormsg.style.display = "none";
219260
return true;
220-
} else{
221-
errormsg.innerHTML="Enter only letters, numbers, or plus sign.";
261+
} else {
262+
errormsg.innerHTML = "Enter only letters, numbers, or plus sign.";
222263
errormsg.classList.toggle("showerror");
223-
setTimeout(() =>{
264+
setTimeout(() => {
224265
errormsg.classList.remove("showerror");
225266
}, 7000);
226267
}
227-
e.preventDefault();
268+
e.preventDefault();
228269
}
229270

230-
function checkboxFilterHandler(checked,regex) {
271+
function checkboxFilterHandler(checked, checkboxValue) {
272+
// where checkboxValue is arr
231273
if (checked) {
232-
state.checkedFilters.push(regex)
274+
state.checkedFilters.push(checkboxValue)
275+
console.log("state.checkedFilters:",state.checkedFilters)
233276
} else {
234277
const found = state.checkedFilters.findIndex(item => {
235-
return item === regex
278+
return item === checkboxValue
236279
})
237-
if (typeof found !== 'undefined') {
280+
console.log("found?", found)
281+
if (found !== -1) {
238282
state.checkedFilters.splice(found, 1)
239283
}
240284
// console.log(`Checkbox not checked.`);
241285
}
242286
destroyView();
243-
if (state.checkedFilters.length > 0){
287+
if (state.checkedFilters.length >= 0) {
288+
// changed above from > 0 to > -1 // 25/10/2023
244289
state.pageIndex = 1;
245290
state.pageSize = +Infinity;
246291
state.totalPages = 1;
247292
renderUi([...state.data]);
248-
}else{
293+
} else {
294+
249295
reloadData();
250296
}
251297
}
252298

253299
function filterPaginatedData() {
254300
const checkboxes = document.querySelectorAll('input[name=data-filter]');
301+
console.log(checkboxes)
302+
255303
for (let checkbox of checkboxes) {
256-
checkbox.addEventListener('change', e => {
304+
const handler = e => {
257305
const checked = e.target.checked;
258-
const regex = new RegExp('.*' + e.target.value + '.*', 'ig');
259-
checkboxFilterHandler(checked, regex)
306+
// console.log("Checked is T/F?",checked)
307+
const checkedParent = e.target.parentElement.parentElement
308+
const checkBoxGroup = checkedParent.querySelectorAll('input[name=data-filter]')
309+
console.log("checkBoxGroup", checkBoxGroup)
310+
//
311+
checkBoxGroup.forEach(item => {
312+
313+
if (item.value !== e.target.value && item.checked == true) {
314+
item.checked = false
315+
const uncheckRegex = state.checkBoxMap[item.value]
316+
console.log("Unchecked regex...?", uncheckRegex)
317+
checkboxFilterHandler(item.checked, item.value)
318+
}
319+
})
320+
checkboxFilterHandler(checked, e.target.value)
260321
}
261-
)
322+
checkbox.removeListeners()
323+
checkbox.onEvent('change', handler)
262324
}
263325
}
264326

0 commit comments

Comments
 (0)