How to add comments with AJAX in CakePHP


In today’s article we are going to create a very basic blog that allows people to create a post and posts comments on that post via AJAX.  We are going to keep it extremely basic and just focus on that actual AJAX functionality.

Ready? Let’s begin.  We are going to start by creating two database tables: posts and posts_comments. Also, I’ve got a very simple example of this same feature using Node.js tutorial.  Below is a sample create statement for the posts table:

[code]CREATE TABLE  `posts` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `title` varchar(255) NOT NULL,
  `summary` text NOT NULL,
  `body` text NOT NULL,
  `created` datetime default NULL,
  `modified` datetime default NULL,
  PRIMARY KEY  (`id`)

And now for the posts_comments table:

[code]CREATE TABLE  `posts_comments` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `post_id` int(10) unsigned NOT NULL,
  `name` varchar(100) NOT NULL,
  `comment` text NOT NULL,
  `created` datetime default NULL,
  `modified` datetime default NULL,
  PRIMARY KEY  (`id`)

To save myself at least three to ten hours of coding, I have used the bakery to bake my two models, two controllers, and eight view pages.  I won’t go into detail of using the bakery here as I recently covered it in detail during “How to create a CMS in CakePHP”.

Once you’re done with the bakery, you should have the following files created for you:

  • app/models/post.php
  • app/models/posts_comment.php
  • app/controllers/posts.php
  • app/controllers/posts_comments.php
  • app/views/posts/add.ctp
  • app/views/posts/edit.ctp
  • app/views/posts/index.ctp
  • app/views/posts/view.ctp
  • app/views/posts_comments/add.ctp
  • app/views/posts_comments/edit.ctp
  • app/views/posts_comments/index.ctp
  • app/views/posts_comments/view.ctp

Got all of those files?  Excellent, let’s move on.  The first thing we are going to want to do is update our posts_comments controller.  We want to update all of our functions to expect a post_id to be passed into it.  We also want to update our files to be prepared to perform our AJAX Javascript event functions.  Below is our updated app/controllers/posts_comments.php:

class PostsCommentsController extends AppController {

 var $name = ‘PostsComments’;
 var $helpers = array(‘Html’, ‘Form’, ‘Ajax’);
 var $components = array(‘RequestHandler’);

