Real Time Comment System With Laravel And Vuejs
In this post we will give you information about Real Time Comment System With Laravel And Vuejs. Hear we will give you detail about Real Time Comment System With Laravel And VuejsAnd how to use it also give you demo for it if it is necessary.
Today, Laravelcode share sommething new and very usefull tutorials with every one. Realtime comment system built using laravel and vuejs. comment system required every website. so, we are created here comment system with some awesome functionality. when user comment and post it then instently comment show in the page.
In this tutorials we are create one sapareted comment module and in this comment module we are cover following functionality. after user register then they will be able to do all functionality or action.
NOTE : In this tutorials we are not adding some file like css, we are cover some basiv stuff in this tutorials. if you get woring code so, please download from my github account we are also add link here Download working code
- Add new comments
- Reply to comments
- Up and Down votes
- Mark spam comments
In this our tutorials for make comment system we are using following technologies :
- Bootstrap
- Loadash
- Vue-resource
- Laravel Mix
Now we are starting our comment system tutorials step by step.
Step : 1 Create comments table migration
First, we need to create comment table for stare all comment data and aslo span and comment voting data. so, create new one migration by following command.
php artisan make:migration comments
Now copy following migration code and past in your migration file.
Schema::create('comments', function (Blueprint $table) {
$table->increments('id');
$table->text('comment');
$table->integer('votes')->default(0);
$table->integer('spam')->default(0);
$table->integer('reply_id')->default(0);
$table->string('page_id')->default(0);
$table->integer('users_id');
$table->timestamps();
});
Schema::create('comment_user_vote', function (Blueprint $table) {
$table->integer('comment_id');
$table->integer('user_id');
$table->string('vote',11);
});
Schema::create('comment_spam', function (Blueprint $table) {
$table->integer('comment_id');
$table->integer('user_id');
});
Now run your migration file using following command
php artisan migrate
Step : 2 Create Auth for Comment System
Now, we are created laravel built-in auth system using following command
php artisan make:auth
Step : 3 Create Models for the Comment System
Now, we are created model for comments table by run followign command
php artisan make:model Comment
Then open your app/Comment.php file and put into it following code.
namespace App;
use IlluminateDatabaseEloquentModel;
class Comment extends Model
{
protected $fillable = ['comment','votes','spam','reply_id','page_id','users_id'];
protected $dates = ['created_at', 'updated_at'];
public function replies()
{
return $this->hasMany('AppComment','id','reply_id');
}
}
In above code we are define required fillable columns fields with $fillable and create one replies() method which has the one-many relationship with own.
Now create a model for comment_user_vote. Run the following command:
php artisan make:model CommentVote
Now open your app/CommentVote.php file and put into following code.
namespace App;
use IlluminateDatabaseEloquentModel;
class CommentVote extends Model
{
protected $fillable = ['comment_id','user_id','vote'];
protected $table = "comment_user_vote";
public $timestamps = false;
}
Now, create last one model for comment_spam table
php artisan make:model CommentSpam
Now open your app/CommentSpam.php file and put into following code.
namespace App;
use IlluminateDatabaseEloquentModel;
class CommentSpam extends Model
{
protected $fillable = ['comment_id','user_id'];
protected $table = "comment_spam";
public $timestamps = false;
}
Step : 4 Create the Routes for Comments
Now, we are creating following route for required in out comment system. open your routes/web.php and past following route in it.
Route::get('/{pageId}', function($pageId) {
return view('page',['pageId' => $pageId]);
});
// Route for index page
Route::get('comments/{pageId}', '[email protected]');
// Route for store comment
Route::post('comments', '[email protected]');
// Route for update comment
Route::post('comments/{commentId}/{type}', '[email protected]');
Step : 5 Create the Controller for Comment
Now, create controller for comment by run following command :
php artisan make:controller CommentController
After run this command then your controller file automatic generated in app/Http/Controllers/CommentController.php open it and place in it following code.
namespace AppHttpControllers;
use IlluminateHttpRequest;
use AppComment;
use AppCommentVote;
use AppCommentSpam;
class CommentController extends Controller
{
public function index($pageId)
{
//
$comments = Comment::where('page_id',$pageId)->get();
$commentsData = [];
foreach ($comments as $key) {
$user = User::find($key->users_id);
$name = $user->name;
$replies = $this->replies($key->id);
$photo = $user->first()->photo_url;
// dd($photo->photo_url);
$reply = 0;
$vote = 0;
$voteStatus = 0;
$spam = 0;
if(Auth::user()) {
$voteByUser = CommentVote::where('comment_id',$key->id)->where('user_id',Auth::user()->id)->first();
$spamComment = CommentSpam::where('comment_id',$key->id)->where('user_id',Auth::user()->id)->first();
if($voteByUser) {
$vote = 1;
$voteStatus = $voteByUser->vote;
}
if($spamComment) {
$spam = 1;
}
}
if(sizeof($replies) > 0) {
$reply = 1;
}
if(!$spam) {
array_push($commentsData,[
"name" => $name,
"photo_url" => (string)$photo,
"commentid" => $key->id,
"comment" => $key->comment,
"votes" => $key->votes,
"reply" => $reply,
"votedByUser" =>$vote,
"vote" =>$voteStatus,
"spam" => $spam,
"replies" => $replies,
"date" => $key->created_at->toDateTimeString()
]);
}
}
$collection = collect($commentsData);
return $collection->sortBy('votes');
}
protected function replies($commentId)
{
$comments = Comment::where('reply_id',$commentId)->get();
$replies = [];
foreach ($comments as $key) {
$user = User::find($key->users_id);
$name = $user->name;
$photo = $user->first()->photo_url;
$vote = 0;
$voteStatus = 0;
$spam = 0;
if(Auth::user()) {
$voteByUser = CommentVote::where('comment_id',$key->id)->where('user_id',Auth::user()->id)->first();
$spamComment = CommentSpam::where('comment_id',$key->id)->where('user_id',Auth::user()->id)->first();
if($voteByUser) {
$vote = 1;
$voteStatus = $voteByUser->vote;
}
if($spamComment) {
$spam = 1;
}
}
if(!$spam) {
array_push($replies,[
"name" => $name,
"photo_url" => $photo,
"commentid" => $key->id,
"comment" => $key->comment,
"votes" => $key->votes,
"votedByUser" => $vote,
"vote" => $voteStatus,
"spam" => $spam,
"date" => $key->created_at->toDateTimeString()
]);
}
$collection = collect($replies);
return $collection->sortBy('votes');
}
public function store(Request $request)
{
$this->validate($request, [
'comment' => 'required',
'reply_id' => 'filled',
'page_id' => 'filled',
'users_id' => 'required',
]);
$comment = Comment::create($request->all());
if($comment)
return [ "status" => "true","commentId" => $comment->id ];
}
public function update(Request $request, $commentId, $type)
{
if($type == "vote"){
$this->validate($request, [
'vote' => 'required',
'users_id' => 'required',
]);
$comments = Comment::find($commentId);
$data = [
"comment_id" => $commentId,
'vote' => $request->vote,
'user_id' => $request->users_id,
];
if($request->vote == "up"){
$comment = $comments->first();
$vote = $comment->votes;
$vote++;
$comments->votes = $vote;
$comments->save();
}
if($request->vote == "down"){
$comment = $comments->first();
$vote = $comment->votes;
$vote--;
$comments->votes = $vote;
$comments->save();
}
if(CommentVote::create($data))
return "true";
}
if($type == "spam") {
$this->validate($request, [
'users_id' => 'required',
]);
$comments = Comment::find($commentId);
$comment = $comments->first();
$spam = $comment->spam;
$spam++;
$comments->spam = $spam;
$comments->save();
$data = [
"comment_id" => $commentId,
'user_id' => $request->users_id,
];
if(CommentSpam::create($data))
return "true";
}
}
}
Step : 6 Comment Component Using VueJS
[ADDCODE]
Run following command for install all package.json file dependencies.
npm install
Now, we are required vue-resource so, run following command for it
npm install --save vue-resource
Now, go to the this path resources/assets/js/components and create one blank file Comments.vue. now leave it blank. and open your resources/assets/js/app.js and add following code.
Add the following line after require(‘./bootstrap’);
import VueResource from "vue-resource"
Now, Add the following line after window.Vue = require(‘vue’);
Vue.use(VueResource);
Vue.component('comment', require('./components/Comments.vue'));
Step : 6 Write Code For Comments.vue
We are already create Comments.vue file before but then we are not put any code in it so, open Comments.vue file and put into following templet code
<template>
<div >
<h1>Comments</h1>
<!-- From -->
<div v-if="user">
<!-- Comment Avatar -->
<div >
<img src="storage/commentbox.png">
</div>
<form name="form">
<div >
<textarea placeholder="Add comment..." required v-model="message"></textarea>
<span v-if="errorComment" style="color:red">{{errorComment}}</span>
</div>
<div >
<input placeholder="Email" type="text" disabled :value="user.name">
</div>
<div >
<input type="button" @click="saveComment" value="Add Comment">
</div>
</form>
</div>
<div v-else>
<!-- Comment Avatar -->
<div >
<img src="storage/commentbox.png">
</div>
<form name="form">
<div >
<a href="login">
<textarea placeholder="Add comment..." required></textarea>
</a>
</div>
</form>
</div>
<!-- Comments List -->
<div v-if="comments" v-for="(comment,index) in commentsData">
<!-- Comment -->
<div v-if="!spamComments[index] || !comment.spam" >
<!-- Comment Avatar -->
<div >
<img src="storage/comment.png">
</div>
<!-- Comment Box -->
<div >
<div >{{comment.comment}}</div>
<div >
<div >
<span >
<em>{{ comment.name}}</em>
</span>
<span >{{ comment.date}}</span>
</div>
<div >
<ul >
<li>Votes: {{comment.votes}}
<a v-if="!comment.votedByUser" v-on:click="voteComment(comment.commentid,'directcomment',index,0,'up')">Up Votes</a>
<a v-if="!comment.votedByUser" v-on:click="voteComment(comment.commentid,'directcomment',index,0,'down')">Down Votes</a>
</li>
<li>
<a v-on:click="spamComment(comment.commentId,'directcomment',index,0)">Spam</a>
</li>
<li>
<a v-on:click="openComment(index)">Reply</a>
</li>
</ul>
</div>
</div>
</div>=
<!-- From -->
<div v-if="commentBoxs[index]">
<!-- Comment Avatar -->
<div >
<img src="storage/comment.png">
</div>
<form name="form">
<div >
<textarea placeholder="Add comment..." required v-model="message"></textarea>
<span v-if="errorReply" style="color:red">{{errorReply}}</span>
</div>
<div >
<input placeholder="Email" type="text" :value="user.name">
</div>
<div >
<input type="button" v-on:click="replyComment(comment.commentid,index)" value="Add Comment">
</div>
</form>
</div>
<!-- Comment - Reply -->
<div v-if="comment.replies">
<div v-for="(replies,index2) in comment.replies">
<div v-if="!spamCommentsReply[index2] || !replies.spam" >
<!-- Comment Avatar -->
<div >
<img src="storage/comment.png">
</div>
<!-- Comment Box -->
<div style="background: grey;">
<div style="color: white">{{replies.comment}}</div>
<div >
<div >
<span >
{{replies.name}}
</span>
<span >{{replies.date}}</span>
</div>
<div >
<ul >
<li>Total votes: {{replies.votes}}
<a v-if="!replies.votedByUser" v-on:click="voteComment(replies.commentid,'replycomment',index,index2,'up')">Up Votes</a>
<a v-if="!replies.votedByUser" v-on:click="voteComment(comment.commentid,'replycomment',index,index2,'down')">Down Votes</a>
</a>
</li>
<li>
<a v-on:click="spamComment(replies.commentid,'replycomment',index,index2)">Spam</a>
</li>
<li>
<a v-on:click="replyCommentBox(index2)">Reply</a>
</li>
</ul>
</div>
</div>
</div>
<!-- From -->
<div v-if="replyCommentBoxs[index2]">
<!-- Comment Avatar -->
<div >
<img src="storage/comment.png">
</div>
<form name="form">
<div >
<textarea placeholder="Add comment..." required v-model="message"></textarea>
<span v-if="errorReply" style="color:red">{{errorReply}}</span>
</div>
<div >
<input placeholder="Email" type="text" :value="user.name">
</div>
<div >
<input type="button" v-on:click="replyComment(comment.commentid,index)" value="Add Comment">
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
Step : 6 Add Script For Comments.vue
Now add following script code in Comments.vue file after closing template tag.
<script>
var _ = require('lodash');
export default {
props: ['commentUrl'],
data() {
return {
comments: [],
commentreplies: [],
comments: 0,
commentBoxs: [],
message: null,
replyCommentBoxs: [],
commentsData: [],
viewcomment: [],
show: [],
spamCommentsReply: [],
spamComments: [],
errorComment: null,
errorReply: null,
user: window.user
}
},
http: {
headers: {
'X-CSRF-TOKEN': window.csrf
}
},
methods: {
fetchComments() {
this.$http.get('comments/' + this.commentUrl).then(res => {
this.commentData = res.data;
this.commentsData = _.orderBy(res.data, ['votes'], ['desc']);
this.comments = 1;
});
},
showComments(index) {
if (!this.viewcomment[index]) {
Vue.set(this.show, index, "hide");
Vue.set(this.viewcomment, index, 1);
} else {
Vue.set(this.show, index, "view");
Vue.set(this.viewcomment, index, 0);
}
},
openComment(index) {
if (this.user) {
if (this.commentBoxs[index]) {
Vue.set(this.commentBoxs, index, 0);
} else {
Vue.set(this.commentBoxs, index, 1);
}
}
},
replyCommentBox(index) {
if (this.user) {
if (this.replyCommentBoxs[index]) {
Vue.set(this.replyCommentBoxs, index, 0);
} else {
Vue.set(this.replyCommentBoxs, index, 1);
}
}
},
saveComment() {
if (this.message != null && this.message != ' ') {
this.errorComment = null;
this.$http.post('comments', {
page_id: this.commentUrl,
comment: this.message,
users_id: this.user.id
}).then(res => {
if (res.data.status) {
this.commentsData.push({
"commentid": res.data.commentId,
"name": this.user.name,
"comment": this.message,
"votes": 0,
"reply": 0,
"replies": []
});
this.message = null;
}
});
} else {
this.errorComment = "Please enter a comment to save";
}
},
replyComment(commentId, index) {
if (this.message != null && this.message != ' ') {
this.errorReply = null;
this.$http.post('comments', {
comment: this.message,
users_id: this.user.id,
reply_id: commentId
}).then(res => {
if (res.data.status) {
if (!this.commentsData[index].reply) {
this.commentsData[index].replies.push({
"commentid": res.data.commentId,
"name": this.user.name,
"comment": this.message,
"votes": 0
});
this.commentsData[index].reply = 1;
Vue.set(this.replyCommentBoxs, index, 0);
Vue.set(this.commentBoxs, index, 0);
} else {
this.commentsData[index].replies.push({
"commentid": res.data.commentId,
"name": this.user.name,
"comment": this.message,
"votes": 0
});
Vue.set(this.replyCommentBoxs, index, 0);
Vue.set(this.commentBoxs, index, 0);
}
this.message = null;
}
});
} else {
this.errorReply = "Please enter a comment to save";
}
},
voteComment(commentId, commentType, index, index2, voteType) {
if (this.user) {
this.$http.post('comments/' + commentId + '/vote', {
users_id: this.user.id,
vote: voteType
}).then(res => {
if (res.data) {
if (commentType == 'directcomment') {
if (voteType == 'up') {
this.commentsData[index].votes++;
} else if (voteType == 'down') {
this.commentsData[index].votes--;
}
} else if (commentType == 'replycomment') {
if (voteType == 'up') {
this.commentsData[index].replies[index2].votes++;
} else if (voteType == 'down') {
this.commentsData[index].replies[index2].votes--;
}
}
}
});
}
},
spamComment(commentId, commentType, index, index2) {
console.log("spam here");
if (this.user) {
this.$http.post('comments/' + commentId + '/spam', {
users_id: this.user.id,
}).then(res => {
if (commentType == 'directcomment') {
Vue.set(this.spamComments, index, 1);
Vue.set(this.viewcomment, index, 1);
} else if (commentType == 'replycomment') {
Vue.set(this.spamCommentsReply, index2, 1);
}
});
}
},
},
mounted() {
console.log("mounted");
this.fetchComments();
}
}
</script>
NOTE : In this tutorials we are not adding some file like css, we are cover some basiv stuff in this tutorials. if you get woring code so, please download from my github account we are also add link here Download working code
Now we are ready to run our example so run bellow command ro quick run:
php artisan serve
Now you can open bellow URL on your browser:
http://localhost:8000
If you face any problem then please write a comment or give some suggestions for improvement. Thanks…
Hope this code and post will helped you for implement Real Time Comment System With Laravel And Vuejs. if you need any help or any feedback give it in comment section or you have good idea about this post you can give it comment section. Your comment will help us for help you more and improve us. we will give you this type of more interesting post in featured also so, For more interesting post and code Keep reading our blogs