ajax jquery - duplicates content after load - javascript

Im making a blog list page, with Load More... and I have a problem. After click/load my whole content duplicates, but only the first page, doesnt duplicates, only the next pages.
If Im open a PHP file, where's my content generated, it shows only the current page what I need to load, for example only second page
There's the whole code
<?php
$paginationClass = 'otw_portfolio_manager-load-more-newspapper';
$paginationLoadMore = 'otw_portfolio_manager-load-more-newspapper';
$uniqueHash = wp_create_nonce("otw_pm_get_posts_nonce");
$listID = $this->listOptions['id'];
$maxPages = $otw_pm_posts->max_num_pages;
$paginationPageNo = (int) $_GET['page'];
//echo $paginationPageNo;
($paginationPageNo == 0) ? $page = 2 : $page = $paginationPageNo + 1;
$ajaxURL = admin_url( 'admin-ajax.php?action=get_pm_posts&post_id='. $listID .'&nonce='. $uniqueHash .'&page='. $page );
?>
<script>
$(document).ready(function(){
$(document).on('click','.show_more',function(){
var ID = $(this).attr('id');
$('.show_more').hide();
$('.loding').show();
$.ajax({
type:'POST',
url:'<?php echo $ajaxURL;?>',
data:'id='+ID,
success:function(html){
$('#show_more_main-'+ID).remove();
$(".row.works").append(html);
}
});
});
});
</script>
<!-- Load More Pagination -->
<div class="js-pagination_container">
<div class="<?php echo $paginationClass;?> hide">
<?php echo $page;?>
</div>
<div id="show_more_main-<?php echo $page;?>" class="<?php echo $paginationLoadMore;?> js-otw_portfolio_manager-load-more">
<?php _e('Load More', OTW_PML_TRANSLATION);?>
</div>
</div>
<?php?>
<!-- End Load More Pagination -->
</div>
Console report after 3 clicks on last "Load More"
13:36:29.502 jquery.min.js:4 XHR finished loading: GET ".../wp-admin/admin-ajax.php?action=get_pm_posts&post_id=1&nonce=7452b3a7e4&page=2".
13:36:31.842 jquery.min.js:4 XHR finished loading: POST ".../wp-admin/admin-ajax.php?action=get_pm_posts&post_id=1&nonce=7452b3a7e4&page=2".
13:36:31.905 jquery.min.js:4 XHR finished loading: GET ".../wp-admin/admin-ajax.php?action=get_pm_posts&post_id=1&nonce=7452b3a7e4&page=3".
13:36:31.936 jquery.min.js:4 XHR finished loading: POST ".../wp-admin/admin-ajax.php?action=get_pm_posts&post_id=1&nonce=7452b3a7e4&page=3".
13:36:36.333 jquery.min.js:4 XHR finished loading: GET ".../wp-admin/admin-ajax.php?action=get_pm_posts&post_id=1&nonce=7452b3a7e4&page=4".
13:36:36.380 jquery.min.js:4 XHR finished loading: POST ".../wp-admin/admin-ajax.php?action=get_pm_posts&post_id=1&nonce=7452b3a7e4&page=2".
13:36:36.585 jquery.min.js:4 XHR finished loading: POST ".../wp-admin/admin-ajax.php?action=get_pm_posts&post_id=1&nonce=7452b3a7e4&page=3".
13:36:36.929 jquery.min.js:4 XHR finished loading: POST ".../wp-admin/admin-ajax.php?action=get_pm_posts&post_id=1&nonce=7452b3a7e4&page=4".
13:36:36.982 jquery.min.js:4 XHR finished loading: POST ".../wp-admin/admin-ajax.php?action=get_pm_posts&post_id=1&nonce=7452b3a7e4&page=3".
I make this function in wordpress

Now I update and move my jquery away from php and now I see how much times it duplicates, and how it works
This is my template
<div class="row works">
<?php foreach( $otw_pm_posts->posts as $post ){
echo $this->buildInterfacePortfolioItems( $post ); ?>
<?php echo $this->getSocial( $post ); ?>
<?php echo $this->getDelimiter( $post ); ?>
<?php }?>
<?php
$paginationClass = 'otw_portfolio_manager-load-more-newspapper';
$paginationLoadMore = 'otw_portfolio_manager-load-more-newspapper';
$uniqueHash = wp_create_nonce("otw_pm_get_posts_nonce");
$listID = $this->listOptions['id'];
$maxPages = $otw_pm_posts->max_num_pages;
$paginationPageNo = (int) $_GET['page'];
//echo $paginationPageNo;
($paginationPageNo == 0) ? $page = 2 : $page = $paginationPageNo + 1;
$ajaxURL = admin_url( 'admin-ajax.php?action=get_pm_posts&post_id='. $listID .'&nonce='. $uniqueHash .'&page='. $page );
?>
<script>
$(document).ready(function(){
loadMore();
});
</script>
<!-- Load More Pagination -->
<div class="js-pagination_container">
<div class="<?php echo $paginationClass;?> hide">
<?php echo $page;?>
</div>
<div class="<?php echo $paginationLoadMore;?> js-otw_portfolio_manager-load-more">
<?php _e('Load More', OTW_PML_TRANSLATION);?>
</div>
</div>
<?php?>
<!-- End Load More Pagination -->
</div>
And this is my jQuery now
function loadMore(){
$(document).on('click','.show_more', 'a' ,function(e){
var post = $(this).attr('href');
$('.show_more').hide();
$('.loding').show();
$.ajax({
type:'POST',
url:post,
success:function(html){
$(html).insertAfter(".row.works");
}
});
e.stopPropagation();
});
}
And how its duplicates
1. click - shows second page
2. click - 3 times duplicate third page
3. click - n times duplicate fourth page and content with second and third page content

Related

Wordpress posts loop in AJAX refresh jQuery

I am trying to include a Wordpress posts loop in my AJAX refresh query, it should refresh every 10 seconds and pull the latest post from the Wordpress loop.
The query is working fine with plain HTML and returning the correct code and refreshing every 10 seconds as per jQuery below. However, when I add in the following code into test.php it returns no data.
<?php
query_posts( array ( 'category_name' => 'top-story', 'posts_per_page' => 1 ) );
while (have_posts()) : the_post(); ?>
<h1><b><?php the_title(); ?></b></h1>
<?php the_post_thumbnail('full', array('height' => '450px', 'class' => 'img-responsive')); ?>
<h2 class="main-subtitle"><?php the_field('job-title'); ?><h2>
<?php
endwhile; wp_reset_query();
?>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
sendRequest();
function sendRequest(){
$.ajax({
url: "/wp-content/themes/website.co.uk/test.php",
success:
function(data){
$('#autodata').html(data); //insert text of test.php into your div
},
complete: function() {
// Schedule the next request when the current one's complete
setInterval(sendRequest, 10000); // The interval set to 5 seconds
}
});
};
});
</script>

Speed up admin-ajax.php request in CPT filters

I have custom post types with JS filtering (based on category). There are simple html boxes + php code with ACF fields what display after select category.
Problem is it take 1 second or more to load all this html boxes so its not so smooth.
This is my JS (file filters.js):
(function($){
$(document).ready(function(){
$(document).on('click', '.js-filter-item > a', function(e){
e.preventDefault();
var category = $(this).data('category');
$.ajax({
url:wp_ajax.ajax_url,
data: { action: 'filter', category: category },
type: 'post',
success: function(result) {
$('.js-filter').html(result);
},
error: function(result) {
console.warn(result);
}
});
});
});
})(jQuery);
This is html of box what is loaded (file content_pozice_box.php)
<a href="<?php echo get_permalink();?>"><div class="vypis_pozice">
<div class="projekt-wrapper">
<?php
$projekt = get_field('projekt');
if( get_field('projekt') == 'XXX' ) {
?>
<div class="logo-wrapper">
<img src="https://YYY.png" class="logo-wrapper-img">
</div><?php
}
if( get_field('projekt') == 'YYY' ) {
?>
<div class="logo-wrapper">
<img src="https://XXX.png" class="logo-wrapper-img">
</div>
<?php
}
?>
<div class="field_projekt"><h3><?php the_field('projekt');?></h3><div class="field_AAA">AAA:
<?php if ( get_field( 'AAA' ) ): ?>
<?php the_field('AAA');?>
<?php else: // field_name returned false ?>
dohodou
<?php endif; // end of if field_name logic ?>
</div></div>
</div>
<?php the_title('<h3>', '</h3>'); ?>
<div class="location-wrapper">
<div class="BBB"><img src="https://BBB.png"><?php the_field('BBB');?></div>
<div class="CCC"><img src="https://CCC.png"><?php the_field('CCC');?></div>
</div>
<div class="DDD"><?php $cat = get_the_category(); echo $cat[0]->cat_name; ?></div><div class="job-button">Otevřít</div>
</div></a>
PHP (loading JS, Ajax, function)
function load_scripts() {
wp_enqueue_script('ajax', get_stylesheet_directory_uri() . '/' . 'template-parts/' .'filters.js', array('jquery'), NULL, true);
wp_localize_script('ajax' , 'wp_ajax',
array('ajax_url' => admin_url('admin-ajax.php'))
);
}
add_action( 'wp_enqueue_scripts', 'load_scripts');
add_action( 'wp_ajax_nopriv_filter', 'filter_ajax' );
add_action( 'wp_ajax_filter', 'filter_ajax' );
function filter_ajax() {
$category = $_POST['category'];
$args = array(
'post_type' => 'pozice',
'posts_per_page' => -1
);
if(isset($category)) {
$args['category__in'] = array($category);
}
$query = new WP_Query($args);
if($query->have_posts()) :
while($query->have_posts()) : $query->the_post();
include("content_pozice_box.php");
endwhile;
endif;
wp_reset_postdata();
die();
}
This won't solve all your problems but the first thing you should do is reduce your database calls. get_field('projekt') is called 4 times, which runs for every iteration of your loop. Oddly, you've already set it to a variable:
$projekt = get_field('projekt');
But you're not using the variable anywhere. So try replacing that first, so that it only runs once per iteration:
if ( $projekt ) {...}
While you're at it you should always escape output for security's sake. I.E. Instead of <h3><?php the_field('projekt');?></h3> replace with <h3><?php echo esc_html( $projekt ); ?></h3>.
To find other sources of inefficiencies you might try the Query Monitor plugin, as well as your browser's dev tools. I'm not sure about your JS. It looks fine to me but perhaps someone else here will notice something.

