A simple Ajax call in wordpress doesn't give the expecetd output - ajax

Here is my javascript file:-
jQuery(document).ready( function($) {
$('#test_button').click(function(e){
alert("test");
$.ajax({
url : my_ajax_object.ajaxurl ,
type : 'post',
dataType : 'json',
data : {
action : 'do_ga'
},
complete: function(res, status) {
if( status == 'success' ) {
console.log("success "+res);
} else {
console.log("fail "+res);
}
}
});
});
});
here is my php code in functions.php:-
function do_ga() {
die("test" );
}
add_action( 'wp_ajax_do_ga', 'do_ga' );
add_action( 'wp_ajax_nopriv_do_ga', 'do_ga' );
//this is the script en queuing
function my_enqueue() {
wp_enqueue_script( 'ga-loadmore', get_template_directory_uri() . '/pl-custom/front-end-assets/js/ga-loadmore.js', array('jquery') );
wp_localize_script( 'ga-loadmore', 'my_ajax_object',
array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
}
add_action( 'wp_enqueue_scripts', 'my_enqueue' );
So,upon the click of the button with id "#test_button" , instead of outputting success [object][object] , it outputs fail [object][object]. What needs to be done here. Precisely , i want "success test". please add the json_encode and decode wherever required in the solution.Thanks

I've separated the PHP code in another file and included it in functions.php and also separated the enqueuing, and changed the syntax of the request a little. I hereby attach my code and it works:
function do_ga() {//server code
$x="test";
wp_die( $x);
exit;
}
add_action( 'wp_ajax_do_ga', 'do_ga' );
add_action( 'wp_ajax_nopriv_do_ga', 'do_ga' );
client side(already enqueued):-
jQuery(document).ready( function($) {
$('#test_button').click(function(e){
url = window.location.origin + '/wp-admin/admin-ajax.php?action=do_ga';
alert("test");
$.ajax({
async: true,
type: 'POST',
url: url,
data: {
'my_number':1 //you need not pass data
},
complete: function(res, status) {
if( status == 'success' ) {
alert("success "+ res.responseText);
} else {
alert("unable to process request");
}
}
})
});
});

Related

Tabulation added to returned ajax call data

my problem is that whenever I do an ajax call and console.log the returned data, there is a tabulation in front of my returned data. Is this normal? If so, is there a way to strip the tabulation from the data variable? My code is below.
function search_rhymes_get_rhyme_content() {
echo 'Test';
die();
}
$.ajax( {
url: rhymes_ajax_obj.ajaxurl,
data: {
'action': 'search_rhymes_get_rhyme_content'
},
success: function( data ) {
console.log( 'Test:' + data );
},
error: function( error ) {
console.log( error );
}
} );
Thanks
I got it working. Output: https://ibb.co/QQHGgXV
I added the following line before my console.log:
data = data.trim();
Here's the updated code with the solution:
function search_rhymes_get_rhyme_content() {
echo 'Test';
die();
}
$.ajax( {
url: rhymes_ajax_obj.ajaxurl,
data: {
'action': 'search_rhymes_get_rhyme_content'
},
success: function( data ) {
console.log( 'Test1:' + data );
data = data.trim();
console.log( 'Test2:' + data );
},
error: function( error ) {
console.log( error );
}
} );

How add the Woocommerce notices(without reload) when using add to cart with ajax?

I try to make the add to cart buttons and notices on the productpages(and everywhere else) work with ajax. But the notices (e.g. You cannot add that amount to the cart - we have X in stock and you already have Y in your cart.) don't work.
How do I make it work?
This is what I have right now:
JS for AJAX Add to Cart handling
/**
* JS for AJAX Add to Cart handling
*/
function ace_product_page_ajax_add_to_cart_js() {
?><script type="text/javascript" charset="UTF-8">
jQuery(function($) {
$('form.cart').on('submit', function(e) {
e.preventDefault();
var form = $(this);
form.block({ message: null, overlayCSS: { background: '#fff', opacity: 0.6 } });
var formData = new FormData(form.context);
formData.append('add-to-cart', form.find('[name=add-to-cart]').val() );
// Ajax action.
$.ajax({
url: wc_add_to_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'ace_add_to_cart' ),
data: formData,
type: 'POST',
processData: false,
contentType: false,
complete: function( response ) {
response = response.responseJSON;
if ( ! response ) {
return;
}
if ( response.error && response.product_url ) {
window.location = response.product_url;
return;
}
// Redirect to cart option
if ( wc_add_to_cart_params.cart_redirect_after_add === 'yes' ) {
window.location = wc_add_to_cart_params.cart_url;
return;
}
var $thisbutton = form.find('.single_add_to_cart_button'); //
var $thisbutton = null; // don't want the 'View cart' button
// Trigger event so themes can refresh other areas.
$( document.body ).trigger( 'added_to_cart', [ response.fragments, response.cart_hash, $thisbutton ] );
// Remove existing notices
$( '.woocommerce-error, .woocommerce-message, .woocommerce-info' ).remove();
// Add new notices
form.closest('.product').before(response.fragments.notices_html)
form.unblock();
}
});
});
});
</script><?php
}
add_action( 'wp_footer', 'ace_product_page_ajax_add_to_cart_js' );
Add to cart handler:
/**
* Add to cart handler
*/
function ace_ajax_add_to_cart_handler() {
WC_Form_Handler::add_to_cart_action();
WC_AJAX::get_refreshed_fragments();
}
add_action( 'wc_ajax_ace_add_to_cart', 'ace_ajax_add_to_cart_handler' );
add_action( 'wc_ajax_nopriv_ace_add_to_cart', 'ace_ajax_add_to_cart_handler' );
// Remove WC Core add to cart handler to prevent double-add
remove_action( 'wp_loaded', array( 'WC_Form_Handler', 'add_to_cart_action' ), 20 );
Add fragments for notices:
/**
* Add fragments for notices
*/
function ace_ajax_add_to_cart_add_fragments( $fragments ) {
$all_notices = WC()->session->get( 'wc_notices', array() );
$notice_types = apply_filters( 'woocommerce_notice_types', array( 'error', 'success', 'notice' ) );
ob_start();
foreach ( $notice_types as $notice_type ) {
if ( wc_notice_count( $notice_type ) > 0 ) {
wc_get_template( "notices/{$notice_type}.php", array(
'messages' => array_filter( $all_notices[ $notice_type ] ),
) );
}
}
$fragments['notices_html'] = ob_get_clean();
wc_clear_notices();
return $fragments;
}
add_filter( 'woocommerce_add_to_cart_fragments', 'ace_ajax_add_to_cart_add_fragments' );
Try replacing in last snippet 'messages' => array_filter( ... with 'notices' => array_filter( ... and it should work.

create loadmore for Wordpress with ajax and custom post type?

I am having some loadmore issues with ajax. Who can help me.
I have code
<button class="load-more">More</button>
Function
add_action('wp_ajax_loadmore', 'get_post_loadmore');
add_action('wp_ajax_nopriv_loadmore', 'get_post_loadmore');
function get_post_loadmore() {
$offset = isset($_POST['offset']) ? (int)$_POST['offset'] : 0;
$getposts = new WP_query(); $getposts->query('post_type=event&post_status=publish&showposts=5&offset='.$offset);
global $wp_query; $wp_query->in_the_loop = true;
while ($getposts->have_posts()) : $getposts->the_post(); ?>
<?php do_action('postthumb1')?>
<?php endwhile; wp_reset_postdata();
die();
}
js
<script>
$(document).ready(function(){
var offset = 4;
$('.load-more1').click(function(event) {
$.ajax({
type : "post",
dataType : "html",
async: false,
url : '<?php echo admin_url('admin-ajax.php');?>',
data : {
action: "loadmore",
offset: offset,
},
beforeSend: function(){
},
success: function(response) {
$('.list-new').append(response);
offset = offset + 5;
},
error: function( jqXHR, textStatus, errorThrown ){
console.log( 'The following error occured: ' + textStatus, errorThrown );
}
});
});
});
</script>
Code working ok but, it load only post_type event. I want to set a variable that can be used for all custom post types.
I tried setting the variable but the code does not work. Does anyone who has experience with ajax can help me?
This will get you all custom post types on the site:
$args = array(
'public' => true,
'_builtin' => false,
);
$output = 'names'; // names or objects, note names is the default
$operator = 'and'; // 'and' or 'or'
$post_types = get_post_types( $args, $output, $operator );
$args = array(
'post_type' => $post_types,
'post_status' => 'publish',
'posts_per_page' => 5,
'offset' => $offset
);
$getpost = new WP_Query( $args );
If you're looking for a certain post_type passed in by the ajax call:
<script>
$(document).ready(function(){
var offset = 4;
$('.load-more1').click(function(event) {
$.ajax({
type : "post",
dataType : "html",
async: false,
url : '<?php echo admin_url('admin-ajax.php');?>',
data : {
action: "loadmore",
offset: offset,
posttype: posttype //Where ever you want to get this from
},
beforeSend: function(){
},
success: function(response) {
$('.list-new').append(response);
offset = offset + 5;
},
error: function( jqXHR, textStatus, errorThrown ){
console.log( 'The following error occured: ' + textStatus, errorThrown );
}
});
});
});
</script>
Function:
add_action('wp_ajax_loadmore', 'get_post_loadmore');
add_action('wp_ajax_nopriv_loadmore', 'get_post_loadmore');
function get_post_loadmore() {
$offset = isset($_POST['offset']) ? (int)$_POST['offset'] : 0;
$posttype = isset($_POST['posttype']) ? $_POST['posttype'] : 'post';
$args = array(
'post_type' => $posttype,
'post_status' => 'publish',
'posts_per_page' => 5,
'offset' => $offset
);
$getposts = new WP_query($args);
global $wp_query;
$wp_query->in_the_loop = true;
while ($getposts->have_posts()) : $getposts->the_post();
do_action('postthumb1');
endwhile;
wp_reset_postdata();
die();
}

Istotope ajax content load

I'm stuck implementing load next set of posts in WordPress with isotope masonry layout.
It's just not triggered for appended elements and I can't figure out why.
If someone could point me in right direction I would appreciate.
jQuery AJAX function
function load_content( args ) {
$container = $('#container-async');
$status = $('.status');
$.ajax({
url: ajax_url,
data: {
action: 'do_load_posts',
nonce: nonce,
args: args
},
type: 'post',
dataType: 'json',
success: function( data, textStatus, XMLHttpRequest ) {
$items = data.posts;
if ( args.action === 'filter') {
/**
* Replace items
*/
$container.imagesLoaded( function() {
$container.isotope({
itemSelector: '.grid-item',
percentPosition: true,
masonry: {
columnWidth: '.grid-sizer'
}
});
$container.html( $items ).isotope( 'appended', $items, function() {
console.log('inserted');
});
});
}
else {
/**
* Append items
*/
$container.imagesLoaded( function() {
$container.isotope({
itemSelector: '.grid-item',
percentPosition: true,
masonry: {
columnWidth: '.grid-sizer'
}
});
$container.append( $items ).isotope( 'appended', $items, function() {
console.log('appended');
});
});
}
},
error: function( MLHttpRequest, textStatus, errorThrown ) {
$status.toggleClass('active');
}
});
}
WordPress AJAX:
function ajax_do_load_posts() {
// Verify nonce
if( !isset( $_POST['nonce'] ) || !wp_verify_nonce( $_POST['nonce'], 'nonce' ) )
die('Permission denied');
$response = [
'status' => 500,
'posts' => 0,
];
$filter = $_POST['args'];
$type = get_post_type_object( $filter['type'] );
$args = [
'post_type' => sanitize_text_field($filter['type']),
'paged' => intval($filter['page']),
'posts_per_page' => $filter['qty'],
];
$qry = new WP_Query($args);
if ($qry->have_posts()) :
ob_start();
while($qry->have_posts()) : $qry->the_post(); ?>
<div class="grid-item col-xs-12 col-sm-6 col-md-4 col-lg-3">
<?php get_template_part('templates/loop', 'card' ); ?>
</div>
<?php endwhile;
$response = [
'status' => 200,
'posts' => ob_get_clean(),
];
endif;
wp_reset_query();
wp_reset_postdata();
die(json_encode($response));
}
add_action('wp_ajax_do_load_posts', 'ajax_do_load_posts');
add_action('wp_ajax_nopriv_do_load_posts', 'ajax_do_load_posts');
Items are inserted or appended into container but masonry is triggered only on items that are already there on page load.
I have googled around and tried various solutions but none of them work, neither with isotope or masonry jquery plugin.
I was able to fix my issue, and kind of looks like the problem is because I was using jQuery default append/insert methods.
I have switched to isotope methods and now things look fine.
So basically instead of
$container.html( $items ).isotope( 'appended', $items, function() {
console.log('inserted');
});
I am now using:
$grid.isotope('insert', jQuery($items));
It looks logical actually that isotope cannot know items are appended if I don't use isotopes append/insert method. And notice that I also wrapped $items inside jQuery.
Anyhow my working JS for same PHP function is:
function load_content( args ) {
$container = $('#container-async');
$status = $('.status');
$.ajax({
url: ajax_url,
data: {
action: 'do_load_posts',
nonce: nonce,
args: args
},
type: 'post',
dataType: 'json',
success: function( data, textStatus, XMLHttpRequest ) {
$items = data.posts;
var $grid = $('.masonry').imagesLoaded( function() {
$grid.isotope({
itemSelector: '.grid-item',
percentPosition: true,
masonry: {
columnWidth: '.grid-sizer'
}
});
if ( args.action === 'filter') {
$grid.isotope('remove', $('.grid-item'));
}
$grid.isotope('insert', jQuery($items));
});
$grid.on( 'layoutComplete', function( event, laidOutItems ) {
$container.removeClass(data.action);
});
},
error: function( MLHttpRequest, textStatus, errorThrown ) {
$status.toggleClass('active');
}
});
}

Cakephp 2.1 and Jquery UI autocomplete

Mission:
Implement autocomplete of departments(saved in departments table) in employee form field called department.
A user enters a few spellings of department name
That brings up list of the names matching departments
The user select one and that's it.
Platforms
CakePhp 2.1
Jquery UI Autocomplete(part of Jquery UI library version 1.8.18)
Database Model
Emplyee (id, first_name,last_name,department_id)
department(id,name)
so in my add.ctp file ajax call is something like
$( "#auto_complete" ).autocomplete({
source: function( request, response ) {
$.ajax({
url: "/employees/showDepartment",
dataType: "json",
data: {
featureClass: "P",
style: "full",
maxRows: 12,
name_startsWith: request.term
},
success: function( data ) {
alert("success--");
response( $.map( data, function( item ) {
//alert(item);
return {
label: item.name,
value: item.id
}
}));
}
});
},
minLength: 2,
select: function( event, ui ) {
log( ui.item ?
"Selected: " + ui.item.label :
"Nothing selected, input was " + this.value);
},
open: function() {
$( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
},
close: function() {
$( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
}
});
i have a action in my EmployeeController called show_depatment()
public function getAddress() {
$this->autoRender = false;// I do not want to make view against this action.
$this->log($this->params->query['name_startsWith'] , 'debug');
$str = $this->params->query['name_startsWith'];
$this->log($str, 'debug');
$this->layout = 'ajax';
$departments = $this->Employee->Department->find('all', array( 'recursive' => -1,
'conditions'=>array('Department.name LIKE'=>$str.'%'),
'fields'=>array('name', 'id')));
//$this->set('departments',$departments);
$this->log($departments, 'debug');
echo json_encode($departments);
}
I dont want show_department action to have any view so i have made $this->autoRender = false;
but it is not working as expected.
when i debug the response using firebug in response and HTLM section it shows
[{"Department":{"name":"Accounting","id":"4"}}] // when i type "acc" in input field
Question
How to make it to display in form field.
echo json_encode($departments); is it right method of sending response in json format?
when i alert in sucess part of ajax call (alert(item);) it gives error as "undefined"
i'm friend of fat Model and skinny Controller so my Controller action looks like this
public function getAddress()
{
if($this->RequestHandler->isAjax()) {
Configure::write('debug', 0);
$this->layout = 'ajax';
$this->autoRender = false;
echo json_encode($this->Employee->Department->getAddress($this->params['url']['term']));
exit;
}
}
and my Department model method:
public function getAddress($str)
{
$rs = array();
$search = $this->find('all', array(
'recursive' => -1,
'conditions'=>array('Department.name LIKE'=>$str.'%'),
'fields'=>array('name', 'id')
));
if (!empty($search))
{
//the jquery ui autocomplete requires object with label/value so we need to traverse the query results and create required array
foreach ($search as $key => $val)
{
$rs[] = array('label' => $val['Department']['name'],
'value' => $val['Department']['id']);
}
}
return $rs;
}
and finaly my view entry is like this:
$( "#auto_complete" ).autocomplete({
minLength: 2,
source: function( request, response ) {
var term = request.term;
if ( term in cache ) {
response( cache[ term ] );
return;
}
lastXhr = $.getJSON( "/employees/showDepartment", request, function( data, status, xhr ) {
cache[ term ] = data;
if ( xhr === lastXhr ) {
response( data );
}
});
}
});
hope this helps.

Resources