From 3cbe1cbf008d26bdee00dd66f6c02a83f79ffb95 Mon Sep 17 00:00:00 2001 From: Sam sunder Date: Sun, 4 Jun 2023 14:31:02 +0000 Subject: [PATCH] Added detailed documentation to JS functions and fixed a mistake while loading css from cookie. --- public/static/settings.js | 266 ++++++++++++++++++++++------------- public/templates/header.html | 4 +- 2 files changed, 170 insertions(+), 100 deletions(-) diff --git a/public/static/settings.js b/public/static/settings.js index 0c8c0f1..87c4f58 100644 --- a/public/static/settings.js +++ b/public/static/settings.js @@ -1,116 +1,186 @@ -// UI: Method for selecting all search engines +/* + UI: Method for selecting all search engines + + This function is called when user click on + `select all` and `deselect all` toogle element. + + - If select all is pressed toggle all options and insert all value + joined with comma to input which is saved in cookie. + then changes text to `deselect all`. + eg value: 'ddg,searx,' + + - If deselect all is pressed uncheck all options and insert empty + value to input which is saved in cookie. +*/ function selectAllHandler(elem) { - let span = elem.parentElement.querySelector('span'); - let mainInput = document.getElementsByName('searchEng')[0]; - let prevStateSelectAll = span.innerText == 'Select all' ? true : false; - document.querySelectorAll('.searchEng-elem').forEach(engine => { - if (prevStateSelectAll) { - engine.querySelector('input[type="checkbox"]').checked = true; - } else { - engine.querySelector('input[type="checkbox"]').checked = false; - } - }) + let span = elem.parentElement.querySelector("span"); + let mainInput = document.getElementsByName("searchEng")[0]; + let prevStateSelectAll = span.innerText == "Select all" ? true : false; + document.querySelectorAll(".searchEng-elem").forEach((engine) => { if (prevStateSelectAll) { - let getValues = () => { - let value = "" - document.querySelectorAll('[data-isCheckbox]:not([data-value="all"])').forEach(elem => { - value += elem.getAttribute("data-value") + ","; - }); - return value; - } - mainInput.value = getValues(); + engine.querySelector('input[type="checkbox"]').checked = true; } else { - mainInput.value = ''; + engine.querySelector('input[type="checkbox"]').checked = false; } - span.innerText = prevStateSelectAll ? 'Deselect all' : 'Select all'; + }); + if (prevStateSelectAll) { + let getValues = () => { + let value = ""; + document + .querySelectorAll('[data-isCheckbox]:not([data-value="all"])') + .forEach((elem) => { + value += elem.getAttribute("data-value") + ","; + }); + return value; + }; + mainInput.value = getValues(); + } else { + mainInput.value = ""; + } + span.innerText = prevStateSelectAll ? "Deselect all" : "Select all"; } +/* + UI: Filter settings as per category + + There are two elements one is `category` and `detail`. + Category contains `data-id` when a user click it + we need to show detail element having + `data-detailId` whose value is same as `data-id`. + + When a user clicks on a category on sidebar, view + settings containing `data-id` of sidebar element's `data-detailId` + and hide other settings -// UI: Filter settings as per category -document.querySelectorAll('.settings-sidebar .set-name').forEach(filter => { - let target = filter.getAttribute('data-detailId'); - filter.addEventListener('click', () => { - try {document.querySelector('.set-name.active').classList.remove('active');} catch(e){} - filter.classList.add('active'); - if (target == 'all') { - document.querySelectorAll('.set-item').forEach((elem) => { - elem.style.display = 'block'; - }) - return; - } - document.querySelectorAll('.set-item[data-id="'+target+'"]').forEach((elem) => { - elem.style.display = 'block' - }) - document.querySelectorAll('.set-item:not([data-id="'+target+'"])').forEach((elem) => { - elem.style.display = 'none' - }) - }) -}) + - if `all` is clicked then show all settings. +*/ +document.querySelectorAll(".settings-sidebar .set-name").forEach((filter) => { + let target = filter.getAttribute("data-detailId"); + filter.addEventListener("click", () => { + try { + document.querySelector(".set-name.active").classList.remove("active"); + } catch (e) {} + filter.classList.add("active"); + if (target == "all") { + document.querySelectorAll(".set-item").forEach((elem) => { + elem.style.display = "block"; + }); + return; + } + document + .querySelectorAll('.set-item[data-id="' + target + '"]') + .forEach((elem) => { + elem.style.display = "block"; + }); + document + .querySelectorAll('.set-item:not([data-id="' + target + '"])') + .forEach((elem) => { + elem.style.display = "none"; + }); + }); +}); -// On settings form submit +/* + This function is called when a user click on submit button + it validates all user inputs and saves to a cookie. + + - if input having `required` attr and is empty it generates a + error text and insert above the setting element + + - else store setttings to a cookie. +*/ function submitSettings() { - let form = document.settings; - let stopProceeding = false; - document.querySelectorAll('.errTxt').forEach(e => e.remove()); - for(let i = 0; i < form.elements.length; i++) { - let input = form.elements[i]; - if (input.value == "" && input.hasAttribute('required')) { - stopProceeding = true; - let elem = input.parentElement.querySelector('[takeInput]') - let errTxt = document.createElement('p') - errTxt.classList.add('errTxt') - errTxt.innerText = 'This setting can\'t be empty!!' - elem.classList.add('invalid'); - elem.parentElement.insertBefore(errTxt, elem); - let sidebarElement = input.closest('.set-item').getAttribute('data-id') - document.querySelector(`.settings-sidebar .set-name[data-detailId="${sidebarElement}`).click(); - stopProceeding = true; - } + let form = document.settings; + let stopProceeding = false; + document.querySelectorAll(".errTxt").forEach((e) => e.remove()); + for (let i = 0; i < form.elements.length; i++) { + let input = form.elements[i]; + if (input.value == "" && input.hasAttribute("required")) { + stopProceeding = true; + let elem = input.parentElement.querySelector("[takeInput]"); + let errTxt = document.createElement("p"); + errTxt.classList.add("errTxt"); + errTxt.innerText = "This setting can't be empty!!"; + elem.classList.add("invalid"); + elem.parentElement.insertBefore(errTxt, elem); + let sidebarElement = input.closest(".set-item").getAttribute("data-id"); + document + .querySelector( + `.settings-sidebar .set-name[data-detailId="${sidebarElement}` + ) + .click(); + stopProceeding = true; } - if (!stopProceeding) { - var expiration_date = new Date(); - expiration_date.setFullYear(expiration_date.getFullYear() + 1); - let formData = new FormData(document.querySelector('form')); - for (var [key, value] of formData.entries()) { - document.cookie = `${key}=${value}; expires=${expiration_date.toUTCString()}` - } - } else { return false; } - // On settings saved successfully - alert("Settings saved succssfully!"); - window.location.reload(); + } + if (!stopProceeding) { + var expiration_date = new Date(); + expiration_date.setFullYear(expiration_date.getFullYear() + 1); + let formData = new FormData(document.querySelector("form")); + for (var [key, value] of formData.entries()) { + document.cookie = `${key}=${value}; expires=${expiration_date.toUTCString()}`; + } + } else { + return false; + } + // On settings saved successfully + alert("Settings saved succssfully!"); + window.location.reload(); } -// Autoload existing settings + +/* + This function will be called on page ready. + it iterates over saved cookies and if cookie name is + in the list of valid cookies then load it. + + - if cookie is searchEng(type=toggle/checkbox) we deselect + all checkboxes and select those which are stored in cookie. + + - if cookie is of type `select` we deselect default selected + option and then select option which is stored in cookie. +*/ function loadUserSettings() { - let inputs = ["searchEng", "theme", "color-sch"] - var keyValuePairs = document.cookie.split(';'); - for(var i = 0; i < keyValuePairs.length; i++) { - var name = keyValuePairs[i].substring(0, keyValuePairs[i].indexOf('=')); - var value = keyValuePairs[i].substring(keyValuePairs[i].indexOf('=')+1); - name = name.trim(); - if (!inputs.includes(name)) { return; } - let input = document.getElementsByName(name)[0]; - input.value = value; - if (name == "searchEng") { - // Unload all checked engine - document.querySelectorAll(".searchEng-elem input[type=checkbox]").forEach(e => { - e.checked = false; - }) - value = value.replace(" ", ""); - value.split(",").forEach(val => { - if (!val) {return} - document.querySelector(`[data-isCheckbox][data-value="${val}"]`). - parentElement.querySelector('input').checked = true - }) - } else { - // Unload all selected options - document.querySelector(`[data-input="${name}"] .options span[data-value="${value}"]`). - removeAttribute('selected'); - singleSelectClickHandler(document.querySelector(`.options span[data-value="${value}"]`)); - } + let inputs = ["searchEng", "theme", "color-sch"]; + var keyValuePairs = document.cookie.split(";"); + for (var i = 0; i < keyValuePairs.length; i++) { + var name = keyValuePairs[i].substring(0, keyValuePairs[i].indexOf("=")); + var value = keyValuePairs[i].substring(keyValuePairs[i].indexOf("=") + 1); + name = name.trim(); + if (!inputs.includes(name)) { + continue; } - + let input = document.getElementsByName(name)[0]; + input.value = value; + if (name == "searchEng") { + // Unload all checked engines + document + .querySelectorAll(".searchEng-elem input[type=checkbox]") + .forEach((e) => { + e.checked = false; + }); + value = value.replace(" ", ""); + value.split(",").forEach((val) => { + if (!val) { + return; + } + document + .querySelector(`[data-isCheckbox][data-value="${val}"]`) + .parentElement.querySelector("input").checked = true; + }); + } else { + // Unload all selected options + document + .querySelector( + `[data-input="${name}"] .options span[data-value="${value}"]` + ) + .removeAttribute("selected"); + singleSelectClickHandler( + document.querySelector(`.options span[data-value="${value}"]`) + ); + } + } } +// Code where settings are loaded from cookie. loadUserSettings(); diff --git a/public/templates/header.html b/public/templates/header.html index 7ee22ce..7e9ac8c 100644 --- a/public/templates/header.html +++ b/public/templates/header.html @@ -24,6 +24,6 @@ head.appendChild(link); } - addCss('static/themes/'+ (cookies["theme"] || {{theme}}) + '.css'); - addCss('static/colorschemes/'+ (cookies["color-sch"] || {{colorscheme}}) + '.css'); + addCss('static/themes/'+ (cookies["theme"] || '{{theme}}') + '.css'); + addCss('static/colorschemes/'+ (cookies["color-sch"] || '{{colorscheme}}') + '.css');