Wordpress: get comments count via ajax - php

I'm using wpdiscuz plugin for comment-system.
But i have one trouble: if i add a comment, sure, that my <?php comments_number( $zero, $one, $more ); ?> is not updated.
I'm new to wordpress, and i need to know, what way is the best for adding dynamical comments count update?
For example checking comments count every 30sec, i can write it with jQuery: no problem.
But how can i access comments count via ajax, without huge amount of custom code? Is it real?

Using AJAX in WordPress is pretty easy, because WP has already built-in core functionality for handling AJAX requests. I had created tutorial on submitting form via AJAX in WP here. I believe that in your situation you would not submit form, but just want to repeatedly request to some action in server-side, where you will return comments count.
So create post ajax function with jQuery like this:
var data = {
// ... some data
'action' => 'get_comments_count', // This data 'action' is required
}
// I specified relative path to wordpress ajax handler file,
// but better way would be specify in your template via function admin_url('admin-ajax.php')
// and getting it in js file
$.post('/wp-admin/admin-ajax.php', data, function(data) {
alert('This is data returned from the server ' + data);
}, 'json');
Then in you functions.php, wrtie something like this:
add_action( 'wp_ajax_get_comments_count', 'get_comments_count' );
add_action( 'wp_ajax_nopriv_get_comments_count', 'get_comments_count' );
function get_comments_count() {
// A default response holder, which will have data for sending back to our js file
$response = array();
// ... Do fetching of comments count here, and store to $response
// Don't forget to exit at the end of processing
exit(json_encode($response));
}
And then repeatedly call ajax function in js file with setInterval or setTimeout.
This is a quick example, to understand more on how ajax in WordPress works, read the tutorial.
Hope it helps!

Related

Wordpress: Passing data to a page using Ajax

