/** * Quiztech Assessment Interaction Script * * Handles AJAX submissions for pre-screening, answer auto-save, * and final assessment submission. */ (function($) { 'use strict'; $(function() { console.log('Assessment script loaded.'); // Check if localized data is available if (typeof quiztech_assessment_vars === 'undefined') { console.error('Quiztech Assessment Error: Localized variables not found.'); return; } var $prescreeningForm = $('#quiztech-prescreening-form'); var $prescreeningSection = $('#quiztech-prescreening-section'); var $assessmentSection = $('#quiztech-assessment-section'); var $submitButton = $prescreeningForm.find('button[type="submit"]'); var $preScreenFormMessages = $('
').insertBefore($submitButton); // Area for messages // Assessment specific elements var $assessmentForm = $('#quiztech-assessment-form'); var $questionsContainer = $('#quiztech-questions-container'); var $questionContainers = $questionsContainer.find('.quiztech-question-container'); var $timerDisplay = $('#quiztech-timer'); var $nextButton = $('#quiztech-next-question'); var $submitAssessmentButton = $('#quiztech-submit-assessment'); var $completionMessage = $('#quiztech-completion-message'); // State variables var currentQuestionIndex = 0; var totalQuestions = $questionContainers.length; var timerInterval; var timerSeconds = 0; // --- Pre-Screening Form Handling --- $prescreeningForm.on('submit', function(event) { event.preventDefault(); // Stop traditional form submission // Use $preScreenFormMessages here $preScreenFormMessages.empty().removeClass('error success'); // Clear previous messages $submitButton.prop('disabled', true).text('Submitting...'); // Disable button var formData = $(this).serialize(); // Get form data // Add required AJAX parameters formData += '&action=quiztech_submit_prescreening'; formData += '&nonce=' + quiztech_assessment_vars.prescreening_nonce; formData += '&invitation_id=' + quiztech_assessment_vars.invitation_id; $.ajax({ type: 'POST', url: quiztech_assessment_vars.ajax_url, data: formData, dataType: 'json', // Expect JSON response from server success: function(response) { if (response.success) { // Success! Hide pre-screening, show assessment $preScreenFormMessages.addClass('success').text(response.data.message || 'Success!'); // Show success message briefly & Use correct variable $prescreeningSection.slideUp(); $assessmentSection.slideDown(); startTimer(); // Start the assessment timer updateNavigationButtons(); // Show initial nav state // No need to re-enable button as the form is gone } else { // Handle WP JSON error $preScreenFormMessages.addClass('error').text(response.data.message || 'An error occurred.'); // Use correct variable $submitButton.prop('disabled', false).text('Submit Pre-Screening & Start Assessment'); // Re-enable button } }, error: function(jqXHR, textStatus, errorThrown) { // Handle general AJAX error console.error("AJAX Error:", textStatus, errorThrown); $preScreenFormMessages.addClass('error').text('A network error occurred. Please try again.'); // Use correct variable $submitButton.prop('disabled', false).text('Submit Pre-Screening & Start Assessment'); // Re-enable button } }); }); // --- Assessment Answer Auto-Save --- // var $assessmentForm = $('#quiztech-assessment-form'); // Already defined above var autoSaveTimeout; // To debounce requests // Target input/textarea/select elements within the assessment form for auto-save $assessmentForm.on('change blur', 'input, textarea, select', function() { clearTimeout(autoSaveTimeout); // Clear previous timeout if exists var $input = $(this); var $questionGroup = $input.closest('.quiztech-question-container'); // Updated selector var questionId = $questionGroup.data('question-id'); var answer = $input.val(); // Add a small visual indicator within the question group var $indicator = $questionGroup.find('.save-indicator'); if ($indicator.length === 0) { $indicator = $('').appendTo($questionGroup.find('label:first')); } $indicator.text('Saving...'); // Debounce the AJAX request slightly autoSaveTimeout = setTimeout(function() { $.ajax({ type: 'POST', url: quiztech_assessment_vars.ajax_url, data: { action: 'quiztech_save_answer', nonce: quiztech_assessment_vars.assessment_nonce, // Use the correct nonce invitation_id: quiztech_assessment_vars.invitation_id, question_id: questionId, answer: answer }, dataType: 'json', success: function(response) { if (response.success) { $indicator.text('Saved ✓').css('color', 'green'); // Optionally fade out the indicator after a delay setTimeout(function() { $indicator.fadeOut().remove(); }, 2000); } else { $indicator.text('Error!').css('color', 'red'); console.error("Auto-save error:", response.data.message); // Consider more prominent error display if needed } }, error: function(jqXHR, textStatus, errorThrown) { $indicator.text('Network Error!').css('color', 'red'); console.error("AJAX Error:", textStatus, errorThrown); } }); }, 500); // Wait 500ms after the last change/blur before sending }); // --- Assessment Navigation --- $nextButton.on('click', function() { if (currentQuestionIndex < totalQuestions - 1) { // Hide current, show next $questionContainers.eq(currentQuestionIndex).addClass('quiztech-question-hidden'); currentQuestionIndex++; $questionContainers.eq(currentQuestionIndex).removeClass('quiztech-question-hidden'); updateNavigationButtons(); } }); function updateNavigationButtons() { if (currentQuestionIndex >= totalQuestions - 1) { // Last question $nextButton.hide(); $submitAssessmentButton.show(); } else { $nextButton.show(); $submitAssessmentButton.hide(); } } // --- Timer Functions --- function startTimer() { if (timerInterval) clearInterval(timerInterval); // Clear existing if any timerSeconds = 0; // Reset timer $timerDisplay.text(formatTime(timerSeconds)); // Initial display timerInterval = setInterval(function() { timerSeconds++; $timerDisplay.text(formatTime(timerSeconds)); }, 1000); } function formatTime(totalSeconds) { var hours = Math.floor(totalSeconds / 3600); var minutes = Math.floor((totalSeconds % 3600) / 60); var seconds = totalSeconds % 60; // Pad with leading zeros minutes = String(minutes).padStart(2, '0'); seconds = String(seconds).padStart(2, '0'); return (hours > 0 ? String(hours).padStart(2, '0') + ':' : '') + minutes + ':' + seconds; } // --- Final Assessment Submission --- // var $submitAssessmentButton = $('#quiztech-submit-assessment'); // Already defined above var $assessmentFormMessages = $('').insertAfter($submitAssessmentButton); // Area for messages $submitAssessmentButton.on('click', function(event) { event.preventDefault(); // Stop traditional form submission (though AJAX auto-save handles data) if (!confirm('Are you sure you want to submit your assessment?')) { return; // User cancelled } $assessmentFormMessages.empty().removeClass('error success'); $submitAssessmentButton.prop('disabled', true).text('Submitting...'); $.ajax({ type: 'POST', url: quiztech_assessment_vars.ajax_url, data: { action: 'quiztech_submit_assessment', nonce: quiztech_assessment_vars.assessment_nonce, // Reuse assessment nonce invitation_id: quiztech_assessment_vars.invitation_id }, dataType: 'json', success: function(response) { if (response.success) { // Success! Display completion message and hide form/timer // Use .html() to render potential basic HTML in the message $completionMessage.html(response.data.completionMessage || 'Assessment Submitted Successfully!').show(); $assessmentForm.hide(); // Hide the form elements (questions, nav) $timerDisplay.hide(); // Hide timer clearInterval(timerInterval); // Stop timer $assessmentFormMessages.remove(); // Remove the temporary message area if not needed } else { $assessmentFormMessages.addClass('error').text(response.data.message || 'An error occurred during submission.'); $submitAssessmentButton.prop('disabled', false).text('Submit Assessment'); // Re-enable button } }, error: function(jqXHR, textStatus, errorThrown) { console.error("AJAX Error:", textStatus, errorThrown); $assessmentFormMessages.addClass('error').text('A network error occurred. Please try again.'); $submitAssessmentButton.prop('disabled', false).text('Submit Assessment'); // Re-enable button } }); }); }); // End document ready })(jQuery);