Need to fire an alert after "page load" on same page

This is a WordPress site and I have a template that renders all posts in a list at this URL http://www.example.com/articles. When the user clicks on a post title, it loads the content of the post using the same template but with a different URL http://www.example.com/articles/?article_id=298. What I cannot figure out is how to show an alert after the page loads the post content. I've tried setTimeout, $(document).ready, $(window).load, window.onload=funtion(), and now $(document).on("pagecontainerload",function().
JQuery/JavaScript
$('a.open-alert').click(function() {
$(document).on("pagecontainerload",function(){
window.alert('hey');
});
});
HTML
<?php
$tearsheet = get_query_var('article_id');
if($tearsheet != '') {
echo 'there is something here';
} else {
$args = array(
'post_type' => 'post',
'posts_per_page' => -1,
);
$query = new WP_Query( $args );
if($query->have_posts()) :
while($query->have_posts()) :
$query->the_post();
?>
<div>
<?php $id = get_the_ID(); ?>
<?php $title = get_the_title(); ?>
<a class="open-alert" href="<?php bloginfo('url'); echo '/find-articles/?article_id='.$id; ?>"><?php echo $title; ?></a>
</div>
<?php
endwhile;
endif;
}
?>
The click handler will never be executed, since the page unloads and a new page is loaded - the one in the link <a class="open-alert" href="<?php bloginfo.... You may have a return false in the onclick handler, but that would mean, the link will not be executed.
In order to do this dynamically, consider reloading only the container within that page, containing the post text by some Ajax functionality.

Load More Posts Ajax Button in WordPress

I've had a look through the old questions and tried many of the different methods that there seems to be to do this. The closest I've got to working is this one here: How to implement pagination on a custom WP_Query Ajax
I've tried everything and it just doesn't work. Absolutely nothing changes on the page. If you inspect the Load More Button and click it, the jQuery is making the Load More Button action as it changes from <a id="more_posts">Load More</a> to <a id="more_posts" disables="disabled">Load More</a> which even that doesn6't seem right to me anyway. It's not adding the posts, I think I'm missing something simple but for the life of me I can't work it out.
The code in my template file is:
<div id="ajax-posts" class="row">
<?php
$postsPerPage = 3;
$args = [
'post_type' => 'post',
'posts_per_page' => $postsPerPage,
'cat' => 1
];
$loop = new WP_Query($args);
while ($loop->have_posts()) : $loop->the_post(); ?>
<div class="small-12 large-4 columns">
<h1><?php the_title(); ?></h1>
<p><?php the_content(); ?></p>
</div>
<?php
endwhile;
echo '<a id="more_posts">Load More</a>';
wp_reset_postdata();
?>
</div>
The code in my functions file is:
function more_post_ajax(){
$offset = $_POST["offset"];
$ppp = $_POST["ppp"];
header("Content-Type: text/html");
$args = [
'suppress_filters' => true,
'post_type' => 'post',
'posts_per_page' => $ppp,
'cat' => 1,
'offset' => $offset,
];
$loop = new WP_Query($args);
while ($loop->have_posts()) { $loop->the_post();
the_content();
}
exit;
}
add_action('wp_ajax_nopriv_more_post_ajax', 'more_post_ajax');
add_action('wp_ajax_more_post_ajax', 'more_post_ajax');
And my jQuery in the footer is:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script type="text/javascript">
jQuery(document).ready( function($) {
var ajaxUrl = "<?php echo admin_url('admin-ajax.php')?>";
// What page we are on.
var page = 5;
// Post per page
var ppp = 3;
$("#more_posts").on("click", function() {
// When btn is pressed.
$("#more_posts").attr("disabled",true);
// Disable the button, temp.
$.post(ajaxUrl, {
action: "more_post_ajax",
offset: (page * ppp) + 1,
ppp: ppp
})
.success(function(posts) {
page++;
$("#ajax-posts").append(posts);
// CHANGE THIS!
$("#more_posts").attr("disabled", false);
});
});
});
</script>
Can anybody see something I'm missing or able to help?
UPDATE 24.04.2016.
I've created tutorial on my page https://madebydenis.com/ajax-load-posts-on-wordpress/ about implementing this on Twenty Sixteen theme, so feel free to check it out :)
EDIT
I've tested this on Twenty Fifteen and it's working, so it should be working for you.
In index.php (assuming that you want to show the posts on the main page, but this should work even if you put it in a page template) I put:
<div id="ajax-posts" class="row">
<?php
$postsPerPage = 3;
$args = array(
'post_type' => 'post',
'posts_per_page' => $postsPerPage,
'cat' => 8
);
$loop = new WP_Query($args);
while ($loop->have_posts()) : $loop->the_post();
?>
<div class="small-12 large-4 columns">
<h1><?php the_title(); ?></h1>
<p><?php the_content(); ?></p>
</div>
<?php
endwhile;
wp_reset_postdata();
?>
</div>
<div id="more_posts">Load More</div>
This will output 3 posts from category 8 (I had posts in that category, so I used it, you can use whatever you want to). You can even query the category you're in with
$cat_id = get_query_var('cat');
This will give you the category id to use in your query. You could put this in your loader (load more div), and pull with jQuery like
<div id="more_posts" data-category="<?php echo $cat_id; ?>">Load More</div>
And pull the category with
var cat = $('#more_posts').data('category');
But for now, you can leave this out.
Next in functions.php I added
wp_localize_script( 'twentyfifteen-script', 'ajax_posts', array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'noposts' => __('No older posts found', 'twentyfifteen'),
));
Right after the existing wp_localize_script. This will load WordPress own admin-ajax.php so that we can use it when we call it in our ajax call.
At the end of the functions.php file I added the function that will load your posts:
function more_post_ajax(){
$ppp = (isset($_POST["ppp"])) ? $_POST["ppp"] : 3;
$page = (isset($_POST['pageNumber'])) ? $_POST['pageNumber'] : 0;
header("Content-Type: text/html");
$args = array(
'suppress_filters' => true,
'post_type' => 'post',
'posts_per_page' => $ppp,
'cat' => 8,
'paged' => $page,
);
$loop = new WP_Query($args);
$out = '';
if ($loop -> have_posts()) : while ($loop -> have_posts()) : $loop -> the_post();
$out .= '<div class="small-12 large-4 columns">
<h1>'.get_the_title().'</h1>
<p>'.get_the_content().'</p>
</div>';
endwhile;
endif;
wp_reset_postdata();
die($out);
}
add_action('wp_ajax_nopriv_more_post_ajax', 'more_post_ajax');
add_action('wp_ajax_more_post_ajax', 'more_post_ajax');
Here I've added paged key in the array, so that the loop can keep track on what page you are when you load your posts.
If you've added your category in the loader, you'd add:
$cat = (isset($_POST['cat'])) ? $_POST['cat'] : '';
And instead of 8, you'd put $cat. This will be in the $_POST array, and you'll be able to use it in ajax.
Last part is the ajax itself. In functions.js I put inside the $(document).ready(); enviroment
var ppp = 3; // Post per page
var cat = 8;
var pageNumber = 1;
function load_posts(){
pageNumber++;
var str = '&cat=' + cat + '&pageNumber=' + pageNumber + '&ppp=' + ppp + '&action=more_post_ajax';
$.ajax({
type: "POST",
dataType: "html",
url: ajax_posts.ajaxurl,
data: str,
success: function(data){
var $data = $(data);
if($data.length){
$("#ajax-posts").append($data);
$("#more_posts").attr("disabled",false);
} else{
$("#more_posts").attr("disabled",true);
}
},
error : function(jqXHR, textStatus, errorThrown) {
$loader.html(jqXHR + " :: " + textStatus + " :: " + errorThrown);
}
});
return false;
}
$("#more_posts").on("click",function(){ // When btn is pressed.
$("#more_posts").attr("disabled",true); // Disable the button, temp.
load_posts();
});
Saved it, tested it, and it works :)
Images as proof (don't mind the shoddy styling, it was done quickly). Also post content is gibberish xD
UPDATE
For 'infinite load' instead on click event on the button (just make it invisible, with visibility: hidden;) you can try with
$(window).on('scroll', function () {
if ($(window).scrollTop() + $(window).height() >= $(document).height() - 100) {
load_posts();
}
});
This should run the load_posts() function when you're 100px from the bottom of the page. In the case of the tutorial on my site you can add a check to see if the posts are loading (to prevent firing of the ajax twice), and you can fire it when the scroll reaches the top of the footer
$(window).on('scroll', function(){
if($('body').scrollTop()+$(window).height() > $('footer').offset().top){
if(!($loader.hasClass('post_loading_loader') || $loader.hasClass('post_no_more_posts'))){
load_posts();
}
}
});
Now the only drawback in these cases is that you could never scroll to the value of $(document).height() - 100 or $('footer').offset().top for some reason. If that should happen, just increase the number where the scroll goes to.
You can easily check it by putting console.logs in your code and see in the inspector what they throw out
$(window).on('scroll', function () {
console.log($(window).scrollTop() + $(window).height());
console.log($(document).height() - 100);
if ($(window).scrollTop() + $(window).height() >= $(document).height() - 100) {
load_posts();
}
});
And just adjust accordingly ;)
Hope this helps :) If you have any questions just ask.
If I'm not using any category then how can I use this code? Actually, I want to use this code for custom post type.

