I have been following multiple tutorials on this (including Wordpress's own) and its driving me a little crazy.
I am trying to get AJAX working on the front end in Wordpress, however it is simply not doing anything, I know the function works as I have tested this independently, your input will be really appreciated on this one. Many thanks in advance.
The code in functions.php
function call_ajax()
{
//assuming this is in a theme?
wp_enqueue_script( 'ajax_car_models', get_template_directory_uri() . '/js/ajax_car_models.js', array( 'jquery' ), null, true);
//loacalize the script using the same handle it was registered / enqueued with
wp_localize_script( 'ajax_car_models', 'my_ajax_script', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
}
//make a call to call_ajax at the right time
add_action( 'wp_enqueue_scripts', 'call_ajax' );
add_action( 'wp_ajax_ajax_car_models', 'ajax_car_models' );
add_action( 'wp_ajax_nopriv_ajax_car_models', 'ajax_car_models' );
function ajax_car_models() {
$args = array( 'post_type' => 'product', 'posts_per_page' => 1040 );
$loop1 = new WP_Query( $args );
$code = '';
$car_make = 26;
$all_models = array();
while ( $loop1->have_posts() ) : $loop1->the_post();
$terms_make = get_the_terms( get_the_id(), 'pa_car-make' );
foreach ( $terms_make as $make ) {
if ( $make->term_id == $car_make ) {
$the_car_model = get_the_terms( get_the_id(), 'pa_model' );
foreach ( $the_car_model as $the_model ) {
if ($all_models[$the_model->name] != 'true') {
$code .= '<br />'.$the_model->name.' ';
$all_models[$the_model->name] = 'true';
}
}
}
}
endwhile;
wp_reset_postdata();
header( 'Content-type: application/json' );
echo json_encode( $code );
die();
}
And the jQuery itself:
jQuery( document ).ready(function() {
jQuery('#car-make').change(my_js_function);
function my_js_function()
{
jQuery.ajax({
url: my_ajax_script.ajaxurl,
dataType: 'json', // add this line
data: ({action : 'ajax_car_models'}),
success: function() {
jQuery("#feedback").html(data);
}
});
}
});
If you include you javascript inline you will not be able to use localize pass it the ajax url.
You should move your javascript into a different file and then use wp_enqueue_script in order to properly use ajax.
function call_ajax()
{
//assuming this is in a theme?
wp_enqueue_script( 'ajax_car_models', get_template_directory_uri() . '/js/ajax_car_models.js', array( 'jquery' ), null, true);
//loacalize the script using the same handle it was registered / enqueued with
wp_localize_script( 'ajax_car_models', 'my_ajax_script', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
}
//make a call to call_ajax at the right time
add_action( 'wp_enqueue_scripts', 'call_ajax' );
You also need to send json headers in your response function
header( 'Content-type: application/json' );
echo json_encode( $code );
exit();
In your ajax call you are not passing the data to your success callback
success: function(data){
console.log(data);
//...
}
You can use the network tab on the chrome developer tools to look at what requests are actually made and check the response they receive.
According to the PHP manual json_encode needs string data to be UTF8 encoded.
Alternatively, you can try doing this instead in your functions.php...
$return_array = array(
'val' => $code
);
echo json_encode($return_array);
Then, in your jQuery script...
jQuery("#feedback").html(data.val);
Also, try adding to your ajax request one more option...
url: my_ajax_script.ajaxurl,
dataType: 'json', // add this line
data: ({action : 'ajax_car_models'}),
Hope these help!
Related
I have a CF7 form and need to get Woocommerce billing phone number and display it inside phone field on page load using jQuery function. I used this code in header area:
// Get billing_phone_number On Quote Form
jQuery(document).ready(function(){
jQuery('#mk-order-tel').val("<?php echo get_user_meta( get_current_user_id(), 'billing_phone', true ) ?>");
});
But it returns raw php code ( <?php echo get_user_meta( get_current_user_id(), 'billing_phone', true ) ?> ) instead of phone number; when I use same php code directly in php files of Woocommerce it works correctly. What should I do to run a php syntax through the jQuery?
EDIT
To escape of above issue, I tried to get data by using ajax but this method does not work too:
in functions.php :
/* Get Customer Phone Number */
function my_ajax_handler(){
global $woocommerce;
$phone = get_user_meta( get_current_user_id(), 'billing_phone', true );
?>
<script type="text/javascript">
jQuery( function($){
jQuery('#mk-order-tel').val("<?php echo json_encode($phone); ?>");
});
</script>
<?php
}
add_action( 'wp_ajax_call_my_ajax_handler', 'my_ajax_handler' );
add_action( 'wp_ajax_nopriv_call_my_ajax_handler', 'my_ajax_handler' );
function my_quote_scripts() {
wp_enqueue_script( 'my-ajax-script', get_stylesheet_directory_uri() . '/js/quote.js', array('jquery') );
wp_localize_script( 'my-ajax-script', 'my_ajax_object', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
}
add_action( 'wp_enqueue_scripts', 'my_quote_scripts' );
in quote.js :
jQuery.ajax({
type:"POST",
url: my_ajax_object.ajax_url,
data: { 'action': 'call_my_ajax_handler' }
})
What else can I do ?
This should work, you're getting an exception because of quotes
const tel = <?php echo get_user_meta( get_current_user_id(), 'billing_phone', true ) ?>;
jQuery(document).ready(function(){
jQuery('#tel').val(tel);
});
Or you can just replace single quotes to double
jQuery(document).ready(function(){
jQuery('#tel').val("<?php echo get_user_meta( get_current_user_id(), 'billing_phone', true ) ?>");
});
Simply using this code in functions.php of child theme can fetch customer phone and display inside input text field :
/* Get Customer Phone Number On Quote Form */
function my_jquery_var() {
if ( $yourtel = get_user_meta( get_current_user_id(), 'billing_phone', true ) ) {
echo '<script type="text/javascript">
var yourTel = "' . $yourtel . '";
document.getElementById("mk-order-tel").value = yourTel;
</script>' . "\n";
}
}
add_action( 'wp_footer', 'my_jquery_var' );
Note: JavaScript should be in footer area.
I"m using the tutorial from this blog post to implement Ajax Load More functionality. https://rudrastyh.com/wordpress/load-more-posts-ajax.html
I've successfully implemented this on my archive page for all blog posts. However, I've got several "RElated Posts" sections that use custom WP Queries that I can't get to work. I've tried the solution in this comment: https://rudrastyh.com/wordpress/load-more-posts-ajax.html#comment-1055
It loads new posts, but they are not adhering to the argumenets of the custom query (specifically displaying posts only in the same category).
The custom query is working (it displays 4 related posts from the same category). When i'm loading more, it is not respecting pagination (it's loading 6 posts instead of 4) and it is not respecting the query (it is loading posts not in the same category).
<div class="related-blog-posts gray-bg pt-5 pb-5 blog">
<div class="related-title pb-3">
<h1 class="mb-2">Related Stories</h1>
<img src="/dcustom/wp-content/uploads/2019/04/Path-137#2x.png" />
</div><!-- scroll-down-->
<div class="container">
<div class="row">
<?php
$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
$query_args = array(
'category__in' => wp_get_post_categories( $post->ID ),
'paged' => $paged,
'post_type' => 'post',
'posts_per_page' => 4,
'post__not_in' => array( $post->ID ),
'orderby' => 'date',
'order' => 'DESC'
);
$third_query = new WP_Query( $query_args ); ?>
<?php
//Loop through posts and display...
if($third_query->have_posts()) : ?>
<?php while ($third_query->have_posts() ) : $third_query->the_post(); ?>
<?php get_template_part('template-parts/content-related-blog-posts'); ?>
<?php endwhile; ?><!-- end the loop-->
<?php endif; ?>
<?php wp_reset_postdata(); ?>
<?php // don't display the button if there are not enough posts
if ( $third_query->max_num_pages > 1 )
echo '<a class="custom_loadmore btn btn-primary">More posts</a>'; // you can use <a> as well
?>
<?php endif; ?><!-- end loop if--->
</div><!-- row -->
</div><!-- container -->
</div><!-- related-case-studies-->
<script>
var test = '<?php echo serialize( $third_query->query_vars ) ?>',
current_page_myajax = 1,
max_page_myajax = <?php echo $third_query->max_num_pages ?>
</script>
<script src="<?php bloginfo('template_url')?>/js/myloadmore.js"></script>
jQuery(function($){ // use jQuery code inside this to avoid "$ is not defined" error
$('.misha_loadmore').click(function(){
var button = $(this),
data = {
'action': 'loadmore',
'query': misha_loadmore_params.posts, // that's how we get params from wp_localize_script() function
'page' : misha_loadmore_params.current_page
};
$.ajax({ // you can also use $.post here
url : misha_loadmore_params.ajaxurl, // AJAX handler
data : data,
type : 'POST',
beforeSend : function ( xhr ) {
button.text('Loading...'); // change the button text, you can also add a preloader image
},
success : function( data ){
if( data ) {
button.text( 'More posts' ).prev().after(data); // insert new posts
misha_loadmore_params.current_page++;
if ( misha_loadmore_params.current_page == misha_loadmore_params.max_page )
button.remove(); // if last page, remove the button
// you can also fire the "post-load" event here if you use a plugin that requires it
// $( document.body ).trigger( 'post-load' );
} else {
button.remove(); // if no data, remove the button as well
}
}
});
});
$('.custom_loadmore').click(function(){
//custom query on front-page.php
var button = $(this),
data = {
'action': 'loadmore',
'query': test,
'page' : current_page_myajax
};
$.ajax({
url : '/dcustom/wp-admin/admin-ajax.php', // AJAX handler
data : data,
type : 'POST',
beforeSend : function ( xhr ) {
button.text('Loading...'); // change the button text, you can also add a preloader image
},
success : function( data ){
if( data ) {
button.text( 'More posts' ).prev().after(data); // insert new posts
current_page_myajax++;
if ( current_page_myajax == max_page_myajax )
button.remove(); // if last page, remove the button
} else {
//button.remove(); // if no data, remove the button as well
}
}
});
});
});
function misha_my_load_more_scripts() {
global $wp_query;
// In most cases it is already included on the page and this line can be removed
wp_enqueue_script('jquery');
// register our main script but do not enqueue it yet
wp_register_script( 'my_loadmore', get_stylesheet_directory_uri() . '/js/myloadmore.js', array('jquery') );
// now the most interesting part
// we have to pass parameters to myloadmore.js script but we can get the parameters values only in PHP
// you can define variables directly in your HTML but I decided that the most proper way is wp_localize_script()
wp_localize_script( 'my_loadmore', 'misha_loadmore_params', array(
'ajaxurl' => site_url() . '/wp-admin/admin-ajax.php', // WordPress AJAX
'posts' => json_encode( $wp_query->query_vars ), // everything about your loop is here
'current_page' => get_query_var( 'paged' ) ? get_query_var('paged') : 1,
'max_page' => $wp_query->max_num_pages,
) );
wp_enqueue_script( 'my_loadmore' );
}
add_action( 'wp_enqueue_scripts', 'misha_my_load_more_scripts' );
/* AJAX LOOP FOR THE ARCHIVE PAGE */
function misha_loadmore_ajax_handler(){
// prepare our arguments for the query
$args = json_decode( stripslashes( $_POST['query'] ), true );
$args['paged'] = $_POST['page'] + 1; // we need next page to be loaded
$args['post_status'] = 'publish';
// it is always better to use WP_Query but not here
query_posts( $args );
if( have_posts() ) :
// run the loop
while( have_posts() ): the_post();
// look into your theme code how the posts are inserted, but you can use your own HTML of course
// do you remember? - my example is adapted for Twenty Seventeen theme
get_template_part( 'template-parts/content-index', get_post_format() );
// for the test purposes comment the line above and uncomment the below one
// the_title();
endwhile;
endif;
die; // here we exit the script and even no wp_reset_query() required!
}
add_action('wp_ajax_loadmore', 'misha_loadmore_ajax_handler'); // wp_ajax_{action}
add_action('wp_ajax_nopriv_loadmore', 'misha_loadmore_ajax_handler'); // wp_ajax_nopriv_{action}
I want to be able to only enqueue certain JavaScript when there is a form embedded (emedded with shortcode and php).
Is there an action hook for Gravity Forms that triggers when a form is embedded? Then I could do something like this.
add_action('some_gforms_hook', function() {
add_action('wp_enqueue_scripts', function() {
wp_enqueue_script( 'postcode', get_bloginfo('stylesheet_directory') . '/modules/Postcode/assets/js/postcode.js', array('jquery') );
wp_localize_script( 'postcode', 'ajax_object', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
});
});
If there is no such hook, is there another (non hacky) way of archiving what I want?
You're looking for gform_enqueue_scripts. It passes the $form object so you determine if your scripts should be loaded for the given form.
I found this example in the documentation.
add_action( 'gform_register_init_scripts', 'gform_format_money' );
function gform_format_money( $form ) {
$script = '(function($){' .
'$('.gf_money input').each(function(){' .
'$(this).val(gformFormatMoney($(this).val()));' .
'}).change(function(){' .
'$(this).val(gformFormatMoney($(this).val()));' .
'});' .
'})(jQuery);';
GFFormDisplay::add_init_script( $form['id'], 'format_money', GFFormDisplay::ON_PAGE_RENDER, $script );
}
The problem with this example is that I don't like the JS written in my PHP files and the add_init_script() function needs a string with JS as argument.
I could use file_get_contents() to get the JS from the file but then I will not be able to localize the script for injecting the AJAX url.
I now use the hook as in the question and it works perfect.
add_action( 'gform_register_init_scripts', function() {
add_action('wp_enqueue_scripts', function() {
wp_enqueue_script( 'postcode', get_bloginfo('stylesheet_directory') . '/modules/Postcode/assets/js/postcode.js', array('jquery') );
wp_localize_script( 'postcode', 'ajax_object', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
});
});
hey guys i have another wordpress question here i've looked at other posts but can't seem to find the solution. so figure ill post my code and see what happens. so im trying to load more posts with ajax but everytime i click it just returns a 0. any help would be much appreciated thanks!
functions.php
add_action( 'get_wp_ajax_publications', 'get_publications' );
add_action( 'get_wp_ajax_nopriv_publications', 'get_publications' );
function get_publications() {
if ( isset($_REQUEST) ) {
$args = array( 'post_type' => 'publications', 'posts_per_page' => 2, 'offset' => 2 );
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
the_title();
echo '<div class="entry-content">';
the_content();
echo '</div>';
endwhile;
}
die();
}
myloadmore.js
$(document).ready(function(){
var offset_value = 0;
$('#loadmore').click(function() {
$.ajax({
url: ajaxurl,
data: {
'action' : 'get_publications',
'offset' : offset_value
},
success:function(data) {
$('#posts').html(data);
}
});
console.log('loadmore clicked');
offset_value +=2;
return false;
});
});
Solved it! had to change the names of my hooks
add_action( 'get_wp_ajax_publications', 'get_publications' );
add_action( 'get_wp_ajax_nopriv_publications', 'get_publications' );
should be
add_action( 'wp_ajax_publications', 'get_publications' );
add_action( 'wp_ajax_nopriv_publications', 'get_publications' );
dropped the get_ from infront of my wp ajax call! thanks so much for your help #rjustin
I have a shortcode in Wordpress which I want to call it with jQuery with the click of a button. I read a few websites and tutorials, but I cannot figure exactly what happen.
I put this on function.php:
add_action( 'init', function() {
ps_register_shortcode_ajax( 'ps_get_survey_form', 'ps_get_survey_form' );
} );
function ps_register_shortcode_ajax( $callable, $action ) {
if ( empty( $_POST['action'] ) || $_POST['action'] != $action )
return;
call_user_func( $callable );
}
function ps_get_survey_form() {
echo do_shortcode( '[dopbsp id=6 lang=el]' );
die();
}
And this on the page-template.php I use:
<button id="testonclick" onclick="test()"></button>
<div id="testresults"></div>
<script>
function test() {
jQuery.ajax({
url: "http://localhost/myweb" + "/wp-admin/admin-ajax.php",
data : {action: 'ps_get_survey_form'},
success: function(results){
jQuery("#testresults").html(results)
},
error: function(errorThrown){console.log(errorThrown);}
});// end of ajax
}
</script>
However, the results is 0. Any idea what happened wrong?
I believe you want to be using something like
add_action('wp_ajax_nopriv_ps_get_survey_form', 'ps_get_survey_form' );
add_action( 'wp_ajax_ps_get_survey_form', 'ps_get_survey_form' );
instead of your
add_action( 'init', function() { ps_register_shortcode_ajax( 'ps_get_survey_form', 'ps_get_survey_form' ); } );
You can read more about that on this Codex page.
As far as I know, what you wrote doesn't make your function available via AJAX at all. I certainly don't know everything though. This is just the method that I use.
You should look over this article on WP and AJAX. It is best to 'tie' the ajax call to the admin ajax script.
http://www.smashingmagazine.com/2011/10/18/how-to-use-ajax-in-wordpress/
add_action("wp_ajax_my_user_vote", "my_user_vote");
add_action("wp_ajax_nopriv_my_user_vote", "my_must_login");
and
wp_register_script( "my_voter_script", WP_PLUGIN_URL.'/my_plugin/my_voter_script.js', array('jquery') );
wp_localize_script( 'my_voter_script', 'myAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' )));
be aware though that the shortcode may load css or js that is needed for the form, which won't get loaded via the ajax call.