Create comment system with jquery ajax and laravel 7

create-comment-system-with-jquery-ajax-and-laravel-7

Hello World, Welcome to ProjectsPlaza.com. Today we will learn how to create a comment system with jQuery Ajax and Laravel 7. In this tutorial, we will save comments and show instantly with the total comments count. This gonna be a very interesting tutorial for me as well as for you (I hope). I have divided this tutorial into the following parts:

  • Create a Post model
  • Create a Comment model
  • Define the hasMany relationship in Post Model
  • Add dummy data for post
  • Create a PostController and define a method for post list and post detail
  • Create templates for post and post detail with comments and show data
  • Setup route
  • Add a comment with jquery ajax and¬† show instantly


Create a Post model

This is our first step. In this step, we will create a post model where we will save and fetch our post data. We will create a post model with title and detail fields.

  • php artisan make: model Post -m
  • The above command creates Post.php in the app folder and migration in the database/migration folder. Open newly created migration file from database/migrations/….posts_table
  • Replace the following code in up method with previous code.
  • Schema::create('posts', function (Blueprint $table) {
                $table->id();
                $table->string('title');
                $table->text('detail')->nullable();
                $table->timestamps();
            });

    Here we have defined two fields title and detail. id and timestamp fields are default field comes in migration. The id field is our primary key and the timestamps field will create created_at and updated_at columns in the table. You can define a custom name for the primary key, but you also need to define the key name in the Model. For example protected $primaryKey='post_id';

  • php artisan migrate This command will create a posts table in the database.

Please ensure that you have correctly connected with database. If not, please add database connectivity in .env file.


Create a Comment model

We will create a comment model with post_id and comment_text fields.

  • Run php artisan make:model Comment -m
  • Open newly created migration file from database/migrations/…comments_table
  • Replace the following code in up method with previous code.
  • Schema::create('comments', function (Blueprint $table) {
                $table->id();
                $table->integer('post_id');
                $table->text('comment_text');
                $table->timestamps();
            });
  • Run php artisan migrate This will create a comments table in the database.

Define the hasMany relationship in Post model

In this step, we will define the hasMany relationship in the post model so that we can fetch comments of a specific post.

  • Open the app/Post.php file and add the following method.
  • function comments(){
        return $this->hasMany('App\Comment')->orderBy('id','desc');
    }

    We have also defined orderBy command so that we can fetch comments in descending order.


Till now, we have defined our post and comment model with the model relationship. In the next step, we will add some dummy data for the post.

Add dummy data for the post with faker library

  • Open database/factories/UserFactory.php
  • // Post
    $factory->define(App\Post::class, function (Faker $faker) {
        return [
            'title' => $faker->name,
            'detail' => $faker->text(500)
        ];
    });
  • Run php artisan tinker.
  • Run factory(App\Post::class,10)->create();
  • The above command will create 10 posts in the posts table.

Show posts with comments

In this section, we will create PostController, post list, post detail view, and set up the route.

PostController

Enter the following command to create the controller

  • php artisan make:controller PostController
  • Open app/Http/Controllers/PostController.php file and add the following two methods in it.
  • // Post list
        public function index(){
            $posts=\App\Post::all();
            return view('posts',['posts'=>$posts]);
        }
        // Post Detail
        public function detail(Request $request,$id){
            $post=\App\Post::find($id);
            return view('post-detail',['post'=>$post]);
        }

    The above two methods will render posts.blade.php and post-detail.blade.php template with posts data. In the next section, we will show the post data in the table format.

