Last active
October 22, 2021 14:03
-
-
Save kishoreandra/a44e7579ea2e1dc0080935e92adae28c to your computer and use it in GitHub Desktop.
carousel code for ref
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const resultsDiv = document.querySelector("#results"); | |
const advisoryDetails = document.querySelector("#advisory-heading"); | |
const errModal = document.querySelector("#error-modal"); | |
const errModalTitle = document.querySelector(".modal-title"); | |
const errModalBody = document.querySelector(".modal-body"); | |
const logout = document.querySelector("#logout"); | |
const logoutForm = document.querySelector("#logout-form"); | |
const modalFooter = document.querySelector(".modal-footer"); | |
const modalCloseBtn = document.querySelector("#btn-close-modal"); | |
const cropDiagnosisSection = document.querySelector("#nav-to-cropdiagnosis"); | |
const startDatePicker = document.querySelector("#startDate"); | |
const endDatePicker = document.querySelector("#endDate"); | |
const filterCrop = document.querySelector("#filter-crop"); | |
const filterDuration = document.querySelector("#filter-duration"); | |
const customFilterOptions = document.querySelector("#custom-filter"); | |
const filterSearch = document.querySelector("#btn-filter"); | |
let confirmBtnCreated = false; | |
// set user details | |
const getAdvisory = JSON.parse(localStorage.getItem("user")); | |
const advisoryName = getAdvisory.user_name; | |
const advisoryId = getAdvisory.user_id; | |
const userRole = getAdvisory.role; | |
advisoryDetails.innerText = `Welcome - ${advisoryName}`; | |
// show advisory for admins | |
if (userRole !== "admin") { | |
cropDiagnosisSection.classList.add("d-none"); | |
} | |
// set max val to datepickers | |
startDatePicker.max = new Date().toISOString().slice(0, -14); | |
startDatePicker.valueAsNumber = | |
Date.now() - new Date().getTimezoneOffset() * 60000; | |
endDatePicker.max = new Date().toISOString().slice(0, -14); | |
endDatePicker.valueAsNumber = | |
Date.now() - new Date().getTimezoneOffset() * 60000; | |
// load picklist to dropdown | |
const loadPickList = () => | |
fetch("/api/picklist", { | |
method: "GET", | |
headers: { | |
"X-Api-Key": headerKey, | |
}, | |
}) | |
.then((response) => response.json()) | |
.then((result) => { | |
sessionStorage.setItem("storedPicklist", JSON.stringify(result.picklist)); | |
return result.picklist; | |
}) | |
.catch((err) => { | |
showErrorModal("Error occurred!", "Please try again"); | |
}); | |
async function attachPickList() { | |
if (sessionStorage.getItem("storedPicklist")) { | |
JSON.parse(sessionStorage.getItem("storedPicklist")); | |
} else { | |
await loadPickList(); | |
} | |
} | |
async function loadCarousel() { | |
await attachPickList(); | |
// filter select | |
attachPicklistFilter(); | |
await fetch("/api/advisory/unverified-predictions", { | |
method: "GET", | |
headers: { | |
"X-Api-Key": headerKey, | |
}, | |
}) | |
.then((response) => response.json()) | |
.then((result) => { | |
createCarouselCard(result, false); | |
}) | |
.catch((error) => { | |
showErrorModal("Error occurred!", "Please try again"); | |
}); | |
} | |
//load carousel at start | |
document.addEventListener("DOMContentLoaded", loadCarousel()); | |
// create carousel element | |
function createCarouselCard(result, isFiltered) { | |
let results = []; | |
results = result["unverified_predictions"]; | |
if (results.length === 0) { | |
let noResultsMsg = isFiltered | |
? "<h6>No predictions found to validate for the selected filter criteria</h6>" | |
: "<h6>No predictions found to validate at the moment</h6>"; | |
resultsDiv.innerHTML = noResultsMsg; | |
return; | |
} | |
resultsDiv.replaceChildren(); // clear previous results | |
results.forEach((pred, idx) => { | |
//carousel | |
const carouselItem = document.createElement("div"); | |
if (idx === 0) { | |
carouselItem.classList.add("carousel-item", "active"); | |
} | |
carouselItem.classList.add("carousel-item"); | |
//row below carousel | |
const row = document.createElement("div"); | |
row.classList.add("row"); | |
//column for rows | |
const column = document.createElement("div"); | |
column.classList.add("col-md-12", "mb-3"); | |
// card for each carousel inside column | |
const card = document.createElement("div"); | |
card.classList.add("card"); | |
card.id = idx; | |
card.setAttribute("data-mID", pred["_id"]); | |
// crop image inside cardDiv | |
const cropImage = document.createElement("img"); | |
cropImage.src = pred["image_path"]; | |
// card body for card | |
const cardBody = document.createElement("div"); | |
cardBody.classList.add("card-body", "ditls_blk"); | |
// card text (upload info) | |
const cardTextUploadedOn = document.createElement("p"); | |
cardTextUploadedOn.classList.add("card-text"); | |
cardTextUploadedOn.innerText = `Uploaded By: ${pred["user_name"]}`; | |
const cardTextUploadedBy = document.createElement("p"); | |
cardTextUploadedBy.classList.add("card-text"); | |
cardTextUploadedBy.innerText = `Uploaded On: ${new Date( | |
pred["uploaded_time"].toLocaleString(undefined, { | |
timeZone: "Asia/Kolkata", | |
}) | |
)}`; | |
// show predictions | |
const formGroup = document.createElement("div"); | |
formGroup.classList.add("form-group", "row", "chk_blk"); | |
const predLabel = document.createElement("div"); | |
predLabel.classList.add("col-lg-12"); | |
predLabel.innerText = "Top 3 predictions by model :"; | |
const dummy = document.createElement("div"); | |
dummy.classList.add("col-lg-12"); | |
formGroup.appendChild(predLabel); | |
formGroup.appendChild(dummy); | |
pred["prediction"].forEach((p, cid) => { | |
const formCheck = document.createElement("div"); | |
formCheck.classList.add("form-check"); | |
const input = document.createElement("input"); | |
input.classList.add("form-check-input"); | |
input.id = `id-${cid}`; | |
input.value = `${p["predicted_disease"]} - ${parseFloat( | |
p["confidence_percentage"] | |
).toFixed(2)} %`; | |
input.type = "checkbox"; | |
input.setAttribute("data-convention", p["predicted_disease"]); | |
if (cid === 0) { | |
input.classList.add("first-checkbox"); | |
} | |
const label = document.createElement("label"); | |
label.classList.add("form-check-label", "pest-dis-label"); | |
label.innerText = `${p["predicted_disease"]} - ${parseFloat( | |
p["confidence_percentage"] | |
).toFixed(2)} %`; | |
label.setAttribute("for", `id-${cid}`); | |
dummy.appendChild(formCheck); | |
formCheck.appendChild(input); | |
formCheck.appendChild(label); | |
}); | |
// yes / no options | |
const verifyRow = document.createElement("div"); | |
verifyRow.classList.add("row"); | |
const verifyLegend = document.createElement("legend"); | |
verifyLegend.classList.add( | |
"col-form-label", | |
"pt-0", | |
"radio_labl", | |
"col-md-6" | |
); | |
verifyLegend.innerText = "Valid Prediction?"; | |
const verifyDummy = document.createElement("div"); | |
verifyDummy.classList.add("radio_blk", "col-md-6"); | |
const verifyYesFormCheck = document.createElement("div"); | |
verifyYesFormCheck.classList.add("form-check"); | |
const verifyNoFormCheck = document.createElement("div"); | |
verifyNoFormCheck.classList.add("form-check"); | |
const verifyDiscardFormCheck = document.createElement("div"); | |
verifyDiscardFormCheck.classList.add("form-check"); | |
const yesInput = document.createElement("input"); | |
yesInput.classList.add("form-check-input", "verify-yes"); | |
yesInput.type = "radio"; | |
yesInput.name = "choosePred" + idx; | |
yesInput.value = "Yes"; | |
yesInput.checked = true; | |
const verifyYesLabel = document.createElement("label"); | |
verifyYesLabel.classList.add("form-check-label"); | |
verifyYesLabel.innerText = "Yes"; | |
const verifyNoLabel = document.createElement("label"); | |
verifyNoLabel.classList.add("form-check-label"); | |
verifyNoLabel.innerText = "No"; | |
const noInput = document.createElement("input"); | |
noInput.classList.add("form-check-input", "verify-no"); | |
noInput.type = "radio"; | |
noInput.name = "choosePred" + idx; | |
noInput.value = "No"; | |
const verifyDiscardLabel = document.createElement("label"); | |
verifyDiscardLabel.classList.add("form-check-label"); | |
verifyDiscardLabel.innerText = "Discard"; | |
const discardInput = document.createElement("input"); | |
discardInput.classList.add("form-check-input"); | |
discardInput.type = "radio"; | |
discardInput.name = "choosePred" + idx; | |
discardInput.value = "Discard"; | |
// yes no options end | |
// select // | |
const selectForm = document.createElement("div"); | |
selectForm.classList.add("form-group", "selectGroup", "d-none", "no_msage"); | |
// message | |
const message = document.createElement("p"); | |
message.innerText = `Thank you, You have selected the Prediction by Model is incorrect. | |
Please provide your feedback by selecting the "Crop" and "Pest/Disease" dropdown. Your feedback shall be used to retrain the model. This shall help the model to get better at prediction.`; | |
// message | |
const selectCropLabel = document.createElement("label"); | |
selectCropLabel.innerText = "Select Crop"; | |
const selectPestLabel = document.createElement("label"); | |
selectPestLabel.innerText = "Select Pest/Disease"; | |
//select for crop options | |
const selectCrop = document.createElement("select"); | |
selectCrop.classList.add("form-control", "crop-select"); | |
//select for pest options | |
const selectPest = document.createElement("select"); | |
selectPest.classList.add("form-control", "pest-select"); | |
const crop_names = JSON.parse(sessionStorage.getItem("storedPicklist")).map( | |
(crop) => crop.crop_name | |
); | |
crop_names.sort(function (a, b) { | |
let curr = a.toLowerCase(), | |
next = b.toLowerCase(); | |
if (curr < next) | |
//sort string ascending | |
return -1; | |
if (curr > next) return 1; | |
return 0; //default return value (no sorting) | |
}); | |
crop_names.push("Select"); | |
for (const crop of crop_names) { | |
const option = document.createElement("option"); | |
option.innerText = crop; | |
if (crop === "Select") { | |
option.selected = true; | |
option.disabled = true; | |
} | |
selectCrop.appendChild(option); | |
} | |
// select // | |
const multiSelectMsg = document.createElement("p"); | |
multiSelectMsg.classList.add("multiselect-msg"); | |
multiSelectMsg.innerText = `To select more than one pest/disease, For windows: Hold down the control (ctrl) button to select multiple options & For Mac: Hold down the command button to select multiple options`; | |
// text area // | |
const textareaLabel = document.createElement("label"); | |
textareaLabel.innerText = "Comments"; | |
const textarea = document.createElement("textarea"); | |
textarea.classList.add("form-control"); | |
textarea.rows = 3; | |
// text area // | |
//button// | |
const verifyBtn = document.createElement("btn"); | |
verifyBtn.classList.add("btn", "btn-primary", "verify-btn", "vrfy_btn"); | |
verifyBtn.innerText = "Submit"; | |
//button// | |
resultsDiv.appendChild(carouselItem); | |
carouselItem.appendChild(row); | |
row.appendChild(column); | |
column.appendChild(card); | |
card.appendChild(cropImage); | |
card.appendChild(cardBody); | |
cardBody.appendChild(cardTextUploadedBy); | |
cardBody.appendChild(cardTextUploadedOn); | |
cardBody.appendChild(formGroup); | |
cardBody.appendChild(verifyRow); | |
verifyRow.appendChild(verifyLegend); | |
verifyRow.appendChild(verifyDummy); | |
verifyDummy.appendChild(verifyYesFormCheck); | |
verifyDummy.appendChild(verifyNoFormCheck); | |
verifyDummy.appendChild(verifyDiscardFormCheck); | |
verifyYesFormCheck.appendChild(yesInput); | |
verifyYesFormCheck.appendChild(verifyYesLabel); | |
verifyNoFormCheck.appendChild(noInput); | |
verifyNoFormCheck.appendChild(verifyNoLabel); | |
verifyDiscardFormCheck.appendChild(discardInput); | |
verifyDiscardFormCheck.appendChild(verifyDiscardLabel); | |
cardBody.appendChild(selectForm); | |
selectForm.appendChild(message); | |
selectForm.appendChild(selectCropLabel); | |
selectForm.appendChild(selectCrop); | |
selectForm.appendChild(selectPestLabel); | |
selectForm.appendChild(selectPest); | |
selectForm.appendChild(multiSelectMsg); | |
selectForm.appendChild(textareaLabel); | |
selectForm.appendChild(textarea); | |
cardBody.appendChild(verifyBtn); | |
}); | |
[...document.querySelectorAll(".verify-yes")].forEach( | |
(radio) => (radio.checked = true) | |
); | |
[...document.querySelectorAll(".first-checkbox")].forEach( | |
(checkbox) => (checkbox.checked = true) | |
); | |
[...document.querySelectorAll(".crop-select")].forEach( | |
(sel) => (sel.value = "Select") | |
); | |
} | |
function removeFadeOut(el, speed) { | |
var seconds = speed / 1000; | |
el.style.transition = "opacity " + seconds + "s ease"; | |
el.style.opacity = 0; | |
setTimeout(function () { | |
el.parentNode.removeChild(el); | |
}, speed); | |
} | |
// toggle based on yes/no , and submit verifications | |
document.querySelector(".container").addEventListener("click", function (e) { | |
const tgt = e.target; | |
if (tgt.type && tgt.type === "radio") { | |
const hide = tgt.classList.contains("verify-no"); | |
[...tgt.closest(".card-body").querySelectorAll(".selectGroup")].forEach( | |
(par) => par.classList.toggle("d-none", !hide) | |
); | |
} else if (tgt.tagName && tgt.tagName === "BTN") { | |
// submit verifications | |
submitAdvisoryVerificationStatus(tgt); | |
} | |
}); | |
// on change crop select | |
document.querySelector(".container").addEventListener("change", function (e) { | |
const tgt = e.target; | |
if ( | |
tgt.type && | |
tgt.type === "select-one" && | |
tgt.classList.contains("crop-select") | |
) { | |
const picklistData = JSON.parse(sessionStorage.getItem("storedPicklist")); | |
const pestSelect = tgt.closest(".card-body").querySelector(".pest-select"); | |
pestSelect.multiple = true; | |
const selectedCrop = tgt.value; | |
let pestData = picklistData.reduce( | |
(acc, curr) => { | |
if (curr["crop_name"] === selectedCrop) { | |
acc["diseases_pests"] = [...curr["diseases"], ...curr["pests"]]; | |
} | |
return acc; | |
}, | |
{ diseases_pests: [] } | |
); | |
const pestsAndDiseases = pestData.diseases_pests.map((pest) => ({ | |
val: pest.value, | |
key: pest.key, | |
})); | |
pestsAndDiseases.sort(function (a, b) { | |
let curr = a.val.toLowerCase(), | |
next = b.val.toLowerCase(); | |
if (curr < next) | |
//sort string ascending | |
return -1; | |
if (curr > next) return 1; | |
return 0; //default return value (no sorting) | |
}); | |
pestsAndDiseases.push({ key: "Select", val: "Select" }); | |
pestSelect.innerHTML = ""; | |
for (const crop of pestsAndDiseases) { | |
const option = document.createElement("option"); | |
option.innerText = crop.val; | |
option.setAttribute("data-convention", crop.key); | |
if (crop.val === "Select") { | |
option.selected = true; | |
option.disabled = true; | |
} | |
pestSelect.appendChild(option); | |
} | |
} | |
}); | |
// logout | |
logout.addEventListener("click", (e) => { | |
e.preventDefault(); | |
if (!confirmBtnCreated) { | |
const confirmBtn = document.createElement("btn"); | |
confirmBtn.classList.add("btn", "btn-primary"); | |
confirmBtn.innerText = "Yes"; | |
confirmBtn.setAttribute("data-dismiss", "modal"); | |
modalFooter.insertBefore(confirmBtn, modalFooter.firstChild); | |
confirmBtn.addEventListener("click", () => { | |
localStorage.removeItem("user"); | |
sessionStorage.removeItem("storedPicklist"); | |
fetch("/user/signout") | |
.then((response) => response.json()) | |
.then((result) => { | |
logoutForm.submit(); | |
}) | |
.catch((error) => { | |
console.error("Error:", error); | |
}); | |
}); | |
confirmBtnCreated = true; | |
} | |
modalCloseBtn.innerText = "Cancel"; | |
errModalTitle.innerHTML = "Confirmation"; | |
errModalBody.innerHTML = "Are you sure you want to log out?"; | |
errModal.click(); | |
}); | |
// Error Modal | |
function showErrorModal(header, body) { | |
errModalBody.innerText = body; | |
errModalTitle.innerText = header; | |
errModal.click(); | |
} | |
// filter select | |
function attachPicklistFilter() { | |
const crop_list = JSON.parse(sessionStorage.getItem("storedPicklist")).map( | |
(crop) => crop.crop_name | |
); | |
crop_list.sort(function (a, b) { | |
let curr = a.toLowerCase(), | |
next = b.toLowerCase(); | |
if (curr < next) | |
//sort string ascending | |
return -1; | |
if (curr > next) return 1; | |
return 0; //default return value (no sorting) | |
}); | |
crop_list.unshift("All"); | |
filterCrop.innerHTML = ""; | |
for (const crop of crop_list) { | |
const option = document.createElement("option"); | |
option.innerText = crop; | |
if (crop === "All") { | |
option.selected = true; | |
option.value = "all"; | |
} | |
filterCrop.appendChild(option); | |
} | |
} | |
// toggle filter | |
filterDuration.addEventListener("change", (e) => { | |
e.target.value === "custom" | |
? customFilterOptions.classList.remove("d-none") | |
: customFilterOptions.classList.add("d-none"); | |
// reset dates after search | |
startDatePicker.valueAsNumber = | |
Date.now() - new Date().getTimezoneOffset() * 60000; | |
endDatePicker.valueAsNumber = | |
Date.now() - new Date().getTimezoneOffset() * 60000; | |
}); | |
// filter search | |
filterSearch.addEventListener("click", () => { | |
let filterCriteria = {}; | |
filterCriteria.crop = filterCrop.value === "all" ? "" : filterCrop.value; | |
filterCriteria.duration = | |
filterDuration.value === "all" ? "" : filterDuration.value; | |
if (filterCriteria.crop && filterCriteria.duration) { | |
filterCriteria.combined = true; | |
filterCriteria.duration_type = | |
filterCriteria.duration === "custom" ? "custom" : "particular"; | |
filterCriteria.filter_search = true; | |
} else { | |
filterCriteria.combined = false; | |
if (filterCriteria.crop || filterCriteria.duration) { | |
filterCriteria.duration_type = | |
filterCriteria.duration === "custom" ? "custom" : "particular"; | |
filterCriteria.filter_search = true; | |
} else { | |
filterCriteria.duration_type = | |
filterCriteria.duration === "custom" ? "custom" : "particular"; | |
filterCriteria.filter_search = false; | |
} | |
} | |
if (filterCriteria.duration_type === "custom") { | |
filterCriteria.start_date = startDatePicker.value; | |
filterCriteria.end_date = endDatePicker.value; | |
filterCriteria.duration = ""; | |
} else { | |
filterCriteria.start_date = startDatePicker.value; | |
filterCriteria.end_date = endDatePicker.value; | |
filterCriteria.duration; | |
} | |
const fdate = new Date(startDatePicker.value); | |
const tdate = new Date(endDatePicker.value); | |
if (fdate.valueOf() > tdate.valueOf()) { | |
showErrorModal( | |
"Selection Error", | |
"Start date must be lesser than End date" | |
); | |
return; | |
} | |
filterSearchCall(filterCriteria); | |
// // reset dates after search | |
// startDatePicker.valueAsNumber = | |
// Date.now() - new Date().getTimezoneOffset() * 60000; | |
// endDatePicker.valueAsNumber = | |
// Date.now() - new Date().getTimezoneOffset() * 60000; | |
}); | |
//filter api call | |
async function filterSearchCall(criteria) { | |
await fetch("/api/advisory/unverified-predictions/filterby", { | |
method: "POST", | |
headers: { | |
"Content-Type": "application/json", | |
"X-Api-Key": headerKey, | |
}, | |
body: JSON.stringify(criteria), | |
}) | |
.then((response) => response.json()) | |
.then((result) => { | |
createCarouselCard(result, true); | |
}) | |
.catch((error) => { | |
showErrorModal("Error occurred!", "Please try again"); | |
}); | |
} | |
// submit adv verf status | |
function submitAdvisoryVerificationStatus(target) { | |
const verifyBtn = target.closest(".card-body").querySelector(".verify-btn"); | |
const cardDiv = verifyBtn.closest(".card"); | |
const carouselDiv = verifyBtn.closest(".carousel-item"); | |
const imagePath = cardDiv.querySelector("img").src; | |
const advisoryComments = cardDiv.querySelector("textarea").value; | |
const advName = advisoryName; | |
const mId = cardDiv.getAttribute("data-mID"); | |
const isCorrectPrediction = cardDiv.querySelector( | |
"input[type='radio']:checked" | |
).value; | |
let validPredictions = []; | |
let verifiedConventionalDiseaseOrPest = []; | |
const checkboxes = cardDiv.querySelectorAll("input[type=checkbox]:checked"); | |
for (let i = 0; i < checkboxes.length; i++) { | |
validPredictions.push(checkboxes[i].value); | |
if (isCorrectPrediction === "Yes") { | |
verifiedConventionalDiseaseOrPest.push( | |
checkboxes[i].getAttribute("data-convention") | |
); | |
} | |
} | |
let selectedCrop = ""; | |
let selectedDiseaseOrPest = ""; | |
let conventionalDiseaseOrPest = []; | |
if (isCorrectPrediction === "No") { | |
selectedCrop = cardDiv.querySelector(".crop-select").value; | |
if (selectedCrop === "Select") { | |
showErrorModal("Mandatory field error", "Please select a crop"); | |
return; | |
} | |
selectedDiseaseOrPest = cardDiv.querySelector(".pest-select").value; | |
if (selectedDiseaseOrPest === "Select") { | |
showErrorModal( | |
"Mandatory field error", | |
"Please select a pest or disease" | |
); | |
return; | |
} | |
const selectedPestDisease = cardDiv.querySelector(".pest-select"); | |
conventionalDiseaseOrPest = Array.from(selectedPestDisease.options) | |
.filter((o) => o.selected) | |
.map((o) => o.getAttribute("data-convention")); | |
} | |
const data = { | |
_id: mId, | |
advisory_comments: advisoryComments, | |
advisory_name: advName, | |
image_path: imagePath, | |
is_advisory_verified: true, | |
advisory_verified_predictions: validPredictions, | |
is_correct_prediction: isCorrectPrediction, | |
verified_crop: selectedCrop, | |
verified_pest_or_disease: selectedDiseaseOrPest, | |
conventional_pest_or_disease: conventionalDiseaseOrPest, | |
model_conventional_disease_or_pest: verifiedConventionalDiseaseOrPest, | |
}; | |
fetch("/api/advisory/update/unverified-predictions", { | |
method: "POST", | |
headers: { | |
"Content-Type": "application/json", | |
"X-Api-Key": headerKey, | |
}, | |
body: JSON.stringify(data), | |
}) | |
.then((response) => response.json()) | |
.then((result) => { | |
removeFadeOut(carouselDiv, 1000); | |
setTimeout(() => { | |
loadCarousel(); | |
}, 1500); | |
}) | |
.catch((error) => { | |
showErrorModal("Error occurred!", "Please try again"); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment