I'm relatively new to Wordpress. So this might not be the best approach, or even possible. With that said, I'm open to better solution.
I have a homepage that will display the latest 12 posts.
I want to make a button that when clicked will load the next 4.
What I have currently is this:
<?php query_posts('showposts=4&offset=12'); ?>
<?php while (have_posts()): the_post(); ?>
//some html tags
<?php endwhile; ?>
This will load me the detail of post 13-16.
I'm looking for a way where I can put this in a function and then call it through a jquery click() event where I can use a counter of some sort for the offset. something like
var offSetCounter = 12;
$(".btnLoadMore").click(function(){
//php function call
loadmore(offSetCounter);
offSetCounter += 4;
});
So next time i click the button the offSetCounter would be 16 and so on.
Thanks in Advance.
To run on Wordpress try this:
PHP:
add_action( 'wp_ajax_nopriv_show_next_posts', 'show_next_posts' );
function show_next_posts() {
$offset = $_POST['offset'];
$the_query = new new WP_Query( array( 'posts_per_page' => 4, 'offset' => $offset ) );
while ( $the_query->have_posts() ) {
$the_query->the_post();
echo '<div class="post_container">' . get_the_title() . '</div>';
}
wp_reset_postdata();
wp_die();
return;
}
add_action('wp_head','add_ajaxurl');
function add_ajaxurl() {
$ajaxurl = admin_url('admin-ajax.php');
echo '<script type="text/javascript">
var ajaxurl ='.$ajaxurl.';
</script>';
}
JS:
jQuery('.btnLoadMore').click(function(){
var offset = jQuery('.post_container').length();
var data = {
'action': 'show_next_posts',
'offset': offset
};
jQuery.post(ajaxurl, data, function( response ) {
console.log( response );
});
});
Related
My target is to take a page of an existent WP theme and customize a full width page, to make that every 1 seconds a MySQL SELECT query is reloaded and the results are shown.
Starting with this snippets I have made the following editing/new files:
template-fullwidth.php
functions.php
my.js (new file)
GetPostDate.php (new file)
What I have done
I started from the template-fullwidth.php of a theme and add the following code between the DIV of the post. The place where I wanted to show the results is between <div id="MaxPostDate"> tags.
</div><!-- .post -->
<!-- START CUSTOM PAGE CODE -->
<?php
if ( is_user_logged_in() ) {
// --- START IF USER LOGGED IN --- //
// Get the current user name and id
?>
<div id="MaxPostDate"></div>
<?php
// --- END IF USER LOGGED IN --- //
} else {
// --- START IF USER NOT LOGGED IN --- //
echo "<p>You have to log-in to see this content</p>";
// --- END IF USER NOT LOGGED IN --- //
}
?>
<div class="result"></div>
<!-- END CUSTOM PAGE CODE -->
<?php comments_template( '', true ); ?>
</div><!-- .posts -->
then I have edited the functions.php file of the theme adding this in the end:
function add_myjavascript(){
wp_enqueue_script( 'ajax-implementation.js', get_bloginfo('template_directory') . "/js/my.js", array( 'jquery' ) );
}
add_action( 'init', 'add_myjavascript' );
function MyAjaxFunction(){
//get the data from ajax() call
$TableContent = $wpdb->get_results("
SELECT MAX(`post_date`) AS MaxDate FROM wp_posts"
);
foreach($TableContent as $Content){echo "<h1>" . $Content->MaxDate . "</h1>";}
// Return the String
die($results);
}
// creating Ajax call for WordPress
add_action( 'wp_ajax_nopriv_MyAjaxFunction', 'MyAjaxFunction' );
add_action( 'wp_ajax_MyAjaxFunction', 'MyAjaxFunction' );
?>
Then, I have made this my.js in the js folder of the theme:
jQuery(document).ready(function refresh_div() {
jQuery.ajax({
url:'/MySite/wp-content/themes/hemingway/GetPostDate.php',
type:'POST',
success:function(results) {
jQuery(".result").html(results);
}
});
}
t = setInterval(refresh_div,1000););
And finally make another file GetPostDate.php
<?php
$TableContent = $wpdb->get_results("
SELECT MAX(`post_date`) AS MaxDate FROM wp_posts"
);
foreach($TableContent as $Content){echo "<h1>" . $Content->MaxDate . "</h1>";
?>
The problems
nothing appear inside the DIV id="MaxPostDate"
I have wrote two time the same query (SELECT MAX(post_date) AS MaxDate FROM wp_posts), I would be wrote just one time!
I think the problem is with your AJAX URL.
Execute your AJAX in footer.php like below:
jQuery.ajax({
url:'<?php echo admin_url('admin-ajax.php'); ?>',
type:'POST',
success:function(results) {
jQuery(".result").html(results);
}
});
then you don't need GetPostDate.php file either.
this my.js in the js folder of the theme
jQuery(document).ready(function refresh_div() {
jQuery.ajax({
url:'//MySite/mysite/wp-admin/admin-ajax.php',
action:'MyAjaxFunction',
type:'POST',
dataType:json,
success:function(results) {
jQuery(".result").html(results.result);
}
});
}
t = setInterval(refresh_div,1000););
the functions.php file of the theme adding this in the end:
function MyAjaxFunction(){
//get the data from ajax() call
$jsonresult = array();
$TableContent = $wpdb->get_results("
SELECT MAX(`post_date`) AS MaxDate FROM wp_posts"
);
foreach($TableContent as $Content){
$jsonresult['result'] = $Content->MaxDate
}
echo json_encode($jsonresult);
die();
}
// creating Ajax call for WordPress
add_action( 'wp_ajax_nopriv_MyAjaxFunction', 'MyAjaxFunction' );
add_action( 'wp_ajax_MyAjaxFunction', 'MyAjaxFunction' );
How can I pass a category name to new WP_Query when I click specific button with category name?
I've got this in my functions.php
<?php
add_action('wp_ajax_my_action', 'data_fetch');
add_action('wp_ajax_nopriv_my_action', 'data_fetch');
function data_fetch(){
$the_query = new WP_Query(array('post_type'=>'wydarzenie','posts_per_page'=>2, 'category_name'=>'2017'));
if($the_query->have_posts()):
while($the_query->have_posts()): $the_query->the_post(); ?>
<h2><?php the_title(); ?></h2>
<p><?php the_content(); ?></p>
<?php endwhile;
wp_reset_postdata();
endif;
die();
}
?>
and this on page with my default loop posts
function fetch(){
$.post('/PRACA/FundacjaWP/wp-admin/admin-ajax.php', {'action':'my_action'}, function(response){
$("#pick-event").html(response);
});
}
$(".show-specific-events").on("click", function(e){
e.preventDefault();
var category = $(this).text();
fetch();
});
I want load a new query with new loop based on category choose when I click a button. Now I set category '2017' but I want it to be dynamic.
Here we will learn how to use AJAX in WordPress. We will see how WordPress AJAX works as Beginner level. In this, we will pass a variable from JavaScript and pass it to WordPress theme function file. After doing the necessary process, we will pass the resulting content back to the JavaScript.
We are assuming that you already know how to enqueue JavaScript, etc.
JavaScript:
jQuery(document).ready(function($) {
$(".show-specific-events").on("click", function(e){
e.preventDefault();
var category = $(this).text();
// This does the ajax request
$.ajax({
url: codecanal_ajax_object.ajax_url,
data: {
'action':'codecanal_ajax_request',
'category_name' : category
},
success:function(data) {
// The OutPut after successfull receiveing content
console.log(data);
},
error: function(errorThrown){
console.log(errorThrown);
}
});
});
});
Implementation of Argument
If you are using in theme custom coding then put the below code in theme’s functions.php file
function codecanal_ajax_request() {
// The $_REQUEST contains all the data sent via ajax
if ( isset($_REQUEST) ) {
// You can check what data is received in the function by debugging it
// print_r($_REQUEST);
$category_name = $_REQUEST['category_name'];
$the_query = new WP_Query(array('post_type'=>'wydarzenie','posts_per_page'=>2, 'category_name'=> $category_name));
if($the_query->have_posts()):
while($the_query->have_posts()): $the_query->the_post(); ?>
<h2><?php the_title(); ?></h2>
<p><?php the_content(); ?></p>
<?php endwhile;
wp_reset_postdata();
endif;
die();
}
// To return to the front page, always finish after echoing the desired content.
die();
}
add_action( 'wp_ajax_codecanal_ajax_request', 'codecanal_ajax_request' );
// For allowing non-logged in users to use AJAX function
// add_action( 'wp_ajax_nopriv_codecanal_ajax_request', 'codecanal_ajax_request' );
/* We can define the AJAX url with using wp_localize_script */
function codecanal_ajax_enqueue() {
wp_localize_script( 'ajax-script', 'codecanal_ajax_object',
array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
}
add_action( 'wp_enqueue_scripts', 'codecanal_ajax_enqueue' );
Your code should look like this.
$args=array(
'posts_per_page' => 50,
'post_type' => 'my_custom_type'
'cat' => $cat_id,
);
$wp_query = new WP_Query( $args );
and when you use jquery at that time you need to pass category id on that.
I am following a Github code to add load more to ACF repeater field. I have 101 fields but load more not working. I tried to bebug too. Ajax response is 0. May be via ajax its not working. Do I have to add anything on functions.php file. Ajax response is 0.
<?php
/*
The code in this file is an example off the code that you would use in your template to
show the first X number of rows of a repeater
I'm sure there are more elegant ways to do the JavaScript, but what's here will work
*/
if (have_rows('gallery_work', 'option')) {
// set the id of the element to something unique
// this id will be needed by JS to append more content
$total = count(get_field('gallery_work', 'option'));
?>
<ul id="my-repeater-list-id">
<?php
$number = 2; // the number of rows to show
$count = 0; // a counter
while( have_rows('gallery_work', 'option') ):the_row();
//the_row();
$image_se_work = get_sub_field('image_se_work', 'option');
?>
<li><img src="<?php echo $image_se_work;?>" alt=""></li>
<?php
$count++;
if ($count == $number) {
// we've shown the number, break out of loop
break;
}
endwhile; // end while have rows
?>
</ul>
<!--
add a link to call the JS function to show more
you will need to format this link using
CSS if you want it to look like a button
this button needs to be outside the container holding the
items in the repeater field
-->
<a id="my-repeater-show-more-link" href="javascript:void(0);" onclick="my_repeater_show_more();"<?php
if ($total < $count) {
?> style="display: none;"<?php
}
?>>Show More</a>
<!--
The JS that will do the AJAX request
-->
<script type="text/javascript">
var my_repeater_field_post_id = <?php echo $post->ID; ?>;
var my_repeater_field_offset = <?php echo $number; ?>;
var my_repeater_field_nonce = '<?php echo wp_create_nonce('my_repeater_field_nonce'); ?>';
var my_repeater_ajax_url = '<?php echo admin_url('admin-ajax.php'); ?>';
var my_repeater_more = true;
function my_repeater_show_more() {
// make ajax request
$.post(
my_repeater_ajax_url, {
// this is the AJAX action we set up in PHP
'action': 'my_repeater_show_more',
'post_id': my_repeater_field_post_id,
'offset': my_repeater_field_offset,
'nonce': my_repeater_field_nonce
},
function (json) {
// add content to container
// this ID must match the containter
// you want to append content to
$('#my-repeater-list-id').append(json['content']);
// update offset
my_repeater_field_offset = json['offset'];
// see if there is more, if not then hide the more link
if (!json['more']) {
// this ID must match the id of the show more link
$('#my-repeater-show-more-link').css('display', 'none');
}
console.log(json);
},
'json'
);
}
console.log(<?php echo $total;?>);
</script>
<?php
} // end if have_rows
?>
You only have one file of a 2 file example here. This is the code that goes in the template. The PHP side of the this example is in the other PHP file https://github.com/Hube2/acf-dynamic-ajax-select-example/tree/master/repeater-ajax-load-more and includes the WP AJAX action that you need to add to your functions.php file.
I created a custom post type called Rubrics for WordPress that is only meant to be seen by users in the backend, so I created it with the argument 'public' => false which works fine.
In another post type (assignments), I generate a list of the custom rubrics post type with the following function:
<select id="ldrm-select-rubric">
<option data-id="0" value="default">Select a Rubric</option>
<?php
$args = array( 'post_type' => 'sfwd-rubrics', 'posts_per_page' => -1 );
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post(); ?>
<option data-id="<?php the_ID(); ?>"><?php the_title(); ?></option>
<?php endwhile; ?>
</select>
That works as well, so now I have a list of the Rubric posts appearing on the Edit page of all Assignments. I'm wondering how I can query the Rubric post content without loading all of them on to the page.
I understand I could just query the content using the above function, but I only want to load the content of the Rubric that is selected from the drop down once the user has selected it to prevent all of the other rubrics from loading as well. Any ideas on how that could be accomplished?
So if I'm correct in assuming that your current code you want to keep. That is to populate the drop down with the title of the rubrics. Whether you like it or not you have already queried the content. From a performance perspective it would be best to set some variables and use Javascript to display the correct one. The other option is to use AJAX and send the post id to the server and respond with the content for the rubric you want. I'll demo both here
Performant/simple load once
<?php
// instantiate some variables
$titles = array();
$contents = array();
// set our arrays
foreach (get_posts(array('post_type'=>'sfwd-rubrics','posts_per_page'=>-1)) as $post) {
$titles[$post->ID] = $post->title;
$content[$post->ID] = $post->content;
} ?>
<select id="ldrm-select-rubric">
<?php foreach ($titles as $id => $title): ?>
<option id="<?= $id ?>"><?= $title ?></option>
<?php endforeach; ?>
<select>
<?php // time to echo out the contents
foreach ($contents as $id => $content): ?>
<div id="<?= $id ?>"><?= $content ?></div>
<?php endforeach; ?>
<script type="text/javascript">
// assuming jQuery is being loaded
(function($) {
var $select = $('#ldrm-select-rubric');
$select.bind('change', function() {
$(this).find('option').css('display', 'none');
$('#' + $(this).val()).css('display', 'block');
});
$select.trigger('change');
})(jQuery);
</script>
More complicated and less performant example using AJAX
There are security features I won't bother in demoing. Here is a link to using AJAX in WordPress
<?php // somewhere in your php wordpress code
add_action('wp_ajax_rubric_content', function() {
echo get_post($_REQUEST['id'])->ID;
});
// Below the PHP code in your current question content
<div id="rubric-content"></div>
<script type="text/javascript">
(function($) {
$('#ldrm-select-rubric').bind('change', function() {
$.ajax({
type: 'GET',
url: ajaxurl,
data: {
action: 'rubric_content',
id: $(this).val(),
},
success: function(resp) {
$('#rubric-content').html(resp);
}
});
});
})(jQuery);
</script>
WARNING: I didn't test the code above, but that's generally how WP AJAX works. You'll need to add a ton of validation in your server code. I strongly recommend the former example as it's simpler, more performant (less queries), and more secure.
Is it possible to count how many times a certain link in post has been clicked?
(for example purpose, let's say that the certain link has an ID named 'bla')
<a id="bla" href="#">download</a>
I got a feeling it should be possible by using custom-fields/post-meta (to keep the count), just like the ever-so-popular 'visitor count' trick. Unfortunately, I'm rather clueless about PHPs.
It could be done with ajax call that updates post meta field before the link is followed. Example below registers ajax action for users that are not logged in, and increases link_click_counter custom field by 1 on each click. Link must have id attribute countable_link. This is a basic example that works for only one link in post. To use it as a plugin create file like wp-content/plugins/click-counter /click-counter.php and copy-paste example code, or put the code in functions.php inside theme folder. First time the link is clicked, new custom field link_click_counter will be created for that post, and there you can track how many clicks link has.
HTML:
<a id="countable_link" href="#">download</a>
PHP:
<?php
/*
Plugin Name: Link Clicks Counter
*/
if ( is_admin() ) add_action( 'wp_ajax_nopriv_link_click_counter', 'link_click_counter' );
function link_click_counter() {
if ( isset( $_POST['nonce'] ) && isset( $_POST['post_id'] ) && wp_verify_nonce( $_POST['nonce'], 'link_click_counter_' . $_POST['post_id'] ) ) {
$count = get_post_meta( $_POST['post_id'], 'link_click_counter', true );
update_post_meta( $_POST['post_id'], 'link_click_counter', ( $count === '' ? 1 : $count + 1 ) );
}
exit();
}
add_action( 'wp_head', 'link_click_head' );
function link_click_head() {
global $post;
if( isset( $post->ID ) ) {
?>
<script type="text/javascript" >
jQuery(function ($) {
var ajax_options = {
action: 'link_click_counter',
nonce: '<?php echo wp_create_nonce( 'link_click_counter_' . $post->ID ); ?>',
ajaxurl: '<?php echo admin_url( 'admin-ajax.php' ); ?>',
post_id: '<?php echo $post->ID; ?>'
};
$( '#countable_link' ).on( 'click', function() {
var self = $( this );
$.post( ajax_options.ajaxurl, ajax_options, function() {
window.location.href = self.attr( "href" );
});
return false;
});
});
</script>
<?php
}
}
?>
One possible way is to redirect all through a common PHP gateway and from there, redirect to the original page you wanted to redirect using Header('Location: yourpage.html');
In the gateway PHP page count the number by incrementing a saved value by 1.