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 $('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); }); } });