I am trying to pass data from an ajax call to a specific page of Wordpress.
Below is the code I am using:
jQuery.ajax({type: "POST",
url: 'single-member-page.php',
data:{ size: 'item' },
success: function(){
//alert(data);
jQuery('#display-member-size').text(data);
}
});
The script does not work for WP. I also inspected the page using the console and I get an error:
single-member-page.php" NOT FOUND
I am new to WP and I do not know how to pass data from an ajax call to a specific page.
#Daniel
You asked a very good question, before proceeding to solution we need to understand thumb rules of wordpress ajax.
Thumb Rules:
According to wordpress standards all the ajax request should come to "ajaxurl" in javascript. It actually contains the "wp-admin/admin-ajax.php" file path.
Example:
$.ajax({
url: ajaxurl,
data: {'action':'generateCptApiKey'},
success:function(data) {
console.log(data);
},
error: function(errorThrown){
console.log(errorThrown);
}
});
If you are doing some sutff in wp-admin dashboard section or related to wp-admin section like creating an option page in wp-admin dashboard area, than "ajaxurl" global variable will be always available there in javascript.
If case of this ajax request is initialized from front end page/post than you have to specify admin-ajax.php files path using following method and better if you localize this for front-end javascript,So it will be available in javascript variable like it is available in wp-admin dashboard section.
In order to achieve this we need to add few more lines of code.
Method:
Updated Example code front-end ajax call :
// Register the script
wp_register_script( 'ajaxsettings', 'path/to/ajaxsettings.js' );
// Localize the script with new data
$ajaxsettings = array(
'ajaxurl' => admin_url('admin-ajax.php')
);
wp_localize_script( 'ajaxsettings', 'ajaxsettings', $ajaxsettings );
// Enqueued script with localized data.
wp_enqueue_script( 'ajaxsettings' );
$.ajax({
url: ajaxsettings.ajaxurl,
data: {'action':'generateCptApiKey'},
success:function(data) {
console.log(data);
},
error: function(errorThrown){
console.log(errorThrown);
}
});
After this we need to write method to handle this ajax request and send output back to the ajax call.
For detecting ajax request call in wordpress they have two standard hooks, hooks are just events like when i send a ajax request, wordpress ajax related hook will trigger and i can call any function on that trigger.
So basically for handling ajax request below are two hooks:
wp_ajax_(action) : It handles request from authenticated / logged in users. (Used for back-end wp-admin dashboard related tasks )
wp_ajax_nopriv_(action) : It handles front-end unauthenticated requests.
(Used for front-end page/post ajax call related tasks )
Here (action) is the name of the method that you have to code in your current theme function.php file, and this method will handle this ajax request.
Examples:
Object oriented style:
add_action( 'wp_ajax_cleanResponseFiles', array($this, 'cleanResponseFiles'));
add_action( 'wp_ajax_nopriv_cleanResponseFiles', array($this, 'cleanResponseFiles'));
Note: Here "cleanResponseFiles" is Method of class that will handle ajax request. and $this is pointing current class object.
Procedural style:
add_action( 'wp_ajax_cleanResponseFiles', 'cleanResponseFiles');
add_action( 'wp_ajax_nopriv_cleanResponseFiles','cleanResponseFiles');
Note: Here "cleanResponseFiles" is function added in current theme function.php file and it will handle ajax request.
In this we are considering that ajax request can be made either from wp-admin dashboard or from front-end page/post.
Example ajax request handler method:
function cleanResponseFiles(){
echo "<pre>";
print_r($_POST);
echo "</pre>";
//Always use exit() in ajax request handler function end
exit();
}
Thumb Rule :
Always use exit() method in ajax request handler method, it's essential.
The best practice of sending ajax request is use Wordpress_nonce.
It's just for avoding CRSF (Cross site request forgery ) by adding Honeypot , A hidden input field with generated random key and at in request handler method it should be validated.
These are the methods that we can use for creating Wordepress nonce and verifying Wordpress nonce and ajax request handler or simple http request handler.
Wordpress Nonce Methods:
wp_create_nonce : Used for creating random key for sending in forms as a hidden field.
wp_verify_nonce : Used for verifying random key in request handler method.
I will attach a working example of wordpress ajax call ASAP in this comment.
Just a brief: All ajax post should be sent to admin-ajax.php Each request needs to supply at least one piece of data called action. Based on this action, the code in admin-ajax.php creates two hooks.
if the value of action is cusom_action, wp_ajax_custom_action and wp_ajax_nopriv_custom_ction are auto created. Check WordPress coddex. https://codex.wordpress.org/AJAX_in_Plugins
Refer this https://codex.wordpress.org/Plugin_API/Action_Reference/wp_ajax_(action)
Basically you create an action like wp_ajax_myaction, this you can define in your functions.php or somewhere where you seem fit. And then call it as shown in the example(Usage section) on the page.
EDIT:
Adding some code to help you understand
In your functions.php
add_action( 'wp_ajax_my_ajax', 'my_ajax' );
add_action('wp_ajax_nopriv_my_ajax', 'my_ajax');
function my_ajax() {
die( "Hello World" );
}
In your JS:
$.ajax({
url: "http://yoursite.com/wp-admin/admin-ajax.php",
data : {action : 'my_ajax'},
success: function( data ) {
alert( 'The code says ' + data);
}
})
Few things about the code:
This is just a quick and dirty code, mostly ripped off from the example just to show you how it will work.
The no_priv action is used for allowing unauthorized access(i.e to non-admin users as well)
The url is usually not hardcoded in the way shown in the example, people usually pass it to the script using admin_url( 'admin-ajax.php' )
The action, sent in the data determines which function should be called. (my_ajax in our case)
Let know if you still have issues.

How to add processing PHP file for AJAX requests in Joomla

I am trying to develop a form in Joomla. The basic problem is:
How can I alter the form select options depending on what the user has chosen before? I need to make several database requests, while the user fills the form. With AJAX, I will need a processing PHP file. Can someone tell me how to do this in Joomla, because with JCE File browser I can't add any.
Thank You!
Assuming you already know how to write a "normal" Joomla component that retrieves data from database and shows them in a page, here's the proposed solution.
In my example I will dynamically retrieve a list of "products" for the selected "category".
COMPONENT: the server part of the Ajax request
Let's say we use JSON to exchange data in the Ajax call.
Within every Joomla component, you can create a JSON view, creating a file view.json.php alongside the default view.html.php. That view will be used when you add "format=json" to your query string.
So you create these additional views that use the same model to get data, but output them as a JSON string. The JSON view is usually something very simple, like this:
public function display()
{
$this->products = $this->getModel()->getProducts();
echo json_encode($this->products);
}
You also need to add the "tmpl=component" so that the response only contains data from the component and not the rest of the Joomla page (like modules and such).
You should end up in a situation where you can put in the browser:
http://yoursite/index.php?option=mycomponent&view=products&format=json&tmpl=component
and you will get a JSON list of products.
Add filters to your request
Of course you only want products for the selected category so you should modify your "getProducts" model method to check for a querystring parameter like category=xyz.
The URL becomes
http://yoursite/index.php?option=mycomponent&view=products&category=1&format=json&tmpl=component
P.S. a more detailed discussion on how to implement the check is off topic, because it's not related to AJAX.
JQUERY: the client part of the AJAX request
Now that you have a component that accept requests via URL and provide a JSON response you can use jQuery to get new data each time the "category" select is changed:
var category_select = $('#category');
var product_select = $('#product');
var request = jQuery.ajax({
"url": 'index.php?option=mycomponents&view=products&tmpl=component&format=json&category=' + category_select.val()
"type": "GET"
}).done(function (result) {
result.each(function (product) {
var new_option = jQuery('<option/>', {
'value': product.id,
})
.text(product.name)
.appendTo(product_select);
});
})
This JS code should be added in the same page where you show your form.

