Revise Ajax Code (GIT: Lauren Gray) to work with Custom Loops - ajax

I have been using this code from Lauren Gray:
https://gist.github.com/graylaurenm/86daa4f23aa8749c0933f72133ac7106
on my Wordpress site, and it works really well for the homepage and archive loops - any that are built into the main wp_Query. However I have created a new custom WP_Query and the AJAX doesn't work, it says "no more articles found" on click of the button...
$loop = new WP_Query( array(
'post_type' => 'post',
'paged' => $paged,
'posts_per_page' => 10
) );
if ( $loop->have_posts() ) :
while ( $loop->have_posts() ) : $loop->the_post();
remove_action( 'genesis_entry_content', 'genesis_do_post_content' );
remove_action( 'genesis_entry_header', 'genesis_post_info', 12 );
remove_action( 'genesis_entry_content', 'genesis_do_post_image', 8 );
add_action( 'genesis_entry_header', 'genesis_do_post_image', 8 );
add_action('genesis_entry_header','add_play_button');
echo '<article class="' . $countClasses . implode( ' ', get_post_class() ) . '">'; // add column class
do_action( 'genesis_entry_header' );
echo '</article>';
endwhile;
if ( $loop->max_num_pages > 1 ) :
echo '<div class="load-more"><a class="load-more-button" id="'.$pageType.'"><i class="fa fa-caret-down" aria-hidden="true"></i> Load More</a></div>';
endif;
endif;
What edits do I need to make to her code so it works with a custom loop like above?

Related

How to set an ajax url in wordpress? I want to call it with datatables.net in server side processing mode

I want to set up an ajax url to use it with Datatables in wordpress. But I don't know how I would set up the corresponding url in wordpress. I guess its a rather easy task but don't know how to do it.
I found example code how to set up datatables server side processing in wordpress but I am struggling to put the following code in real life (how to create the corresponding FrontendConfig.ajaxurl in Wordpress? Or would it be better to create a wordpress json endpoint?)
jQuery
jQuery('#student_table').DataTable({
"bProcessing": true,
"serverSide": true,
"ajax":{
"url": FrontendConfig.ajaxurl+'?action=getStudentsFromExamIdAjax&exam_nounce=exam_nounce_data&exam_id=1',
type: "post",
}
});
Wordpress php
add_action('wp_ajax_getStudentsFromExamIdAjax', 'getStudentsFromExamIdAjax' );
add_action('wp_ajax_nopriv_getStudentsFromExamIdAjax', 'getStudentsFromExamIdAjax' );
function getStudentsFromExamIdAjax(){
if(empty($_GET['action']) || empty($_GET['exam_id'])){
wp_send_json_error( new \WP_Error( 'Bad Request' ) );
}
if(isset($_GET['exam_id']) && $_SERVER['REQUEST_METHOD'] === 'POST' && wp_verify_nonce( $_GET['exam_nounce'], 'exam_nounce_data' )):
$exam_id = (isset($_GET['exam_id'])) ? absint($_GET['exam_id']) : '';
/*# You can create a function to get the data here */
$students = getStudentsFromExamId($exam_id);
$tdata = [];
foreach ($students as $key => $value):
$tdata[$key][] = $value->roll_no;
$tdata[$key][] = $value->name;
$tdata[$key][] = $value->phone;
$tdata[$key][] = 'action here';
endforeach;
$total_records = count($tdata);
$json_data = array(
/* $_REQUEST['draw'] comes from the datatable, you can print to ensure that */
"draw" => intval( $_REQUEST['draw'] ),
"recordsTotal" => intval( $total_records ),
"recordsFiltered" => intval( $total_records ),
"data" => $tdata
);
echo json_encode($json_data);
endif;
wp_die();
}
You just need to set the following enqueue_style_and_scripts into your function.php file. You need to set wp_localize_script, check this link https://developer.wordpress.org/reference/functions/wp_localize_script/. Don't forget to change the code as per your coding requirement.
/*# Enqueue styles & scripts */
if( !function_exists('enqueue_style_and_scripts') ):
function enqueue_style_and_scripts(){
$version = wp_get_theme()->get('Version');
wp_enqueue_script(
'general_js',
get_stylesheet_directory_uri() . '/assets/js/general.js',
array('jquery'),
$version,
true
);
$frontendconfig = array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'is_user_logged_in' => is_user_logged_in(),
);
wp_localize_script( 'general_js', 'FrontendConfig', $frontendconfig );
}
add_action('wp_enqueue_scripts', 'enqueue_style_and_scripts');
endif;

