🏠 Home 

JAIN - LMS Attendance Helper

Simplify the process of taking the attendance in Jain University's LMS.


Install this script?
// ==UserScript==
// @name         JAIN - LMS Attendance Helper
// @namespace    https://greasyfork.org/en/users/781076-jery-js
// @version      2.0
// @description  Simplify the process of taking the attendance in Jain University's LMS.
// @author       Jery
// @license      MIT
// @match        https://lms.futurense.com/mod/attendance/take.php
// @icon         https://www.nicepng.com/png/detail/270-2701205_jain-heritage-a-cambridge-school-kondapur-jain-university.png
// @grant        GM_getValue
// @grant        GM_setValue
// ==/UserScript==
/**************************
* Notify new Update
***************************/
if (GM_getValue("version") != GM_info.script.version) {
GM_setValue("attendanceType", "modern");
GM_setValue("version", GM_info.script.version);
alert(`
JAIN - LMS Attendance Helper:\n\n
This scipt has been updated!!\n
Try out the new features soon!!\n\n
What's new:\n
-New 'Modern' attendance gui\n
-Bug Fixes`
);
}
/***************************************************************
* Add a start button to the page and use the
* button beside it as a reference for the styles.
***************************************************************/
let startButton = document.createElement("button");
startButton.innerHTML = "Start taking attendance";
startButton.type = "button";
startButton.className = "btn btn-start";
// Style the start button
startButton.style.position = "inherit";
startButton.style.color = "#fff";
startButton.style.backgroundColor = "#6c757d";
startButton.style.transition = "color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out";
// Add hover (mouse-in) effects to the start button
startButton.addEventListener("mouseenter", function () {
startButton.style.backgroundColor = "#5c636a";
startButton.style.borderColor = "#565e64";
});
// Add hover (mouse-out) effects to the start button
startButton.addEventListener("mouseleave", function () {
startButton.style.backgroundColor = "6c757d";
startButton.style.borderColor = "inherit";
});
// Append the start button to the right of the reference element
document.querySelector(".btn.btn-secondary").parentElement.appendChild(startButton);
// Add an event listener to the start button
startButton.addEventListener("click", function () {
attendance();
});
/***************************************************************
* Add a dropdown menu to the right of the 'take
* attendance' button for choosing attendance type.
***************************************************************/
let dropdown = document.createElement("select");
dropdown.id = "attendance-dropdown";
dropdown.title = "Choose preferred view for Attendance.\nClassic- Displays a dialog where you can type in USN.\nModern- Displays a GUI where you can mark the USNs.";
// Create the "Mark as Present" option and add it to the dropdown
let presentOption = document.createElement("option");
presentOption.value = "present";
presentOption.textContent = "Classic [Mark as Present]";
dropdown.appendChild(presentOption);
// Create the "Mark as Absent" option and add it to the dropdown
let absentOption = document.createElement("option");
absentOption.value = "absent";
absentOption.textContent = "Classic [Mark as Absent]";
dropdown.appendChild(absentOption);
// Create the "Use Modern" option and add it to the dropdown
let modernOption = document.createElement("option");
modernOption.value = "modern";
modernOption.textContent = "Modern [BETA]";
dropdown.appendChild(modernOption);
// Style the dropdown menu
dropdown.style.marginLeft = "5px";
// Append the dropdown to the right of the attendance button
document.querySelector(".btn.btn-start").parentElement.appendChild(dropdown);
// Set the attendance type to the last selected value
if (GM_getValue("attendanceType") == "present") dropdown.value = "present";
else if (GM_getValue("attendanceType") == "absent") dropdown.value = "absent";
else if (GM_getValue("attendanceType") == "modern") dropdown.value = "modern";
// Add an event listener to the dropdown
dropdown.addEventListener("change", function () {
if (dropdown.value == "present") GM_setValue("attendanceType", "present");
else if (dropdown.value == "absent") GM_setValue("attendanceType", "absent");
else if (dropdown.value == "modern") GM_setValue("attendanceType", "modern");
});
/***************************************************************
* Main Function to handle attendance.
* Shows a prompt for entering students USN number.
* First marks everyone (who isnt marked yet) as ABSENT
* and then marks the entered numbers as PRESENT.
***************************************************************/
function attendance() {
if (dropdown.value != "modern") {
// Set all (unmarked) students to PRESENT/ABSENT at start.
document.querySelector("td.cell.c4 [name='setallstatus-select']").value = "unselected";
if (dropdown.value == "present") document.querySelector("td.cell.c6 input[name='setallstatuses']").checked = true;
else if (dropdown.value == "absent") document.querySelector("td.cell.c5 input[name='setallstatuses']").checked = true;
// Initialize a variable to end loop
let stop = false;
// Not using a while loop here because the script works in a single thread,
// so it wont be able to reflect any changes until the while loop ends.
let loop = () => {
if (stop) return;
// Create a prompt to get USN of student
let usn = prompt("Enter the USN (or enter a non-numeric value to end)");
// Check whether the input is a number or else terminate.
if (isNaN(usn)) {
stop = true;
} else {
// remove whitespaces from USN and pad it with 0s to make it 3 digit
usn = usn.trim().toString().padStart(3, '0')
// Initialize the rows and cells
let rows = document.querySelectorAll("table tr");
for (let i = 3; i < rows.length; i++) {
let cells = rows[i].querySelectorAll("td");
if (cells.length > 0 && cells[3].textContent.endsWith(usn)) {
if (dropdown.value == "present") cells[6].querySelector("input").checked = true;        // Mark the cell (student) PRESENT
else if (dropdown.value == "absent") cells[7].querySelector("input").checked = true;    // Mark the cell (student) ABSENT
showToast("Marked USN " + usn + " as present.")     // Display success message
break;
}
else {
showToast("No student with USN " + usn + " found.") // Display error message
}
}
}
setTimeout(loop, 0);
};
loop();
}
else {
let colorPresent = "rgb(122, 255, 122)";
let colorAbsent = "rgb(253, 186, 47)";
let overlayDiv = document.createElement("div");
overlayDiv.style.cssText = "position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 999; display: flex; align-items: center; justify-content: center;";
document.body.appendChild(overlayDiv);
let formDiv = document.createElement("div");
formDiv.style.cssText = "position: relative; width: 80%; height: 70%; background-color: rgba(255, 255, 255, 0.8); border-radius: 10px; padding: 20px; overflow: auto; display: flex; flex-direction: column; align-items: center; justify-content: center; resize: both;";
overlayDiv.appendChild(formDiv);
let rows = Array.from(document.querySelectorAll("table tr")).slice(3);
let sortedUSNs = rows.map(row => row.querySelectorAll("td")[3].textContent).sort();
let list = document.createElement("ul");
list.style.cssText = "list-style-type: none; display: flex; padding: 20px; flex-wrap: wrap; justify-content: center;";
formDiv.appendChild(list);
sortedUSNs.forEach(usn => {
let listItem = document.createElement("li");
listItem.style.cssText = "width: 100px; height: 40px; margin: 5px; border-radius: 5px; display: flex; font-weight: bold; align-items: center; justify-content: center;";
listItem.textContent = usn;
let row = rows.find(row => row.querySelectorAll("td")[3].textContent === usn);
let presentRadio = row.querySelectorAll("input")[0];
let absentRadio = row.querySelectorAll("input")[1];
listItem.style.backgroundColor = presentRadio.checked ? colorPresent : colorAbsent;
listItem.addEventListener("click", function () {
listItem.style.backgroundColor = listItem.style.backgroundColor === colorPresent ? colorAbsent : colorPresent;
showToast(`Marked USN ${usn} as ${listItem.style.backgroundColor === colorPresent ? "present" : "absent"}.`);
presentRadio.checked = listItem.style.backgroundColor === colorPresent;
absentRadio.checked = listItem.style.backgroundColor === colorAbsent;
});
list.appendChild(listItem);
});
let closeButton = document.createElement("button");
closeButton.innerHTML = "Close";
closeButton.style.cssText = "position: sticky; bottom: 10px; align-self: end;";
closeButton.addEventListener("click", function () {
document.body.removeChild(overlayDiv);
});
formDiv.appendChild(closeButton);
}
}
/***************************************************************
* Display a simple toast message on the top right of the screen
***************************************************************/
function showToast(message) {
var x = document.createElement("div");
x.innerHTML = message;
x.style.color = "#000";
x.style.backgroundColor = "#fdba2f";
x.style.borderRadius = "10px";
x.style.padding = "10px";
x.style.position = "fixed";
x.style.top = "5px";
x.style.right = "5px";
x.style.fontSize = "large";
x.style.fontWeight = "bold";
x.style.zIndex = "10000";
x.style.display = "block";
x.style.borderColor = "#565e64";
x.style.transition = "right 2s ease-in-out";
document.body.appendChild(x);
setTimeout(function () {
x.style.right = "-1000px";
}, 2000);
setTimeout(function () {
x.style.display = "none";
document.body.removeChild(x);
}, 3000);
}