Ajax PHP : cant go to new php page

The goal for my script is showing list of results from page1.php to page-listes.php
I incluse all method to my ajax call the sucess method was fired but page list not displayed
The ajax call code is :
$.ajax({
type: "POST",
url: "page-listes.php",
data: "name="+name+"&type="+type+"&region="+region+"&aliment="+aliment+"&periode="+periode,
dataType: 'html'
}) .done(function() {
alert( "success" );
})
fail(function() {
alert( "error" );
})
.always(function() {
alert( "complete" );
});
And the php result file is :
<?php
try {
$bdd = new PDO('mysql:charset=utf8;host=localhost;dbname=reps-bd', 'tchiko', 'tchiko');
} catch (Exception $e) {
die('Erreur : ' . $e->getMessage());
}
if (isset($_POST['name'])) {
$name = $_POST['name'];
$type = $_POST['type'];
$region = $_POST['region'];
$aliment = $_POST['aliment'];
$periode = $_POST['periode'];
// recuperer la liste
$repListe = $bdd->query('SELECT re.libelle libeller, t.libelle libellet, r.nom nom, r.nb_personne nb, r.image image, r.date date
FROM course r
INNER JOIN region re ON r.id_region=re.id_pays
INNER JOIN type t ON t.id_type=t.id_type
WHERE r.nom LIKE "%'.$name.'%"')
or die(print_r($bdd->errorInfo()));
?>
// some html code
<?php
while ($cours= $repListe->fetch()){
$fch_image = 'images/temp/'.$cours['image'].'.jpg';
?>
<div class="offer_list clearfix">
<div class="offer_item clearfix">
<div class="offer_image"><img src="<?php echo $fch_image;?>" alt=""></div>
<div class="offer_aside">
<h2><?php echo strtoupper($cours['nom']);?></h2>
<div class="offer_descr">
<p>...............</p>
</div>
<div class="offer_data">
<div class="offer_price"><?php echo $cours['diff'];?></div>
<span class="offer_miliage"><?php echo $cours['libellet'];?></span>
<span class="offer_regist"><?php echo $cours['date'];?></span>
</div>
</div>
</div>
</div>
<?php
}
$repListe->closeCursor();
}
?>
// some html code
I think the php file was correct,but nothing happen when i call it
The problem is that your code doesn't have any mechanism to actually append the response to your page. For instance, if you had a <p> with an id of myParagraph and want to append the response there, then your done callback should look like this:
.done(function(response){
$('#myParagraph').html(response);
});
Developer tools in your browser is your friend :-) Right click -> Inspect element (Chrome/Firefox), switch to console tab and you will see what is wrong. You forgot dot before fail() method :-)

Categories

Resources