 function index($post_id = null) {
  if (!$post_id) {
   $this->Session->setFlash(__(‘Invalid PostsComment’, true));
   $this->redirect(array(‘controller’ => ‘posts’, ‘action’=>’index’));
  $this->set(‘post_id’, $post_id);
  $this->PostsComment->recursive = 0;
  $this->set(‘postsComments’, $this->paginate(‘PostsComment’, array(‘post_id’ => intval($post_id))));

 function add($post_id = null) {
  if (!$post_id && empty($this->data)) {
   $this->Session->setFlash(__(‘Invalid PostsComment’, true));
  if (!empty($this->data)) {
   if ($this->PostsComment->save($this->data)) {
    $this->Session->setFlash(__(‘The PostsComment has been saved’, true));
   } else {
    $this->Session->setFlash(__(‘The PostsComment could not be saved. Please, try again.’, true));
  } else {
   $this->data[‘PostsComment’][‘post_id’] = $post_id;

 function delete($id = null, $post_id = null) {
  if (!$id || !$post_id) {
   $this->Session->setFlash(__(‘Invalid id for PostsComment’, true));
  if ($this->PostsComment->del($id)) {
   $this->Session->setFlash(__(‘PostsComment deleted’, true));


The key things that we’ve done in here is:

  • Updated all functions to accept $post_id
  • Updated the functions to check that $post_id is passed in, if not display an error message
  • Update our paginate function in the index to add the condition of checking our post_id
  • In our add, update our $this->data to set the post_id automatically
  • None of our functions (except the index) do any redirects, they simply set our flash message
  • Added the RequestHandler component (allow AJAX pagination)
  • Added the Ajax helper

Next up, we’ve updated our app/views/posts_comments/index.ctp:

echo $javascript->link(‘prototype’);
echo $javascript->link(‘scriptaculous’);

echo $javascript->codeBlock(‘function updateCommentList(post_id) {
 new Ajax.Updater(“content”,”/CMS/posts_comments/index/1″, {asynchronous:true, evalScripts:true, requestHeaders:[“X-Update”, “content”]});
<div id=”comments”>
 <h2><?php __(‘PostsComments’);?></h2>
 $paginator->options(array(‘update’ => ‘content’, ‘indicator’ => ‘spinner’));
 echo $paginator->counter(array(
 ‘format’ => __(‘Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%’, true)
 foreach ($postsComments as $postsComment):
  <?php echo $postsComment[‘PostsComment’][‘name’]; ?>
  <?php echo $postsComment[‘PostsComment’][‘comment’]; ?>
  <?php echo $postsComment[‘PostsComment’][‘created’]; ?>
  <?php echo $ajax->link(__(‘Delete’, true), array(‘action’=>’delete’, $postsComment[‘PostsComment’][‘id’],

$postsComment[‘PostsComment’][‘post_id’]), array(‘complete’ => ‘updateCommentList(‘ . $post_id . ‘)’), sprintf(__(‘Are you sure you want to delete # %s?’,

true), $postsComment[‘PostsComment’][‘id’])); ?>
 <?php endforeach; ?>
 <div id=”newcomment”></div>
 <div class=”paging”>
  <?php echo $paginator->prev(‘<< ‘.__(‘previous’, true), array(), null, array(‘class’=>’disabled’));?>
  |  <?php echo $paginator->numbers();?>
  <?php echo $paginator->next(__(‘next’, true).’ >>’, array(), null, array(‘class’=>’disabled’));?>
 <div class=”actions”>
   <li><?php echo $ajax->link(__(‘New PostsComment’, true), ‘add/’ . $post_id, array(‘update’ => ‘newcomment’)); ?></li>

The first thing we did is stripped out our table listing and have just left straight echos of our content and delete link.  I’ll let you stylize it and make it look “pretty”.  At the top of our file, we have included two Javascript files.  Download Prototype ( and save it in app/webroot/js/prototype.js and download scriptaculous and save it in app/webroot/js/*.

We’ve only made three other important modifications:

  • Added $paginator->options() making our pagination done through AJAX
  • Updated our $html->link() for deleting to $ajax->link(), we’ve done the same for our New PostsComment link as well
  • For our delete link, we’ve told AJAX to call our JavaScript array function “updateCommentList()” when it’s done and we’ve told our new comment link to display the form in the <div> “newcomment”

Finally our add.ctp:

[code]<div class=”postsComments form”>
<?php echo $form->create(‘PostsComment’);?>
   <legend><?php __(‘Add PostsComment’);?></legend>
  echo $form->input(‘post_id’, array(‘type’ => ‘hidden’));
  echo $form->input(‘name’);
  echo $form->input(‘comment’);
echo $ajax->submit(‘Add’, array(‘url’ => ‘add’, ‘complete’ => ‘updateCommentList(‘ . $this->data[‘PostsComment’][‘post_id’] . ‘)’));
echo $form->end();

We’ve done two things here:

  • Updated our “post_id” to be hidden because we set it automatically for the user
  • We’ve changed our form->end to not be a submit button and added an ajax->submit.  Like the delete link, when we are done we tell it to call our “updateCommentList” Javascript function.

To test the following functionality, start by creating a new post.  With a new post created, we will assume the id is 1, go to <url>/posts_comments/index/1.  This will display a list of comments for this post.  Clicking the New PostsComment will AJAX our form on the page.  Enter in some data and click submit.  Your data will be submitted via AJAX and when it’s done our comment will automatically be displayed at the end of the list.  Clicking delete will remove the comment and redraw the list through AJAX.

That’s all for today’s article, I hope you enjoyed it.  If you have any suggestions, please let me know by adding a comment below.

About the author

  • Article Spinner

    server communication on your web site and in web applications. Article Spinner

  • Sofi

    Hi! i’m following your article. i can add and delete PostsComment with Ajax… But the Ajax.Updater is not working.. it doesn’t update my /posts_comments/index/ page.. Any ideas?

  • Sofi

    Finally solve my problem! i change this line:
    new Ajax.Updater(“content”,”/CMS/posts_comments/index/1″, {asynchronous:true, evalScripts:true, requestHeaders:[“X-Update”, “content”]});


    new Ajax.Updater(“content”,”//posts_comments/index/1″, {asynchronous:true, evalScripts:true, requestHeaders:[“X-Update”, “content”]});

  • archlord gold

    this is exactly the post I needed to see!

  • Nokadota

    I definitely think you’ve got a new regular reader. =D

  • 2moons gold

    good article , I added you in the ‘Liked’ category.. thanks for sharing the article!

  • NoviceChef


  • natural cures

    Hi! i’m following your article. i can add and delete PostsComment with Ajax… But the Ajax.Updater is not working.. it doesn’t update my /posts_comments/index/ page.. Any ideas

  • Челябинск такси

    Interestingly. Very much it was pleasant to me!

  • resume

    Finally, I found what I need … Thanks !!!

  • ricky

    I’m using $ajax->submit(…) to submit a form, but I can’t get any form data in action of the controller, anybody knows the reason??

  • reg cleaner reviews

    Thanks for such a nice article.It includes very informative information.

  • Balaji J H

    This post is too useful!
    Hope your blog contains more good posts anyway i have opted for your Blog Updates via FeedBurner!
    Ahead for more useful post from you!


  • watch weeds season 4

    Great post! This code really helped me out with a side project I’m working on!

  • Resume Writing Services

    My friend suggested me to visit your blog. Very well explained. I would like to say that it is very interesting to read your blog.

  • Stephen

    Thank you, didn’t have a clue, after trawling through tutorials, how to add comments that are associated with a particular post_id.
    However now have to figure out how to add comments on the same page as the posts view using requestaction and pretty urls aswell.

  • essay writing services

    Thanks for the tutorial, it’s great and so easy to understand. Your blog is amazing! Did you do all the features like the menu at the bottom yourself?

    • eldad


  • louis vuitton boulogne

    Your blog site is excellent. Say thanks to you truly for providing plenty of both useful and interesting advise. I will bookmark bookmark your website and will be absolutely coming back. Again, I truly appreciate all your work furthermore providing plenty of worthwhile info for the audience.

  • Pingback: 3 Best ‘Cakephp Comment Plugin & Informative Cakephp Comment Tutorials’ | Web Resource, Tech Tips and Softwares - Enfew

  • thesis writing service

    I don’t have anything else to include on to your article – you basically spelled everything out. great read!

  • Study Agent

    This is generally a wonderful website i should say,I enjoyed reading your articles. This is truly a great read for me. I have bookmarked it and I am looking forward to reading new articles. Keep up the good work.

  • sddssd

    Testing here. I hope this to be done as shown above.

    • ttlk


  • sddssd

    This comments down here seem to be sent without AJAX.

    Could you place a page so we can test what shown above, please?

  • Pingback: London goes to court to evict St. Paul’s protest | Channel 5 News

  • Pingback: ohui

  • Pingback: skin tag home removal

  • Pingback: online PC repair

  • Pingback: Goozle Zone

  • Pingback: bad credit loans

  • Pingback: ania quisumbing

  • Pingback: guayabera san antonio

  • Pingback: song downloads online

  • Pingback: youth and beauty

  • Pingback: one buck resume

  • Pingback: ultimate power profits

  • sad


By Jamie

My Books