I’ve created a custom post template for a front-end question bank/quiz in which I have two elements:
- A div which displays question text
- A button when pressed should trigger an ajax query to get the next question from a database
Code in functions.php
//Load ajax object for question bank
add_action('wp_enqueue_scripts', 'my_enqueue');
function my_enqueue(){
wp_enqueue_script( "question-refresh", get_stylesheet_directory_uri() . "/js/question-refresh.js", array("jquery") , null, true);
$question_nonce = wp_create_nonce( 'question' );
wp_localize_script(
'question-refresh',
'my_ajax_obj',
array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => $question_nonce,
)
);
}
add_action('wp_ajax_nopriv_get_question', 'get_question_from_database');
add_action('wp_ajax_get_question', 'get_question_from_database');
function get_question_from_database(){
check_ajax_referer( 'question' ); //Checks nonce
echo "<script type='text/javascript'>alert('SCRIPTS LOADED');</script>";
$question_number = rand(1,4);
$query = "SELECT * FROM `questions`
WHERE question_number = $question_number";
$result = $mysqli->query($query) or die($mysqli->error.__LINE__);
$question = $result->fetch_assoc();
echo json_encode(array("success" => true, "question-text"=>$question['question_text']));
exit;
}
The code I have in my custom post template is as following:
<main>
<div class="container">
<div>Question 1 of 5</div>
<p id="question-container">
</p>
<button id="next-question" type="button">Next</button>
</div>
</main>
I have a separate js file stored in my-child-theme/js/question-refresh.js I think I have isolated where the issue is coming from. I have obviously done something wrong with the jQuery.post as it doesn’t seem to be running. I am new to jQuery and have just been following other questions and tutorials. Would really appreciate if someone could spot what I am doing wrong. Many thanks!
jQuery(document).ready(function($) {
$("#next-question").click( function() {
console.log("Hello");
$.post(
my_ajax_obj.ajax_url,
{
_ajax_nonce: my_ajax_obj.nonce,
"action": "get_question"
},
function(response) {
console.log("Hello");
console.log(response);
$("#question-container").text(response.question-text);
});
});
});
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
There’s two problems that I see.
Firstly, your add_action('wp_ajax_nopriv_get_question',... code is inside your template, but your template is not going to be loaded when the request is sent to wp-admin/admin-ajax.php, which does not load templates. The callback code and the code that hooks it need to go in your theme’s functions.php file.
Secondly, you have only hooked the callback for logged-out users (nopriv_). This means that the code will not work when you are logged in. You need to hook for both logged-in and logged-out users:
add_action('wp_ajax_get_question', 'get_question_from_database');
add_action('wp_ajax_nopriv_get_question', 'get_question_from_database');
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0