How to display a 'live' count of total files uploaded?

I am looking to display the total number of files in a database. To clarify, say I had a website where people could upload pictures of their cars, and I wanted to display a live number of how many pictures there are, what would be the best way to do this? Javascript, php? A mix? I envision a div with a number saying "Total Pictures: x" and where x would be whatever the live total is. I plan on using MySQL to store all the data on the website. Is this even recommended to have something communicate with the server this much? Is there a name for displaying a live number? Thanks!
If you are thinking to use the AngularJS way, you could create a Poller service which polls every second (assuming your /counter.php returns json):
app.factory('Poller', function($http, $timeout) {
var data = { response: {}};
var poller = function() {
$http.get('/counter.php').then(function(r) {
data.response = r.data;
$timeout(poller, 1000);
});
};
poller();
return {
data: data
};
});
Then your controller:
app.controller('CounterCtrl', function(Poller, $scope){
$scope.counter = Poller.data;
});
And finally in your view:
{{counter.response}}
You can read more about $http
Set up a PHP script that queries the database and returns the total file upload count. After that, you can use JavaScript on the page to periodically call the server in a specified interval of time and fetch the count data from your PHP script. Using jQuery and GET, you can do something like this:
jQuery(function($){
setInterval(function(){
$.get( '/counter.php', function(fileUploadCount){
$('#counter').html( fileUploadCount );
});
},20000); // 20 seconds
});
In your HTML:
<p><span id='counter'>xx</span> files have been uploaded so far!</p>
Hope this helps!
How live do you want it to be? Just whenever someone updates the site it's going to have the new value or do you actually want it to update in near real-time?
If it's the latter you have to use Javascript against some kind of API that returns the amount of files in the database. I can't help you with that bit since you are using PHP, but it shouldn't be too hard. Just return some JSON looking something like
{ fileCount: 45020 }
Client-side you have a few options. You have the different javascript frameworks like AngularJS and EmberJS (and many more), as well as just 'plain old' javascript and frameworks like jQuery
The keyword is really AJAX, even if that is just a sort of buzzword for using javascript to make websites dynamic.
I am a fan of using AngularJS because it's easy, but I'll try to give you some pointers for using jQuery first. Note that I have not used jQuery in years now.
The jQuery way
jQuery has a function called jQuery.getJSON(), and according to the documentation you can use that function something like this:
// Assign handlers immediately after making the request,
// and remember the jqxhr object for this request
var jqxhr = $.getJSON( "http://example.com/api/fileCount.json")
.done(function(data) { console.log(data) })
.fail(function() { console.log( "error" ); })
.always(function() { console.log( "complete" ); });
So this means we can call an endpoint and fetch some data using jQuery.
Here is a link to a tutorial about the basics of jQuery by the way.
jQuery makes us able to do things like this:
<div id="divTest1"></div>
<script type="text/javascript">
$("#divTest1").text("Hello, world!");
</script>
When that is executed the div with id "divTest1" will contain the text 'Hello, world!'.
That sounds like something we could use here!
Javascript also has this really nice function called setTimeout(), which allows us to make it call a function later.
This describes how to use jQuery with setTimeout()
As you can see it also shows us jQuery.documentReady(), which is an event that fires when the website is finished loading, so it is a good place to put code we want executed.
The example below shows how to use jQuery to hide a div with id=div after 3 seconds.
jQuery(document).ready(function () {
setTimeout( "jQuery('#div').hide();",3000 ); //hide a div after 3 seconds
});
Combining these things you should be able to make a repeating call that fetches data from your server and then updates a div or another element with the data you have fetched.
Just create a function which uses jQuery.getJSON() to fetch data, and then at the bottom of that add a setTimeout call to run itself in X seconds (however often you want it to update).
In jQuery.documentReady() you call that function the first time the document loads.
And in the .done() bit of the getJSON() call you add the data you got from the server to your div with whatever html you want. I showed you how to use $("#divTest1").text(), but there is also a .html() which acts the same but you should use it to add html to a element.
The angular way would be to use AngularJS's $http to do the same thing, but I wouldn't recommend learning AngularJS until you have a bit of a better grasp on Javascript.
When you do though, I highly recommend it. It's a much better approach than using jQuery.
You can read about AngularJS here
I hope this helps!

