Kumi
33f55824d8
Enhanced global.js and script.js to conditionally load jQuery and Bootstrap only if they are not already present. This change improves loading efficiency and reduces redundant script execution. Additionally, fixed a bug in renderer.php by removing duplicate Bootstrap loading, which also reduces external dependency. A new .gitignore file was added to ignore backup files with a .bak extension, helping to keep the repository clean. Ensured error logging only displays error messages for better clarity.
206 lines
No EOL
7.4 KiB
JavaScript
206 lines
No EOL
7.4 KiB
JavaScript
document.addEventListener("DOMContentLoaded", function () {
|
|
// Function to load a script into the DOM
|
|
function loadScript(url, integrity, crossorigin) {
|
|
return new Promise((resolve, reject) => {
|
|
const script = document.createElement("script");
|
|
script.src = url;
|
|
script.integrity = integrity;
|
|
script.crossOrigin = crossorigin;
|
|
script.onload = () => resolve(script);
|
|
script.onerror = () => reject(new Error(`Failed to load script: ${url}`));
|
|
document.head.appendChild(script);
|
|
});
|
|
}
|
|
|
|
// Function to get URL parameters
|
|
function getUrlParameter(name) {
|
|
const url = document.location.href;
|
|
const urlobj = new URL(url);
|
|
return urlobj.searchParams.get(name);
|
|
}
|
|
|
|
// Function to wait until a global variable is defined
|
|
function waitForGlobalVariable(variableName) {
|
|
return new Promise((resolve) => {
|
|
const checkVariable = setInterval(() => {
|
|
if (window[variableName]) {
|
|
clearInterval(checkVariable);
|
|
resolve();
|
|
}
|
|
}, 100);
|
|
});
|
|
}
|
|
|
|
// Check if the 'embed' parameter is set to '1'
|
|
if (getUrlParameter("embed") === "1") {
|
|
// Apply custom CSS to hide Moodle interface elements
|
|
const style = document.createElement("style");
|
|
style.innerHTML = `
|
|
body.path-mod {
|
|
#header, #footer, .breadcrumb, .navbar, .side-pre, .side-post, .drawer, .drawer-toggler, .footer-popover, .navigation {
|
|
display: none !important;
|
|
}
|
|
#region-main {
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
}
|
|
`;
|
|
document.head.appendChild(style);
|
|
|
|
// Load jQuery if not already defined
|
|
const jQueryPromise = window.jQuery
|
|
? Promise.resolve()
|
|
: loadScript(
|
|
"https://code.jquery.com/jquery-3.7.1.min.js",
|
|
"sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=",
|
|
"anonymous"
|
|
).then(() => waitForGlobalVariable("$"));
|
|
|
|
jQueryPromise
|
|
.then(() => {
|
|
console.log("jQuery loaded successfully");
|
|
|
|
// Load Bootstrap if not already defined
|
|
const bootstrapPromise = window.bootstrap
|
|
? Promise.resolve()
|
|
: loadScript(
|
|
"https://stackpath.bootstrapcdn.com/bootstrap/5.3.3/js/bootstrap.bundle.min.js",
|
|
"sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz",
|
|
"anonymous"
|
|
).then(() => waitForGlobalVariable("bootstrap"));
|
|
|
|
return bootstrapPromise;
|
|
})
|
|
.then(() => {
|
|
console.log("Bootstrap loaded successfully");
|
|
|
|
$(document).ready(function () {
|
|
$(".btn-secondary:contains('Back')").hide();
|
|
|
|
const embedded = getUrlParameter("embed");
|
|
const inModal = getUrlParameter("modal");
|
|
const page = getUrlParameter("page") ? getUrlParameter("page") : 0;
|
|
|
|
// Set required attribute on inputs associated with labels containing <i title="Required field">
|
|
$('label:has(i[title="Required field"])').each(function () {
|
|
const inputId = $(this).attr("for");
|
|
$("#" + inputId).attr("required", "required");
|
|
});
|
|
|
|
// Hide the modal if the 'cancel' button is clicked
|
|
$("[name=cancel]").click(function () {
|
|
hideContent();
|
|
});
|
|
|
|
$("form").each(function () {
|
|
const form = $(this);
|
|
|
|
// Check if the form has a button where the text contains "Finish attempt"
|
|
let isLast = false;
|
|
const finishButton = form.find('input[type="submit"][value*="Finish attempt"]');
|
|
if (finishButton.length) {
|
|
isLast = true;
|
|
}
|
|
|
|
form.submit(function (event) {
|
|
event.preventDefault(); // Prevent the default form submission
|
|
|
|
// Check if the form is valid
|
|
if (!form[0].checkValidity()) {
|
|
form[0].reportValidity();
|
|
return;
|
|
}
|
|
|
|
// Serialize the form data
|
|
let formData = form.serialize();
|
|
|
|
// Add the submit button's data to formData
|
|
const submitButton = form.find(
|
|
'input[type="submit"][name="savevalues"]'
|
|
);
|
|
if (submitButton.length) {
|
|
formData +=
|
|
"&" +
|
|
encodeURIComponent(submitButton.attr("name")) +
|
|
"=" +
|
|
encodeURIComponent(submitButton.val());
|
|
}
|
|
|
|
const sesskey = form.find('input[name=sesskey]').val();
|
|
const attempt = form.find('input[name=attempt]').val();
|
|
|
|
// Perform the AJAX request
|
|
$.ajax({
|
|
url: form.attr("action"), // Use the form's action attribute
|
|
type: form.attr("method"), // Use the form's method attribute
|
|
data: formData,
|
|
success: function (response, status, xhr) {
|
|
if (form.attr("action").includes("/quiz/")) {
|
|
// Check if the quiz has a next page by calling the attempt.php page
|
|
let nextUrl = form.attr("action").replace("processattempt", "attempt");
|
|
nextUrl += "&page=" + (parseInt(page) + 1) + "&attempt=" + attempt + "&sesskey=" + sesskey;
|
|
|
|
if (isLast) {
|
|
nextUrl = "https://invalid.invalid";
|
|
}
|
|
|
|
$.get(nextUrl, function (response) {
|
|
console.log(nextUrl + " seems to be a valid URL, redirecting...");
|
|
nextUrl = nextUrl + "&embed=1";
|
|
|
|
if (inModal === "1") {
|
|
nextUrl += "&modal=1";
|
|
}
|
|
|
|
document.location.href = nextUrl;
|
|
|
|
return;
|
|
})
|
|
.fail(function () {
|
|
console.log("No next page found at " + nextUrl + ", finalizing attempt...");
|
|
|
|
const finalize = "/mod/quiz/processattempt.php";
|
|
const data = {
|
|
attempt: attempt,
|
|
finishattempt: 1,
|
|
sesskey: sesskey,
|
|
};
|
|
$.post(finalize, data, function (response) {
|
|
console.log(response);
|
|
// Close the modal if `modal=1` is set
|
|
if (inModal === "1") {
|
|
window.top.closeQuizModal();
|
|
} else {
|
|
// Else call the nextContent function
|
|
window.top.nextContent();
|
|
}
|
|
});
|
|
});
|
|
|
|
} else {
|
|
// Close the modal if `modal=1` is set
|
|
if (inModal === "1") {
|
|
window.top.closeQuizModal();
|
|
} else {
|
|
// Else call the nextContent function
|
|
window.top.nextContent();
|
|
}
|
|
}
|
|
},
|
|
error: function (xhr, status, error) {
|
|
// Handle any errors that occur during the AJAX request
|
|
console.error(
|
|
"Form submission failed: " + status + " - " + error
|
|
);
|
|
},
|
|
});
|
|
});
|
|
});
|
|
});
|
|
})
|
|
.catch((error) => {
|
|
console.error(error.message);
|
|
});
|
|
}
|
|
}); |