quiztech-assessment-platform/public/js/assessment.js
Ruben Ramirez 130b9eefb9 feat: Implement front-end assessment interaction AJAX flow
- Add AssessmentAjaxHandler class for AJAX requests.
- Add assessment.js for front-end logic.
- Implement pre-screening form submission via AJAX.
- Implement answer auto-save via AJAX.
- Implement final assessment submission via AJAX.
- Update assessment-shell.php template for dynamic rendering and JS hooks.
- Enqueue and localize assessment.js conditionally.

Refs: assessment_interaction_plan.md
Note: Includes TODOs for evaluation CPT handling, status updates, and sanitization.
2025-04-03 16:02:16 -05:00

163 lines
No EOL
8 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 $formMessages = $('<div class="form-messages"></div>').insertBefore($submitButton); // Area for messages
// --- Pre-Screening Form Handling ---
$prescreeningForm.on('submit', function(event) {
event.preventDefault(); // Stop traditional form submission
$formMessages.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
$formMessages.addClass('success').text(response.data.message || 'Success!'); // Show success message briefly
$prescreeningSection.slideUp();
$assessmentSection.slideDown();
// No need to re-enable button as the form is gone
} else {
// Handle WP JSON error
$formMessages.addClass('error').text(response.data.message || 'An error occurred.');
$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);
$formMessages.addClass('error').text('A network error occurred. Please try again.');
$submitButton.prop('disabled', false).text('Submit Pre-Screening & Start Assessment'); // Re-enable button
}
});
});
// --- Assessment Answer Auto-Save ---
var $assessmentForm = $('#quiztech-assessment-form');
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('.question-group');
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
});
// --- Final Assessment Submission ---
var $submitAssessmentButton = $('#quiztech-submit-assessment');
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 message and potentially hide the form/button
$assessmentFormMessages.addClass('success').text(response.data.message || 'Assessment Submitted Successfully!');
$assessmentForm.hide(); // Hide the form after successful submission
// Optionally redirect: window.location.href = response.data.redirect_url;
} 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);