Woocommerce create load more products with Ajax - php

I'm trying to create a function that loads more products using Ajax request in Woocommerce. My idea is to create a button "Load more Products" that replace the woocommerce pagination and that loads the 2nd the 3rd etc pages using ajax request. I've created the script that create the load more button with the ajax request and it works, but I'm trying to create a php function that retrive the rest of the products using the ajax request.
Below my code to create the load more button:
<?php
$max_num_pages = $wp_query->max_num_pages;
if ($max_num_pages > 1) {
$output .=
'<script type="text/javascript">
var page = 1,
max_page = '.$max_num_pages.'
jQuery(document).ready(function(){
jQuery(".woocommerce-pagination").hide();
jQuery("#woo_load_more").click(function(){
jQuery(this).hide();
jQuery("#spinner").show();
jQuery.ajax({
type: "POST",
url: "http://demo.ecquadro.com/transport/wp-admin/admin-ajax.php",
data: {
action: "wooPagination",
page: page+1,
per_page: 4,
},
success: function(data, textStatus, XMLHttpRequest){
page++;
jQuery(".prova").append(data);
jQuery("#spinner").hide();
if (max_page > page) {
jQuery("#woo_load_more").show();
}
},
error: function(MLHttpRequest, textStatus, errorThrown){
jQuery("#spinner").hide();
jQuery(this).show();
}
});
});
});
</script>
<div class="woo-products-load">
<span>'.__('Load More Posts', '').'</span>
<img id="spinner" src="'.get_template_directory_uri().'/img/loader.gif" style="display: none;">
</div>';
}
echo $output;
?>
Any idea how to create a function called "wooPagination" that load the rest of the pages?
Thanks in advance.

The esiest solution would probably be to use the infinite-scroll script. You find it here http://www.infinite-scroll.com/
Make you do not delete the normal pagination from the HTML-output and then hook it up as follows(you probably need to change the selectors to fit your site):
var infinite_scroll = {
loading: {
//img: "/img/loading-animation.gif",
msgText: '',
},
nextSelector: ".pagination a.next",
navSelector: ".pagination",
itemSelector: "#main-content ul.products .product-small",
contentSelector: "#main-content ul.products"
};
//Unbind load more on scroll
$(window).unbind('.infscr');
//
$("#load-more-button").click( function() {
$(document).trigger('retrieve.infscr');
});

Related

Refresh php embedded in html [duplicate]

What i want to do is, to show a message based on certain condition.
So, i will read the database after a given time continuously, and accordingly, show the message to the user.
But i want the message, to be updated only on a part of the page(lets say a DIV).
Any help would be appreciated !
Thanks !
This is possible using setInterval() and jQuery.load()
The below example will refresh a div with ID result with the content of another file every 5 seconds:
setInterval(function(){
$('#result').load('test.html');
}, 5000);
You need a ajax solution if you want to load data from your database and show it on your currently loaded page without page loading.
<script type="text/javascript" language="javascript" src=" JQUERY LIBRARY FILE PATH"></script>
<script type="text/javascript" language="javascript">
var init;
$(document).ready(function(){
init = window.setInterval('call()',5000);// 5000 is milisecond
});
function call(){
$.ajax({
url:'your server file name',
type:'post',
dataType:'html',
success:function(msg){
$('div#xyz').html(msg);// #xyz id of your div in which you want place result
},
error:function(){
alert('Error in loading...');
}
});
}
</script>
You can use setInterval if you want to make the request for content periodically and update the contents of your DIV with the AJAX response e.g.
setInterval(makeRequestAndPopulateDiv, "5000"); // 5 seconds
The setInterval() method will continue calling the function until clearInterval() is called.
If you are using a JS library you can update the DIV very easily e.g. in Prototype you can use replace on your div e.g.
$('yourDiv').replace('your new content');
I'm not suggesting that my method is the best, but what I generally do to deal with dynamic stuff that needs access to the database is the following method :
1- A server-side script that gets a message according to a given context, let's call it "contextmsg.php".
<?php
$ctx = intval($_POST["ctx"]);
$msg = getMessageFromDatabase($ctx); // get the message according to $ctx number
echo $msg;
?>
2- in your client-side page, with jquery :
var DIV_ID = "div-message";
var INTERVAL_IN_SECONDS = 5;
setInterval(function() {
updateMessage(currentContext)
}, INTERVAL_IN_SECONDS*1000);
function updateMessage(ctx) {
_e(DIV_ID).innerHTML = getMessage(ctx);
}
function getMessage(ctx) {
var msg = null;
$.ajax({
type: "post",
url: "contextmsg.php",
data: {
"ctx": ctx
},
success: function(data) {
msg = data.responseText;
},
dataType: "json"
});
return msg;
}
function _e(id) {
return document.getElementById(id);
}
Hope this helps :)

