How Linq to Objects Queries Work
9th April 2014How to Use The HTML5 Sectioning Elements
13th April 2014Starting with jQuery Ajax
When coding in standard JavaScript we are stuck using a method called XMLHttpRequest. The jQuery Ajax method is a more simplified way of handling this HTTP request, and you have a large index of documentation explaining each of the various options. I’ll be demonstrating two different styles of handling Ajax requests using different return values from PHP.
First I’ve created a new page, index.html, along with a related stylesheet. I won’t go over these codes so if you’re interested just download the project source. I also downloaded a local copy of jQuery along with a blank JavaScript file named ajax.js.
<div>
<h2>Someuser’s Profile</h2>
<h3>Joined Nov 1st, 2013 – <span id=”followercnt”>18</span> Followers</h3>
<div id=”followbtncontainer”><a href=”#” id=”followbtn”>Follow</a></div>
</div><!– @end .heading –>
….
<div id=”loadmorefollowers”>
<a href=”#pg1″ id=”morefllwrs”>Load more followers</a>
</div><!– @end #loadmorefollowers –>
Above I have combined two bits of code from my HTML which are located at different sections in the page. The anchor link using an ID of #followbtn will trigger an event callback when clicked. The same goes for the other anchor link, #morefllwrs. However these events will run different callback functions, and they both expect a different type of request using Ajax.
We can start by looking at the follow button example and how this behavior works.
Simple Ajax Actions
Many social networks like Twitter and Pinterest use Ajax to auto-update the page once you follow a new profile. This would obviously require connecting into a database for any live application, but for this example we can write the PHP as if we already connected into the database. First let’s take a peek at the JS codes
$(function(){
$(‘#followbtn’).on(‘click’, function(e){
e.preventDefault();
$(‘#followbtn’).fadeOut(300);
$.ajax({
url: ‘php/ajax-follow.php’,
type: ‘post’,
data: {‘action’: ‘follow’, ‘userid’: ‘11239528343’},
success: function(data, status) {
if(data == “ok”) {
$(‘#followbtncontainer’).html(‘<p><em>Following!</em></p>’);
var numfollowers = parseInt($(‘#followercnt’).html()) + 1;
$(‘#followercnt’).html(numfollowers);
}
},
error: function(xhr, desc, err) {
console.log(xhr);
console.log(“Details: ” + desc + “nError:” + err);
}
}); // end ajax call
});
Once the button is clicked we need to call e.preventDefault to stop the href value from loading a hash symbol into the address bar. Then I’m using .fadeOut() on the button to remove it from the page so that a user doesn’t try clicking twice. You will notice the Ajax request has a lot of different options – certainly not the whole catalog but enough to get us going. I’ll break them down individually so you can understand how the Ajax call works.
- url – the external URL to which we are sending the request. In this case I’ve organized all my Ajax PHP scripts into a folder and this one calls ajax-follow.php.
- type – the request method, POST or GET.
- data – what content are we passing to the PHP file? It should be organized like a JSON string with key:value pairs. So in PHP we can get the ‘action’ value by using$_POST[‘action’].
- success – if the Ajax request runs successfully then we either call a separate function or write the callback inline. I usually write the function right within Ajax because it’s often much easier.
- error – if the Ajax request fails, or somehow gets an error in the response, this alternative function is triggered. Usually helpful when debugging issues between JS and PHP.
I’ve structured this call so it could work for any simple common action we need to take. The ‘action’ found in our data string could be anything including unfollow, block, send a friend request, etc. The ‘userid’ is just made-up for my example but you’ll need this to be accurate when updating info in a database.
if($_POST[‘action’] == “follow”) {
/**
* we can pass any action like block,
follow, unfollow, send PM….
* if we get a ‘follow’ action then we could
take the user ID and create a SQL command
* but with no database, we can simply assume the
follow action has been completed and return ‘ok’
**/
echo “ok”;
}
So now inside ajax-follow.php we can see a very simple block of logic which checks for the action parameter. If we have it set to ‘follow’ then we could run some code that connects into the database and creates a new following relationship from the logged-in user and the current profile. At the end if it all works then we can return any value – I’ve chosen a string ‘ok’.
If you look back in the Ajax code you’ll see we run a logic check for if(data == “ok”). We only want to update the page with a success message if PHP has created the follow relationship. You might also notice we can update the number of followers on the page using a JavaScript methodparseInt().
JSON Return Data in PHP
For the second bit of Ajax we want to dynamically load a full list of followers on this user’s profile. We can see this person has 18 followers and only 10 are displaying by default. Each click will load 5 more followers until we have loaded them all. Since we know how Ajax connects into PHP let’s first start with the backend file ajax-followers.php.
header(“content-type:application/json”);
$pg1 = array(
array
(
‘username’ => ‘facingdown’,
‘profile_pic’ => ‘img/default-avatar.png’
),
array
(
‘username’ => ‘doggy_bag’,
‘profile_pic’ => ‘img/default-avatar.png’
),
array
(
‘username’ => ‘goingoutside’,
‘profile_pic’ => ‘img/default-avatar.png’
),
array
(
‘username’ => ‘redditdigg’,
‘profile_pic’ => ‘img/default-avatar.png’
),
array
(
‘username’ => ‘lots_of_pudding’,
‘profile_pic’ => ‘img/default-avatar.png’
),
‘nextpage’ => ‘#pg2’
);
PHP uses a special function called header() for setting properties of the page during rendering. In this case we don’t want the data returned as plaintext, but instead using application/json as JSON data. This is formatted in a way that jQuery can easily loop through each follower and then append them into the list.
Notice all I’ve created are simple PHP arrays that contain a profile username and their avatar. There is a $pg1 and $pg2 variable which indicates each of the pages we can load. All of this info could be pulled out of MySQL and would appear in similar syntax using something like mysqli_fetch_assoc().
if($_POST[‘page’] == ‘#pg1’)
echo json_encode($pg1);
if($_POST[‘page’] == ‘#pg2’)
echo json_encode($pg2);
exit();
After both arrays have been defined you’ll see this block of code at the bottom. We check which page is needed by calling upon a variable passed in through jQuery $_POST[‘page’]. Whether it’s page 1 or 2 we just need to json_encode() the array and simply echo it out onto the page(since our document type is application/json). PHP’s exit() is a friendly way of terminating the script when its sole purpose is meant for Ajax calls.
Loading Followers with Ajax
This last bit of code inside ajax.js is much more convoluted than the earlier block. But this is the reason why I wanted to introduce two distinct methods of PHP/Ajax because there is so much to learn about this topic.
$(‘body’).on(‘click’, ‘#morefllwrs’, function(e){
e.preventDefault();
var container = $(‘#loadmorefollowers’);
$(container).html(‘<img src=”img/loader.gif”>’);
var newhtml = ”;
Before even getting to the Ajax request let’s delve deeper into the actual event handler. Notice that my selector is targeting the page body and we pass the #morefllwrs button as a parameter to the .on() method. The purpose is to handle clicks on the same link which gets dynamically appended into the page. So right when the DOM loads jQuery will target the first link, and a user will click to load more followers, but in order to get another button to appear we need to add HTML onto the page using jQuery.
This means whenever the user clicks the button a second time, it normally wouldn’t register because it wasn’t part of the original DOM so jQuery doesn’t notice it. By using the whole body as our selector it will keep listening for the click event including new elements which are added to the page after loading. The other code inside just creates variables, and then we replace the button HTML with a loading gif so the user doesn’t click twice.
$.ajax({
url: ‘php/ajax-followers.php’,
type: ‘post’,
data: {‘page’: $(this).attr(‘href’)},
cache: false,
success: function(json) {
$.each(json, function(i, item) {
if(typeof item == ‘object’) {
newhtml += ‘<div> <a href=”#”>
<img src=”‘+item.profile_pic+'”> <h4>’
+item.username+'</h4></a></div>’;
}
else {
return false;
}
}) // end $.each() loop
if(json.nextpage != ‘end’) {
// if the nextpage is any other value other than end, we add the next page link
$(container).html(‘<a href=”‘+json.nextpage+'” id=”morefllwrs”>Load more followers</a>’);
} else {
$(container).html(‘<p></p>’);
}
$(‘#followers’).append(newhtml);
},
error: function(xhr, desc, err) {
console.log(xhr + “n” + err);
}
}); // end ajax call
Much of this syntax will look familiar because we are using the same jQuery function. In this case we need to call a different PHP file and we are passing a page value based on the button’s HREF attribute. It’s just one little trick we can use for dynamically-loaded page results. In fact, the biggest difference will be found inside the success function callback since we are using a type of jQuery .each() loop.
The response from PHP is held in a JS variable called json. We turn each array object inside the JSON string into a new variable called item. Since this is a very basic example the objects only have two keys – item.profile_pic and item.username. Any real-world example might include many more values.
One possibly confusing aspect of this loop is the very first logic check if(typeof item == ‘object’) used on each item. I’m doing this because each JSON response is comprised of profile objects, along with a string at the end called nextpage. When we get to this value we need to handle it differently because it won’t be added into the list, but instead it is used to build the new “Load more followers” button.
If this nextpage value is not ‘end’ then we know it contains some page value like #pg2. We can use this as the new button’s HREF attribute, which gets passed back into PHP to load the next set of followers. Once we hit the last JSON entry then we know there are no more pages. So we don’t append any new button and the loading gif is replaced instead by a single empty paragraph.