ReferenceError: ajax_object is not defined when loading Wordpress post via Ajax

I've been trying to implement the recommendation by #SagiveSEO in this thread:
Proper way to load a single post via Ajax?
The idea: click a button and load a post via AJAX. The idea being that you'll have a tree of buttons to allow people to navigate quickly to useful content.
Unfortunately, it fails.
In the console I get the message "ReferenceError: ajax_object is not defined" which refers to the line "$.post(ajax_object.ajaxurl..."
What am I doing wrong?
Here's my HTML:
<button class="get_project" data-postid="3300">PROJECT NAME</button>
<div class="postcontainer"></div>
Here's my Javascript:
jQuery(function($){
$('.get_project').click(function() {
var postid = $(this).data('postid'); // Amended by #dingo_d
$.post(ajax_object.ajaxurl, {
action: 'my_load_ajax_content ',
postid: postid
}, function(data) {
var $response = $(data);
var postdata = $response.filter('#postdata').html();
$('.postcontainer').html(postdata);
});
})
//alert( "hello world" );
});
and here is the php from my functions.php file:
function my_load_ajax_content () {
$pid = intval($_POST['post_id']);
$the_query = new WP_Query(array('p' => $pid));
if ($the_query->have_posts()) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
$data = '
<div class="post-container">
<div id="project-content">
<h1 class="entry-title">'.get_the_title().'</h1>
<div class="entry-content">'.get_the_content().'</div>
</div>
</div>
';
}
}
else {
echo '<div id="postdata">'.__('Didnt find anything', THEME_NAME).'</div>';
}
wp_reset_postdata();
echo '<div id="postdata">'.$data.'</div>';
}
// Next two lines corrected - thanks #dingo_d
add_action ( 'wp_ajax_my_load_ajax_content', 'my_load_ajax_content' );
add_action ( 'wp_ajax_nopriv_my_load_ajax_content', 'my_load_ajax_content' );
Also required in functions.php within the script enqueuing function:
wp_enqueue_script( 'myajaxpostloader', get_template_directory_uri().'/js/ajax.js', array( 'jquery' ), '1.0', true );
wp_localize_script( 'myajaxpostloader', 'ajax_object', array(
'ajaxurl' => admin_url( 'admin-ajax.php' )
));
(note that my Javascript is saved as /js/ajax.js where /js/ is a subdirectory of the Wordpress theme).
You didn't localize your ajax object. In Twenty fifteen theme you'd do it like this - in functions.php you'd put
wp_localize_script( 'twentyfifteen-script', 'ajax_object', array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
));
Where your scripts are enqueued.
In your theme be sure to use proper handle - in stead of 'twentyfifteen-script' put the one where your ajax code is in. So if your ajax JavaScript is located in a file called custom.js, and you've enqueued that script with the handle custom_js, then you'd put
wp_localize_script( 'custom_js', 'ajax_object', array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
));
After you've enqueued that script. All in all in your functions.php you'd put something like this:
add_action('after_setup_theme', 'mytheme_theme_setup');
if ( ! function_exists( 'mytheme_theme_setup' ) ){
function mytheme_theme_setup(){
add_action( 'wp_enqueue_scripts', 'mytheme_scripts');
}
}
if ( ! function_exists( 'mytheme_scripts' ) ){
function mytheme_scripts() {
wp_enqueue_script( 'custom_js', get_template_directory_uri().'/js/custom.js', array( 'jquery'), '1.0.0', true );
wp_localize_script( 'custom_js', 'ajax_object', array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
));
}
}
Or at the very least look for such code and just place the localization there :)