jQuery DataTables - Send URL parameter with Ajax call

I am using jQuery DataTables with Ajax-sourced data and pagination. Each time when I click pagination link the same Ajax URL is called.
How can I send different offset to load records accordingly?
You can do that with ajax.data option.
For example, to send current page number as URL parameter use the code below:
var table = $('#example').DataTable({
"ajax": {
"url": "/getNextPageData",
"data": function(){
var api = $('#example').DataTable();
// Get paging information
var info = api.page.info();
// Update URL
// Send page number as a parameter
api.ajax.url(
"/getNextPageData/" + (info.page + 1)
);
}
}
});
Try this code for pagination:
function pagination(val)
{
var pageurl='yourPage.php';
event.preventDefault();
$.ajax({
type:'post',
url:pageurl+'?page='+val,
success: function(data){
$('.element').html(data);
}});
}
Define this function in your pagination in html like that
<a onclick='pagination("<?= $i ?>")' href='yourPage.php?page=".$i."'><?=$i?> </a>

php ajax - auto refresh a div only if returned data is not empty

I am using bootstrap , php and mysql for an application . With this , whenever the users are logged in , the admin will post messages across to all users that will be displayed as an alert on the page . Below is my ajax code :
$.ajaxSetup(
{
cache: false,
beforeSend: function() {
$('#admin_message').hide();
},
complete: function() {
$('#admin_message').show();
},
success: function() {
$('#admin_message').show();
}
});
var $admin_msg = $("#admin_message");
$admin_msg.load("get_message_board.php");
var refreshId = setInterval(function()
{
$admin_msg.load('get_message_board.php');
}, 10000);
Below is my alert holder holder
<div class="alert alert-success" id="alert_holder">
<p id="admin_message" style="text-align: center;font-size: 20px"></p>
</div>
PHP SCRIPT :
include './functions.php';
$sql = "select message from msg_db3 where user_group ='".$_SESSION['active_user_group']."' order by id DESC LIMIT 1";
$temp = return_results($sql);
echo $temp['0']['message'];
Now i want to make sure that the div (with id='alert_holder') is hidden by default and shows up only if echo $temp['0']['message'] is not empty .If it is empty , it should be hidden . Also the transition is a bit odd since it shakes the entire page while bringing the alert up on the screen .
Please advice on the above .
THanks in advance .
EDIT:
can you try with normal Ajax?
$.ajax({
url: "get_message_board.php"
})
.done(function( data) {
console.log(data);
if(data.length>0){
$('#admin_message').show();
} else {
alert('not found');
}
}
});
Check your response length and show if it's not null
success: function(data) {
if(data.length>0){
$('#admin_message').show();
}
}
In php script you can change to
if(isset($temp['0'])){
echo $temp['0']['message'];
}
The main problem with your code is with
complete: function() {
$('#admin_message').show();
},
This code will show #admin_message every time when ajax is completed.
if you remove this unnecessary part you can make only my first change with if detection.

Loading query results into a Div

