I’m trying to use AJAX and JSON inside CodeIgniter. I’ve never used either technologies before, but I’m starting to get a handle on it.
Here’s what I’m trying to achieve…
On my site, users can “love” other user’s posts on the forums. I would like the counter next to the love link to update automatically using AJAX and JSON.
Here is the relevant code:
VIEW:
A simple HTML link used for adding a love to the count.
<p><a href="#" class="love"><?php if ($post->love) { echo $post->love; } else { echo 0; } ?></a></p>
JQUERY:
Called when the link above is clicked. It calls the /ajax/love_forum_post function (code below) and passes through some data for the post and active user ID’s (2 and 1, which I’ve hard coded in for the time being). It then increments the count by 1 and switches the class.
$(document).ready(function(){
$('.love').click(function() {
$.ajax({
type: 'GET',
url: base_url + '/ajax/love_forum_post',
data: { post_id: 2, user_id: 1, ajax: 1 },
});
var num = parseInt($.trim($(this).html()));
$(this).html(++num).toggleClass('loved');
return false;
});
});
CONTROLLER:
The function called by Ajax when the link is clicked.
public function love_forum_post()
{
$post_id = $this->input->get('post_id');
$user_id = $this->input->get('user_id');
$is_ajax = $this->input->get('ajax');
if ($is_ajax)
{
$this->load->model('forums_model');
$total_loves = $this->forums_model->add_love($post_id, $user_id);
echo json_encode($total_loves);
}
// If someone tries to access the AJAX function directly.
else
{
redirect('', 'location');
}
MODEL:
And finally, the model function that is called to add a love to the database and return the new count, which is grabbed in the controller using JSON (I think).
function add_love($post_id, $user_id)
{
// Check that the user has not already loved the post.
$this->db->select('id');
$this->db->from('post_rating');
$this->db->where('post_id', $post_id);
$this->db->where('user_id', $user_id);
$query = $this->db->get();
// If they have not already loved the post.
if ( ! $query->num_rows() > 0)
{
$data = array(
'post_id' => $post_id,
'user_id' => $user_id,
'rating' => 1
);
// If a new love is added, return the new count.
if ($this->db->insert('post_rating', $data))
{
$this->db->select('id');
$this->db->from('post_rating');
$this->db->where('post_id', $post_id);
$this->db->where('user_id', $user_id);
$query = $this->db->get();
return $query->num_rows();
}
}
}
So…
- How would I fetch this new love count with JSON and make my counter show the new total?
- Is there anything else in my code that should be changed/improved?
- And finally, I am unable to use the POST method as I have CSRF protection enabled. How could I alter my code to allow the POST method to be used instead of GET? Or is the GET method okay for this?
Thanks, I’m still very green when it comes to PHP, CodeIgniter, AJAX and jQuery. Enjoying the challenge though!
- Tim.
1. How would I fetch this new love count with JSON and make my counter show the new total?
You’re (almost) already doing this. Your
json_encode()‘ed return value is an integer. Try this instead:Then, in your view…
2. Is there anything else in my code that should be changed/improved?
Rather than passing in an “ajax” parameter, use the
Inputclass to tell whether it’s an AJAX request…3. And finally, I am unable to use the POST method as I have CSRF protection enabled. How could I alter my code to allow the POST method to be used instead of GET? Or is the GET method okay for this?
I would strongly recommend using POST, rather than GET, as GET requests are assumed not to change any data. (Google “idempotence” for a better understanding of this concept…)
As for CSRF protection, I included a solution in the answer to your first question (see above).