Laravel 5.5 for beginners: create like and deslike systeme using Ajax 2018 - BTS Au Maroc

samedi 10 février 2018

Laravel 5.5 for beginners: create like and deslike systeme using Ajax 2018



Source Code


First, make sure you have installed new laravel project laraveladmin
composer create-project --prefer-dist laravel/laravel laraveladmin

Create Connection

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=sectorcode
DB_USERNAME=root
DB_PASSWORD=null

Create Laravel Authentication

php artisan make:auth

Create Model and Migration

php artisan make:model Post -m
php artisan make:model Like -m

Post migration

        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->text('body');
            $table->timestamps();
            $table->integer('user_id'); //on user table
        });

Like migration

        Schema::create('likes', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
            $table->integer('user_id'); // on user table
            $table->integer('post_id'); // on post table
            $table->boolean('like');
        });

Run Migration

php artisan migrate

Model

Post Model

<?php

namespace App;

use IlluminateDatabaseEloquentModel;

class Post extends Model
{
    public function user(){
      return $this->belongsTo('AppUser');
    }
    
    public function likes(){
      return $this->belongsTo('AppLike');
    }
}

Like Model

<?php

namespace App;

use IlluminateDatabaseEloquentModel;

class Like extends Model
{
    public function user(){
      return $this->belongsTo('AppUser');
    }
    public function post(){
      return $this->belongsTo('AppPost');
    }
}

User Model

<?php

namespace App;

use IlluminateNotificationsNotifiable;
use IlluminateFoundationAuthUser as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

   
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

   
     * @var array
     
    protected $hidden = [
        'password', 'remember_token',
    ];

    public function likes(){
      return $this->hasMany('AppLike');
    }
    public function post(){
      return $this->hasMany('AppPost');
    }
}

Post Controller

<?php

namespace AppHttpControllers;

use IlluminateHttpRequest;
use AppPost;
use AppLike;
use IlluminateSupportFacadesAuth;
use IlluminateSupportFacadesSession;

class PostController extends Controller
{
    public function index(){
      $posts = Post::orderBy('created_at', 'desc')->get();
        return view('post.index', ['posts' => $posts]);
    }
    public function postLikePost(Request $request)
       {
           $post_id = $request['postId'];
           $is_like = $request['isLike'] === 'true';
           $update = false;
           $post = Post::find($post_id);
           if (!$post) {
               return null;
           }
           $user = Auth::user();
           $like = $user->likes()->where('post_id', $post_id)->first();
           if ($like) {
               $already_like = $like->like;
               $update = true;
               if ($already_like == $is_like) {
                   $like->delete();
                   return null;
               }
           } else {
               $like = new Like();
           }
           $like->like = $is_like;
           $like->user_id = $user->id;
           $like->post_id = $post->id;
           if ($update) {
               $like->update();
           } else {
               $like->save();
           }
           return null;
       }
}

Routes

Route::get('/post', 'PostController@index');
Route::post('/like','PostController@postLikePost')->name('like');

Vews

In resources/views/ create new folder named with "post", and in the post folder we will store all post data into index.blade.php

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Like & Dislike</title>
    <!-- Bootstrap -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.2/html5shiv.js"></script>
      <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
   <div class="container">
     <div class="blog-header">
       <h2>Like & Dislike System</h2>
       <p>Using ajax to like and disklike system in laravel 5.5</p>
       <hr>
     </div>

     <div class="row">
       <div class="col-sm-8">
         <div class="blog-post">
           @foreach ($posts as $post)
             <div class="post" data-postid="{{ $post->id }}">
             <a href="#"><h3>{{$post->title}}</h3></a>
             <h6>Posted on {{$post->created_at}} by {{$post->user->name}}</h6>
             <p>{{$post->body}}</p>
             <div class="interaction">
               <a href="#" class="btn btn-xs btn-warning like">{{ Auth::user()->likes()->where('post_id', $post->id)->first() ? Auth::user()->likes()->where('post_id', $post->id)->first()->like == 1 ? 'You like this post' : 'Like' : 'Like'  }}</a> |
               <a href="#" class="btn btn-xs btn-danger like">{{ Auth::user()->likes()->where('post_id', $post->id)->first() ? Auth::user()->likes()->where('post_id', $post->id)->first()->like == 0 ? 'You don't like this post' : 'Dislike' : 'Dislike'  }}</a>
            </div>
             <hr>
           </div>
           @endforeach
         </div><!-- /.blog-post -->
         <nav>
           <ul class="pager">
             <li><a href="#">Previous</a></li>
             <li><a href="#">Next</a></li>
           </ul>
         </nav>
       </div><!-- /.blog-main -->
     </div><!-- /.row -->
     <div class="footer">
       <p>Copyright © 2018 <a href="#">Sector Code</a></p>
       <p>
         <a href="#">Back to top</a>
       </p>
     </div>
   </div><!-- /.container -->
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <script src="{{ asset('/js/like.js') }}"></script>
    <script>
      var token = '{{ Session::token() }}';
      var urlLike = '{{ route('like') }}';
    </script>
  </body>
</html>

Java Script Files

In Public/Js/ we will create new file named with "like.js

var postId = 0;
$('.like').on('click', function(event) {
    event.preventDefault();
    postId = event.target.parentNode.parentNode.dataset['postid'];
    var isLike = event.target.previousElementSibling == null;
    $.ajax({
        method: 'POST',
        url: urlLike,
        data: {isLike: isLike, postId: postId, _token: token}
    })
        .done(function() {
            event.target.innerText = isLike ? event.target.innerText == 'Like' ? 'You like this post' : 'Like' : event.target.innerText == 'Dislike' ? 'You don't like this post' : 'Dislike';
            if (isLike) {
                event.target.nextElementSibling.innerText = 'Dislike';
            } else {
                event.target.previousElementSibling.innerText = 'Like';
            }
        });
});

1 commentaire:

Pages