AJAX + WMPL plugin + WOOCOMMERCE plugin. Can not translate the text in wordpress

I'm using WPML plugin and it works great in my theme except in an ajax.
This is my code:
ob_start();
wc_add_notice( __( 'Sorry, the total meals exceeds the limit.', 'woocommerce' ), "error" );
wc_get_template( 'content-subcription-plan.php' );
$woocommerce_order_review = ob_get_clean();
$data = array('fragments' => $woocommerce_order_review);
wp_send_json( $data );
die();
I mean the below code does'nt working.
__( 'Sorry, the total meals exceeds the limit.', 'woocommerce' )
Note: I try above code without ajax and it works great.
Thanks for your help!

Woocommerce - adding x number of products thru add-to-cart

has anyone been able to add multiple products of the same kind, with a click of add-to-cart button. I have enclosed a picture to show what I would like to build.
Objective: To be able to add multiples of a product to cart at once on my CATALOG page, NOT viewing product page.
This is what I want to build. Check ink.talentosoft.com, imagine, under the products, the "Details" link is to replace the number input, and "Add to Cart" to replace for the add cart button that can handle the number input
I have looked at the code for single product/add-to-cart/simple product, the problem is: the number input and add to cart button are enclosed in a form element. Due to wp code being spread out, I am unable to find the handler for this form. If the handler for the form is found, may I theoretically copy past the simple.php add multiples section, right into my catalog page?
I have looked at and tried to use hooks do_action( "woocommerce_simple_add_to_cart" ); to bring up the single.php file.
I want to ask about the woocommerce_add_to_cart_action() method in plugin/woocommerce/woocommerce-function.php, Can I directly call this method ( add a hook to this method ), How do I keep track of the number input so I know how many products the user wants in the cart?
If I make this change, will this neglect woo's AJAX functionality to add to cart? Of course depending on what stage of the add to cart transaction I am able to squeeze in to this event handler.
This solution helped me a lot.
Create this file inside your theme: woocommerce/loop/add-to-cart.php. And add the following code to it:
<?php
/**
* Custom Loop Add to Cart.
*
* Template with quantity.
*
* #author WooThemes
* #package WooCommerce/Templates
* #version 1.6.4
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly.
global $product;
?>
<?php if ( ! $product->is_in_stock() ) : ?>
<?php echo apply_filters( 'out_of_stock_add_to_cart_text', __( 'Read More', 'woocommerce' ) ); ?>
<?php else : ?>
<?php
$link = array(
'url' => '',
'label' => '',
'class' => ''
);
switch ( $product->product_type ) {
case "variable" :
$link['url'] = apply_filters( 'variable_add_to_cart_url', get_permalink( $product->id ) );
$link['label'] = apply_filters( 'variable_add_to_cart_text', __( 'Select options', 'woocommerce' ) );
break;
case "grouped" :
$link['url'] = apply_filters( 'grouped_add_to_cart_url', get_permalink( $product->id ) );
$link['label'] = apply_filters( 'grouped_add_to_cart_text', __( 'View options', 'woocommerce' ) );
break;
case "external" :
$link['url'] = apply_filters( 'external_add_to_cart_url', get_permalink( $product->id ) );
$link['label'] = apply_filters( 'external_add_to_cart_text', __( 'Read More', 'woocommerce' ) );
break;
default :
if ( $product->is_purchasable() ) {
$link['url'] = apply_filters( 'add_to_cart_url', esc_url( $product->add_to_cart_url() ) );
$link['label'] = apply_filters( 'add_to_cart_text', __( 'Add to cart', 'woocommerce' ) );
$link['class'] = apply_filters( 'add_to_cart_class', 'add_to_cart_button' );
} else {
$link['url'] = apply_filters( 'not_purchasable_url', get_permalink( $product->id ) );
$link['label'] = apply_filters( 'not_purchasable_text', __( 'Read More', 'woocommerce' ) );
}
break;
}
// If there is a simple product.
if ( $product->product_type == 'simple' ) {
?>
<form action="<?php echo esc_url( $product->add_to_cart_url() ); ?>" class="cart" method="post" enctype="multipart/form-data">
<?php
// Displays the quantity box.
woocommerce_quantity_input();
?>
<button type="submit" class="button alt"><?php echo $link['label']; ?></button>
</form>
<?php
} else {
echo apply_filters( 'woocommerce_loop_add_to_cart_link', sprintf('%s', esc_url( $link['url'] ), esc_attr( $product->id ), esc_attr( $product->get_sku() ), esc_attr( $link['class'] ), esc_attr( $product->product_type ), esc_html( $link['label'] ) ), $product, $link );
}
?>
<?php endif; ?>

Adding wp_editor inside a thickbox

I would like to add a wp_editor inside a modal dialog (thickbox) at frontend but only gets an empty editor with no buttons on in. (WordPress 3.5 and plugin development)
The wp_editor is attached via an ajax call...
It seems like some important javascripts is missing to the page.
Is it possible to preload editor scripts i WP in some way?
Here is a sample plugin to expose the problem (adds a edit link to every content):
<?php
/*
Plugin Name: ThickboxEditor
*/
$thickboxeditor = new ThickboxEditor();
class ThickboxEditor{
function __construct()
{
add_action( 'wp_print_styles', array( &$this, 'wp_print_styles' ) );
add_action( 'init', array( &$this, 'init' ) );
add_filter( 'the_content', array( &$this, 'the_content' ) );
add_action( 'wp_ajax_thickboxeditor', array( &$this, 'editor' ) );
add_action( 'wp_ajax_nopriv_thickboxeditor', array( &$this, 'editor' ) );
}
function the_content( $content ){
$content .= 'EDIT THICKBOXEDITOR';
return $content;
}
function editor(){
wp_editor( $this->postcontent, 'postcontent', array(
'media_buttons' => false,
'teeny' => false,
'textarea_rows' => '7',
'tinymce' => array( 'plugins' => 'inlinepopups, fullscreen, wordpress, wplink, wpdialogs' )
) );
die(0);
}
}
?>
UPDATE
Thanks to #danielauener one solution is to initialize mceAddControl. So here is a working sample of the same plugin:
<?php
/*
Plugin Name: ThickboxEditor
*/
$thickboxeditor = new ThickboxEditor();
class ThickboxEditor{
function __construct()
{
add_action( 'wp_print_styles', array( &$this, 'wp_print_styles' ) );
add_action( 'init', array( &$this, 'init' ) );
add_filter( 'the_content', array( &$this, 'the_content' ) );
add_action( 'wp_ajax_thickboxeditor', array( &$this, 'editor' ) );
add_action( 'wp_ajax_nopriv_thickboxeditor', array( &$this, 'editor' ) );
add_action( 'wp_footer', array( &$this, 'wp_footer' ) );
}
function wp_footer(){
echo '<!--';
wp_editor( '', 'invisible_editor_for_initialization' );
echo '-->';
}
function the_content( $content ){
$content .= 'EDIT THICKBOXEDITOR';
return $content;
}
function editor(){
wp_editor( '', 'postcontent', array(
'media_buttons' => false,
'teeny' => false,
'textarea_rows' => '7',
'tinymce' => array( 'plugins' => 'inlinepopups, fullscreen, wordpress, wplink, wpdialogs' )
) );
?>
<script language="javascript">
jQuery(document).ready(function(){
tinymce.execCommand('mceAddControl',true,'postcontent');
});
</script>
<?php
die(0);
}
}
?>
It would be really nice to skip the ugly wp_editor initialization :-)
Funny, that thickbox doesn't provides any callbacks. But as I mentioned on twitter, I would try a $.ajaxSuccess call to solve the ugly js-inject. Just add the following to one of your javascript files:
(function($) {
// gets called for every successful ajax call
$(document).ajaxSuccess( function(evt, request, settings) {
// make sure this call was from your thickbox
if ($('#your-thickbox-selector').length > 0) {
tinymce.execCommand('mceAddControl',true,'postcontent');
}
});
})( jQuery );
UPDATE: The ajaxSuccess method has to be assigned to an element, changed the code

Resources