diff --git a/public/js/assessment.js b/public/js/assessment.js new file mode 100644 index 0000000..ac50c31 --- /dev/null +++ b/public/js/assessment.js @@ -0,0 +1,163 @@ +/** + * 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 = $('
').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 = $('').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 = $('
').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); \ No newline at end of file diff --git a/public/templates/assessment-shell.php b/public/templates/assessment-shell.php index 0ecd07e..8debb8e 100644 --- a/public/templates/assessment-shell.php +++ b/public/templates/assessment-shell.php @@ -56,15 +56,17 @@ if ( ! $invitation_data || ! $current_step ) {

- +

-
- token, 'quiztech_prescreening_nonce' ); ?> - + + + token, 'quiztech_prescreening_nonce' ); ?> + + token ); ?>"> ?> @@ -90,9 +92,10 @@ if ( ! $invitation_data || ! $current_step ) {
+
- +