quiztech-assessment-platform/public/js/assessment.js

228 lines
No EOL
9 KiB
JavaScript

/**
* 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 = $('<div class="form-messages"></div>').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 = $('<span class="save-indicator" style="margin-left: 10px; font-size: 0.8em; color: grey;"></span>').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 = $('<div class="form-messages"></div>').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);