Image wont change

I am trying to get the image links from 9gag (what also works) and when I click on a button the image changes to the next one. The basic problem is that it works only once. I can then switch between the 1st and the 2nd image, though. This should be pretty simple, but I ´ve got no clue where the error is, so thanks in advance to anyone bothering to look at this.
<?php
$index = 0
$html = file_get_contents("http://www.9gag.com");
preg_match_all( '|http://d24w6bsrhbeh9d\.cloudfront\.net/photo/.+?\.jpg|', $html, $gags);
?>
<script>
function nextImg(){
<?php $index++;?>
pic.src='<?php echo $gags[0][$index];?>';
}
function prevImg(){
<?php $index--;?>
pic.src='<?php echo $gags[0][$index];?>';
}
</script>
You can't increment your PHP variables after the page has loaded. You are trying to increment them client-side with JavaScript. You are going to need to call that PHP using AJAX if you want to do this without refreshing the page, and even then you'll want to increment a javascript variable to keep track of where you are.
EDIT: I went a little nuts creating an ajax routine using PHP and JavaScript, specifically the jQuery library, which you will need to link to for this to work. You may also need to modify parts of the script to work with what you're trying to accomplish, but this certainly is a guide for running your ajax app as you're hoping to.
Start by making a PHP file with this script:
<?php
// Set content header to json
header('Content-Type: application/json');
// Get the index from the AJAX
$index = $_GET['index'];
// Grab file contents & parse
$html = file_get_contents("http://www.9gag.com");
preg_match_all( '|http://d24w6bsrhbeh9d\.cloudfront\.net/photo/.+?\.jpg|', $html, $gags);
// Send filename back to AJAX script as JSON
echo json_encode(array($gags[0][$index]));
?>
Then, in your HTML, include this jQuery to complete AJAX calls to your PHP script, and update the DOM with the data from the PHP script.
<script>
$(function() {
'use strict';
// Initiate index variable
var index = 0;
// Load initial image
loadImage(index);
// Add click event to a button with class of next-btn
$('.next-btn').click(function(e) {
e.preventDefault();
// Increment index to get next image
index++;
// Run AJAX function to retrieve image
loadImage(index);
});
// Add click event to a button with class prev-btn
$('.prev-btn').click(function(e) {
e.preventDefault();
// Decrement the index if it isn't 0
if (index > 0) {
index--;
}
// Run AJAX function to retrieve image
loadImage(index);
});
});
function loadImage(index) {
'use strict';
$.ajax({
type: 'GET',
url: 'your-php-script.php', // Filepath to your PHP script
data: 'index='+index, // Index is passed through GET request
dataType: 'json', // Return JSON
success: function (data) { // If the php script succeeds
// Change img with class of pic's src
// to the filename retrieved from php
$('.pic').attr('src', data[0]);
}
});
}
</script>
Configuring this for your needs will require some serious PHP and jQuery/JavaScript knowledge, as some debugging will likely be needed. Good luck!
EDIT 2:
I uploaded the working (tested, it works) source files to my website if you want to download. Please accept answer and let me know you grabbed the files...
http://www.wedgewebdesign.com/files/ajax-image-loader.zip
#Eric basically has it right but didn't really go into detail if you aren't familiar with the model...
PHP is a server side language in that it does all its processing on the web host server and once it is complete sends a static result back to the user. This means, whatever you see after the page is loaded within PHP is there to stay, unless you do one of two things:
1) Send a new request -- You provide different parameters, the page re-executes its logic and returns a new result to the user
2) Execute some form of clientside Javascript. Javascript is different from PHP in that it executes on the client (not the server) so you don't necessarily have to send responses back to the server unless you need more information. Javascript and PHP can be combined to create AJAX calls which allow the client to make asynchronous calls to the webserver for more data without reloading the entire page. The Javascript handles re-drawing the new information or updating the page which can appear seamless to the user.
What you therefore need is one of those two options. Either you provide 'next'/'previous' links to the user and the page is loaded differently each time or you create an AJAX call that fetches the url of the next image and then loads it.
Try assigning a variable to $gags[0][$index]. Something like
$imgsrc = $gags[0][$index];
and then
pic.src='<?php echo $imgsrc; ?>';

