I am working on a simple AJAX WordPress plugin. The plugin needs to make a call and then pass the results using AJAX.
Here is my function in JavaScript:
function courseGradeHistory(student_id) {
// Ensure jQuery is available
if (typeof jQuery === 'undefined') {
console.error('jQuery is not defined. Please ensure jQuery is loaded before this script.');
return;
}
// Get course code and student ID from the input fields
var course_code = document.getElementById("course_code").value;
var $resultsContainer = $('#studentCourseSchedule');
var student_id = student_id || document.getElementById("student_id").value;
console.log("Course Code: " + course_code);
console.log("Student ID: " + student_id);
// Validate inputs
if (!student_id || !course_code) {
alert("Please provide both Student ID and Course Code.");
return;
}
alert("Loading Course History for Student ID: " + student_id + " and Course Code: " + course_code);
$resultsContainer.html('<p>Loading Courses...</p>');
// Make AJAX request to fetch course grade history
// Ensure that 'ajaxurl' is defined in your WordPress env
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'connect_course_history',
student_id: student_id,
course_code: course_code,
numberofdays: 30
},
success: function(data) {
$resultsContainer.html(data);
},
error: function(xhr, status, error) {
$resultsContainer.html('<p>Error loading courses. Please try again.</p>');
console.error('AJAX Error:', status, error);
}
});
}
And below is my corresponding PHP function:
// Register action for authenticated users
add_action('wp_ajax_connect_course_history', 'connect_course_history');
// register action for unauthenticated users
add_action('wp_ajax_nopriv_connect_course_history', 'connect_course_history');
function connect_course_history($student_id, $course_code, $numberofdays) {
global $wpdb;
$sql = "CALL sp_connect_course_history('$student_id', '$course_code', $numberofdays);";
$wpdb->query($sql);
$course_history = $wpdb->get_results($sql, ARRAY_A);
if (empty($course_history)) {
return "<p>No course history found for this student.</p>";
}
// Prepare the output
$output = "<table><tr><th>DATE</th><th>Grade</th></tr>";
foreach ($course_history as $course) {
$output .= "<tr>";
$output .= "<td>{$course['DATE']}</td>";
$output .= "<td>{$course['grade']}</td>";
$output .= "</tr>";
}
$output .= "</table>";
return $output;
}
Below is all that I see in the Developer Console:
error @ myplugin_script.js:63
c @ jquery.min.js?ver=3.7.1:2
fireWith @ jquery.min.js?ver=3.7.1:2
l @ jquery.min.js?ver=3.7.1:2
(anonymous) @ jquery.min.js?ver=3.7.1:2
XMLHttpRequest.send
send @ jquery.min.js?ver=3.7.1:2
ajax @ jquery.min.js?ver=3.7.1:2
(anonymous) @ jquery-migrate.min.js?ver=3.4.1:2
e.<computed> @ jquery-migrate.min.js?ver=3.4.1:2
courseGradeHistory @ myplugin_script.js:48
onchange @ ?page_id=1238&student_id=954894:516
handleMouseUp_ @ unknown
I expect the results from the call to update resultsContainer.
Your PHP function connect_course_history($student_id, $course_code, $numberofdays) is declared to accept three arguments. However, when WordPress calls an AJAX action, it doesn't automatically pass $_POST or $_GET variables as direct function arguments.
<?php
add_action('wp_ajax_connect_course_history', 'connect_course_history_callback');
add_action('wp_ajax_nopriv_connect_course_history', 'connect_course_history_callback');
function connect_course_history_callback() {
global $wpdb;
// IMPORTANT: Retrieve data from $_POST
$student_id = isset($_POST['student_id']) ? sanitize_text_field($_POST['student_id']) : '';
$course_code = isset($_POST['course_code']) ? sanitize_text_field($_POST['course_code']) : '';
$numberofdays = isset($_POST['numberofdays']) ? intval($_POST['numberofdays']) : 30;
if (empty($student_id) || empty($course_code)) {
echo "<p>Error: Missing Student ID or Course Code.</p>";
wp_die(); // Always use wp_die() or die() at the end of AJAX callbacks
}
$sql = $wpdb->prepare("CALL sp_connect_course_history(%s, %s, %d);", $student_id, $course_code, $numberofdays);
$wpdb->query($sql);
$course_history = $wpdb->get_results($sql);
if ($wpdb->last_error) {
error_log("Database Error in connect_course_history: " . $wpdb->last_error);
echo "<p>Database error: Could not retrieve course history.</p>";
wp_die();
}
if (empty($course_history)) {
echo "<p>No course history found for this student or course.</p>";
wp_die();
}
$output = "<table><thead><tr><th>DATE</th><th>Grade</th></tr></thead><tbody>";
foreach ($course_history as $course) {
$output .= "<tr>";
$output .= "<td>" . esc_html($course->DATE) . "</td>";
$output .= "<td>" . esc_html($course->grade) . "</td>";
$output .= "</tr>";
}
$output .= "</tbody></table>";
echo $output;
wp_die();
}
?>
Your JavaScript is mostly fine, as it correctly sends the data. The problem was on the PHP side.
function courseGradeHistory(student_id_param) {
if (typeof jQuery === 'undefined') {
console.error('jQuery is not defined. Please ensure jQuery is loaded before this script.');
return;
}
var course_code = document.getElementById("course_code").value;
var $resultsContainer = jQuery('#studentCourseSchedule');
var student_id = student_id_param || document.getElementById("student_id").value;
console.log("Course Code: " + course_code);
console.log("Student ID: " + student_id);
if (!student_id || !course_code) {
alert("Please provide both Student ID and Course Code.");
return;
}
alert("Loading Course History for Student ID: " + student_id + " and Course Code: " + course_code);
$resultsContainer.html('<p>Loading Courses...</p>');
jQuery.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'connect_course_history',
student_id: student_id,
course_code: course_code,
numberofdays: 30
},
success: function(data) {
$resultsContainer.html(data);
console.log("AJAX Success:", data);
},
error: function(xhr, status, error) {
$resultsContainer.html('<p>Error loading courses. Please try again.</p>');
console.error('AJAX Error:', status, error, xhr.responseText);
}
});
}