Create Views

  • Create posts-blade.php and post-detail.blade.php in resources/views folder.
  • Add the following code in posts.blade.php
  • <!DOCTYPE html>
    <html>
    <head>
        <title>Post List</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" />
    </head>
    <body>
        <div class="container mt-3">
            <table class="table table-bordered">
                <tr>
                    <th>Title</th>
                    <th>Detail</th>
                </tr>
                @isset($posts)
                    @foreach($posts as $post)
                    <tr>
                        <td><a href="{{ url('detail/'.$post->id) }}">{{ $post->title }}</a></td>
                        <td>{{ Str::words($post->detail,5,'...') }}</td>
                    </tr>
                    @endforeach
                @endisset
            </table>
        </div>
    </body>
    </html>

    I am using the bootstrap library for styling our page. Here we are fetching our posts data in a loop.

  • Add the following code in post-detail.blade.php
  • <!DOCTYPE html>
    <html>
    <head>
        <title>Post List</title>
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.0.0/animate.min.css" />
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" />
    </head>
    <body>
        <div class="container mt-3">
            <p class="mb-2"><a href="{{ url('/posts') }}"><< Post List</a></p>
            <h3 class="mb-2 pb-1 border-bottom">{{$post->title}}</h3>
            <p>{{$post->detail}}</p>
            <hr/>
            {{-- Post Comments --}}
            <div class="card mt-4">
                <h5 class="card-header">Comments <span class="comment-count float-right badge badge-info">{{ count($post->comments) }}</span></h5>
                <div class="card-body">
                    {{-- Add Comment --}}
                    <div class="add-comment mb-3">
                        @csrf
                        <textarea class="form-control comment" placeholder="Enter Comment"></textarea>
                        <button data-post="{{ $post->id }}" class="btn btn-dark btn-sm mt-2 save-comment">Submit</button>
                    </div>
                    <hr/>
                    {{-- List Start --}}
                    <div class="comments"> 
                        @if(count($post->comments)>0)
                            @foreach($post->comments as $comment)
                                <blockquote class="blockquote">
                                  <small class="mb-0">{{ $comment->comment_text }}</small>
                                </blockquote>
                                <hr/>
                            @endforeach
                        @else
                        <p class="no-comments">No Comments Yet</p>
                        @endif
                    </div>
                </div>
            </div>
            {{-- ## End Post Comments --}}
        </div>
    </body>
    </html>

Set up routes

  • Open routes/web.php file
  • Add the following code at the end
  • Route::get('posts', 'PostController@index');
    Route::get('detail/{id}', 'PostController@detail');

    Run your project with this command php artisan serve

  • Check the post list page at http://127.0.0.1:8000/posts URL.
  • Followings are our post list and post detail screen

 


Add a comment with jquery ajax show instantly

In this step, we will save comments when clicking on the save comment button with the animation effect and instantly show the total number of comments. For animation, I am using an animate CSS library.

  • Add the following code in post-detail.blade.php file before the close of body tag.
  • <script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script type="text/javascript">
    // Save Comment
    $(".save-comment").on('click',function(){
        var _comment=$(".comment").val();
        var _post=$(this).data('post');
        var vm=$(this);
        // Run Ajax
        $.ajax({
            url:"{{ url('save-comment') }}",
            type:"post",
            dataType:'json',
            data:{
                comment:_comment,
                post:_post,
                _token:"{{ csrf_token() }}"
            },
            beforeSend:function(){
                vm.text('Saving...').addClass('disabled');
            },
            success:function(res){
                var _html='<blockquote class="blockquote animate__animated animate__bounce">\
                <small class="mb-0">'+_comment+'</small>\
                </blockquote><hr/>';
                if(res.bool==true){
                    $(".comments").prepend(_html);
                    $(".comment").val('');
                    $(".comment-count").text($('blockquote').length);
                    $(".no-comments").hide();
                }
                vm.text('Save').removeClass('disabled');
            }   
        });
    });
    </script>

  • Add the following route in the route file.
  • Route::post('save-comment','PostController@save_comment');
  • Now add the save_comment method in PostController.
  • // Save Comment
        function save_comment(Request $request){
            $data=new \App\Comment;
            $data->post_id=$request->post;
            $data->comment_text=$request->comment;
            $data->save();
            return response()->json([
                'bool'=>true
            ]);
        }

Now run your project and add a comment, you will see that newly added comment append at the top with animation and counting will show in the blue box.

You can extend this comment system by adding user authentication.


I hope you have enjoyed this tutorial. Please add your feedback in the comment section.

Leave a Reply