AJAX calling a PHP code and getting a response every few minutes

I'm trying to create a very simple message board (author, text, and date written) that will auto-update every few moments to see if a new message has arrived, and if it has, auto load the latest message(s).
I'm proficient in PHP, but my knowledge in AJAX is lacking.
The way I see it, I would have to create a PHP file called get_messages.php that would connect to a database and get through a $_GET variable return all posts beyond date X, and then I would somehow through jquery call this PHP file every few minutes with $_GET=current time?
Does this sound correct?
How would I got about requesting and returning the data to the web page asynchronously?
You're pretty close, you'll need a PHP script that can query the database for your results. Next, you'll want to transfigure those results into an array, and json_encode() them:
$results = getMyResults();
/* Assume this produce the following Array:
Array(
"id" => "128","authorid" => "12","posttime" => "12:53pm",
"comment" => "I completely agree! Stackoverflow FTW!"
);
*/
print json_encode($results);
/* We'll end up with the following JSON:
{
{"id":"128"},{"authorid":"12"},{"posttime":"12:53pm"},
{"comment":"I completely agree! Stackoverflow FTW!"}
}
*/
Once these results are in JSON format, you can better handle them with javascript. Using jQuery's ajax functionality, we can do the following:
setInterval("update()", 10000); /* Call server every 10 seconds */
function update() {
$.get("serverScript.php", {}, function (response) {
/* 'response' is our JSON */
alert(response.comment);
}, "json");
}
Now that you've got your data within javascript ('response'), you are free to use the information from the server.
Ignore the ASP.NET stuff, this link is a good start:
http://www.aspcode.net/Timed-Ajax-calls-with-JQuery-and-ASPNET.aspx
What you're going to use is a javascript function called setTimeout, which asynchronously calls a javascript function on an interval. From there, jQuery has a fancy function called "load" that will load the results of an AJAX call into a DIV or whatever element you're looking for. There are also numerous other ways to get jQuery to do alter the DOM the way you'd like.
There are a hundred ways to do this, but I'd say avoid writing plain Javascript to save yourself the headache of cross-browser functionality when you can.
I suggest you go for the Simple AJAX Code-Kit (SACK) available on Google code.
I've been using it since before it was on Google code. It's very light and straightforward. It's one js file that you have to include. I've seen it being used in online browser games as well.
http://code.google.com/p/tw-sack/
Example for loading page contents from get_messages.php in a div (if you don't care about the page contents from get_messages.php, and simply want to call the php file, simple remove the ajax.element line):
<script type="text/javascript" src="tw-sack.js"></script>
<script>
var ajax = new sack();
ajax.method = "GET"; // Can also be set to POST
ajax.element = 'my_messages'; // Remove to make a simple "ping" type of request
ajax.requestFile = "get_messages.php";
ajax.setVar("user_name","bobby");
ajax.setVar("other_variables","hello world");
ajax.setVar("time",dateObject.getTime());
ajax.onCompleted = whenCompleted;
ajax.runAJAX();
function whenCompleted(){
alert('completed');
}
</script>
<div id="my_messages">Loading...</div>
You don't need to specify an "ajax.element" if you want to do a simple "ping" type of request and ignore the output of the php file. All you have to do to implement your requirements now is to use a "setTimeout" making the ajax calls.
There are also many other options like:
//ajax.onLoading = whenLoading;
//ajax.onLoaded = whenLoaded;
//ajax.onInteractive = whenInteractive;
No need to learn or include huge frameworks. And you'll get started in no time with tw-sack.

Categories