I have a div
<div id="loading"></div>
I then have some jQuery that loads in a page which is query heavy and therefore displays a spinner
<script>
$('#page1').click(function () {
// add loading image to div
$('#loading').html('<img src="loading.gif"> loading...');
// run ajax request
$.ajax({
type: "POST",
dataType: "html",
url: "client_reporting_01_data.php",
success: function (d) {
// replace div's content with returned data
$('#loading').html(d);
}
});
});
</script>
My trigger for this is a menu item:
<li id="page1" class = "<?php if($current_pgname == "client_reporting_01") echo 'active'; ?>">
C01: Summary Report
</li>
QUESTION:
I have multiple pages and multiple menu items
I'd like to be able to REuse the code I have here to pull the required pages back when the appropriate menu item is clicked.
So I would have another menu item
<li id="page2" class = "<?php if($current_pgname == "client_reporting_02") echo 'active'; ?>">
C02: Summary Report
</li>
and another page to call: client_reporting_02
I am just struggling with how to do the jquery to make this work
Somehow the jquery has to be able to read a page requested ie client_reporting_02_data.php
A further complication is how to actually move to that page and have it work. If say I am on pagexyz and i click the menu item for client_reporting_01 - it of course doesn not move there at present as a href="#"
One way to do it is bind to a class, rather than an id -
<script>
$('.reportLink').click(function () {
...
});
</script>
add the class, and a data attribute that holds the url (ie. data-url="client_reporting_01_data.php" and your li would now be
<li id="page1" class = "reportLink <?php if($current_pgname == "client_reporting_01") echo 'active'; ?>" data-url="client_reporting_01_data.php">
C01: Summary Report
</li>
now your script can be something like -
<script>
$('.reportLink').click(function () {
// add loading image to div
$('#loading').html('<img src="loading.gif"> loading...');
linkurl = $(this).data('url');//Probably want to sanitize and/or whitelist to prevent injection
// run ajax request
$.ajax({
type: "POST",
dataType: "html",
url: linkurl,
success: function (d) {
// replace div's content with returned data
$('#loading').html(d);
}
});
});
</script>
I am changing your already existing code slightly. If I understand what you want, the following will work. Instead of using the ID to call the function, add a generic class to all list items that are effected. I called it mypage here. Then there are a couple of ways to do it.
One way is: Instead of storing the url as is as a class, let the id tell you what url you are to look for. See the changes below for explanation:
// Generic class
$('.mypage').click(function () {
// add loading image to div
$('#loading').html('<img src="loading.gif"> loading...');
// if you need to include the 0 with child page numbers less than 10, you should change your ids accordingly.
var page=this.id.replace('page',''),
url= 'client_reporting_' + page + '_data.php';
// run ajax request
$.ajax({
type: "POST",
dataType: "html",
url: url,
success: function (d) {
// replace div's content with returned data
$('#loading').html(d);
}
});
});
Why not just delegate an event listener to the <ul> elements with an <a> anchor and put the url to load in the href? Like so;
HTML
<ul id="pages">
<li class = "reportLink <?php if($current_pgname == "client_reporting_01") echo 'active'; ?>">
C01: Summary Report
</li>
<li class = "reportLink <?php if($current_pgname == "client_reporting_02") echo 'active'; ?>">
Another Summary Report
</li>
</li>
Javascript
var $target = $('#loading');
$('#pages').on('click', 'a', function(event) {
event.preventDefault();
// add loading image to div
$target.html('<img src="loading.gif"> loading...');
$.ajax({
type: "POST",
dataType: "html",
url: this.href,
success: function (d) {
// replace div's content with returned data
$target.html(d);
}
});
});
You could even simplify your code by using .load like so:
Javascript - Simplifed version
var $target = $('#loading');
$('#pages').on('click', 'a', function(event) {
event.preventDefault();
$target
.html('<img src="loading.gif"> loading...')
.load(this.href);
});

Contents loaded with Ajax lose style

I've create a page that load 10 elements and at the bottom of the page I've placed the classic button "load more" to load 10 more elements.
The problem is with jQuery, the style given by :nth-child() property doesn't work for the next 10 elements and so on.
Is there a solution to solve this problem?
E.g.:
File main.js
$("#main_content > p:nth-child(3n+2)").addClass("small-product-wrapper");
$("#main_content > p:nth-child(3n+3)").addClass("small-product-wrapper");
File example.php
<script type="text/javascript">
$('#more_button').click(function(){
loaded_messages += 10;
$('#loading').ajaxSend(function() {
$("#loading").stop(true,true).fadeIn().delay(200).fadeOut();
});
var dati = "twitterpagination/get_messages/" + loaded_messages;
$.ajax({
url:'twitterpagination/get_messages/' + loaded_messages,
type: 'get',
data: dati,
cache: false,
success: function() {
$.get(dati, function(data){
$("#main_content").append(data);
});
if(loaded_messages >= num_messages - 10) {
$("#more_button").hide();
}
},
error: function() {
// do nothing
}
});
return false;
});
</script>
<div id="main">
<?php
foreach($latest_messages as $message) {
echo '<p>'.$message->message .'</p>';
}
?>
<div id="more_button">more</div>
</div>
File loaded by Ajax url:
<?php
foreach($latest_messages as $message) {
echo '<p>'.$message->message .'</p>';
}
?>
In the file loaded by ajax:
<?php
foreach($latest_messages as $message) {
echo '<p class="small-product-wrapper">'.$message->message .'</p>';
}
?>
Add the style to the returned P tag
You need to re-run those 2 jQuery lines right after the new html is added from your AJAX.
success: function() {
$.get(dati, function(data){
$("#main_content").append(data);
// here
$("#main_content > p:nth-child(3n+2)").addClass("small-product-wrapper");
$("#main_content > p:nth-child(3n+3)").addClass("small-product-wrapper");
});
}
This is because those original lines are run only once when the page is loaded.
When you load new content with Ajax the only way to have the style automatically assigned to it it's to give it a class and have that class style defined in css.
If you don't do that, you have to assign the style again in the callback function of the ajax call.

Categories