228 lines
No EOL
9 KiB
JavaScript
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); |