Saturday, December 29, 2018

A Simple Laravel CRUD App

A Simple Laravel CRUD App

A Laravel CRUD Sample

Laravel is an excellent PHP framework for web development. It creates a RESTful web app with just a few commands. The procedures are shown as the following steps:

1. Create a New Project

$> laravel new laravel_product
Crafting application...
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Package operations: 86 installs, 0 updates, 0 removals
  - Installing doctrine/inflector (v1.3.0): Loading from cache
  - Installing doctrine/lexer (v1.0.1): Loading from cache
  - Installing dragonmantank/cron-expression (v2.2.0): 
                    :
                    :
Package manifest generated successfully.
Application ready! Build something amazing.

After creating a new project named 'laravel_product', the files needed have been created under the directory.

$> cd laravel_product
$> php artisan -v
Laravel Framework 5.7.19

2: Configure MySQL Database

Edit .env file

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_product
DB_USERNAME=xxxx
DB_PASSWORD=xxxx

Add a database in MySQL server

Add a database manually by using Sequel Pro and following parameters.

  • Database Name: laravel_product
  • Database Encoding: UTF-8 Unicode (utf8mb4)
  • Database Collation: Default (utf8mb4_general_ci)

Create database

Create tables

$> php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table

3: Create a Model 'Product' and a Migration File.

$> php artisan make:model Product -m
Model created successfully.
Created Migration: 2018_12_26_181923_create_products_table

Edit migration file 2018_12_26_181923_create_products_table.php

Insert fields between id and timestamps:

  $table->increments('id');
    :
  $table->string('prod_name');
  $table->text('prod_desc');
  $table->integer('prod_price');
  $table->integer('prod_qty'); 
    :
  $table->timestamps();

Create table 'products'

$> php artisan migrate
Migrating: 2018_12_26_181923_create_products_table
Migrated:  2018_12_26_181923_create_products_table

Add the fillable property inside Product.php file.

<?php
  namespace App;
  use Illuminate\Database\Eloquent\Model;

  class Product extends Model {
      protected $fillable = [
        'prod_name',
        'prod_desc',
        'prod_price',
        'prod_qty'
      ];
  }

4: Create Routes and Controller

Create ProductController.php

Use following command to create controller.

  • php artisan make:controller
$> php artisan make:controller ProductController --resource
Controller created successfully.

Add routes code in /routes/web.php file.

Route::resource('products', 'ProductController');

Show routes

$> php artisan route:list
+-----------+-------------------------+------------------+-----------+
| Method    | URI                     | Name             | Action    |
+-----------+-------------------------+------------------+-----------+
| GET|HEAD  | /                       |                  | Closure   |
| GET|HEAD  | api/user                |                  | Closure   |
| GET|HEAD  | products                | products.index   | *@index   |
| POST      | products                | products.store   | *@store   |
| GET|HEAD  | products/create         | products.create  | *@create  |
| GET|HEAD  | products/{product}      | products.show    | *@show    |
| PUT|PATCH | products/{product}      | products.update  | *@update  |
| DELETE    | products/{product}      | products.destroy | *@destroy |
| GET|HEAD  | products/{product}/edit | products.edit    | *@edit    |
+-----------+-------------------------+------------------+-----------+
* = App\Http\Controllers\ProductController

5: Create the views

a. Create a file layout.blade.php inside '/resources/views' folder.

b. Create a folder 'products' inside '/resources/views' folder.

c. Then, create the following three files inside '/resource/view/products'.

  • create.blade.php
  • edit.blade.php
  • index.blade.php

d. Edit layout.blade.php

<!DOCTYPE html>
<html lang='en'>
<head>
 <meta charset="utf-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatiable" content="ie=edge">
 <title>Laravel 5.7 A simple CRUD Example</title>
    <link href="{{ asset('css/app.css') }}" rel="stylesheet" type="text/css">
</head>
<body>
 <!-- Navbar start -->
  <nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
    <a class="navbar-brand" href="{{ route('products.index') }}">
    A Laravel CRUD Sample</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" 
      data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" 
      aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarsExampleDefault">
      <ul class="navbar-nav mr-auto">
        <li class="nav-item active">
          <a class="nav-link" href="{{ route('products.create') }}">
            Add A Product 
            <span class="sr-only">(current)</span></a>
        </li>
      </ul>
      <form method="post" action="#" class="form-inline my-2 my-lg-0">
        <input class="form-control mr-sm-2" type="text" placeholder="Search" 
          aria-label="Search">
        <button class="btn btn-outline-success my-2 my-sm-0" 
          type="submit">Search</button>
      </form>
    </div>
  </nav> 
  <!-- Navbar end -->
 <div class="container">
  @yield('content')
 </div>
 <script src="{{ asset('js/app.js') }}"></script>
</body>
</html>

e. Edit create.blade.php

Remember to add @csrf in the tag in order to have CSRF Protection.

<form method="post" action="{{ route('products.store') }}"> 
  @csrf  // must added.
     :
</form>

create.blade.php is as follows:

@extends('layout')

@section('content')
<div class="card uper">
 <div class="card-header">
  <h4>Add Product</h4>
 </div>
 <div class="card-body">
   @if ($errors->any())
  <div class="alert alert-danger">
    <ul>
      @foreach ($errors->all() as $error)
     <li>{{ $error }}</li>
     <button type="button" class="close" data-dismiss="alert" 
       aria-label="Close">
       <span aria-hidden="true">&times;</span>
              </button>
   @endforeach 
    </ul>
    </div><br/>
  @endif
  <form method="post" action="{{ route('products.store') }}">
    @csrf
    <div class="form-group">
      <label for="prod_name">Product Name:</label>
            <input type="text" class="form-control" name="prod_name"/>
    </div>
    <div class="form-group">
      <label for="prod_desc">Product Description:</label>
            <input type="text" class="form-control" name="prod_desc"/>
    </div>
          <div class="form-group">
      <label for="prod_price">Product Price:</label>
      <input type="text" class="form-control" name="prod_price"/>
    </div>
    <div class="form-group">
      <label for="prod_qty">Product Quantity:</label>
   <input type="text" class="form-control" name="prod_qty"/>
    </div>
    <button type="submit" class="btn btn-primary">Add</button>
    <a href="{{ route('products.index') }}" class="btn btn-info">Back</a>
   </form>
    </div>
  </div>
@endsection

f. Code 'create' function in ProductController.php

Remember to add use App\Product; in the controller in order to use the Model 'Product'.

<?php
  namespace App\Http\Controllers;
  use Illuminate\Http\Request;
  use App\Product;  // must add

  public function create() 
    {
      return view('shares.create');
    }

6: Save Data

Code the "store" function in the ProductController.php

public function store(Request $request)
  {
    $request->validate([
      'prod_name'  => 'required',
      'prod_desc'  => 'required',
      'prod_price' => 'required|integer',
      'prod_qty'   => 'required|integer'
    ]);
    $product = new Product([
      'prod_name'  => $request->get('prod_name'),
      'prod_desc'  => $request->get('prod_desc'),
      'prod_price' => $request->get('prod_price'),
      'prod_qty'   => $request->get('prod_qty')
    ]);
    $product->save();
    return redirect('/products')->with('success','Product has been added!');
  }

Add some testing data and save.

7: Display the data.

Code index.blade.php

@extends('layout')

@section('content')
<div class="uper">
 @if(session()->get('success'))
  <div class="alert alert-success">
    {{ session()->get('success') }}
    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
   <span aria-hidden="true">&times;</span>
          </button>
   </div><br/>
 @endif
</div>
<table class="table table-hover">
  <thead> 
 <tr>
  <td><b>ID</b></td>
  <td><b>Product Name</b></td>
  <td><b>Product Description</b></td>
  <td><b>Product Price</b></td>
  <td><b>Product Qty</b></td>
  <td colspan="2"><b>Action</b></td>
 </tr>
  </thead>
  <tbody>
   @foreach($products as $product)
   <tr>
     <td>{{$product->id}}</td>
     <td>{{$product->prod_name}}</td>
     <td>{{$product->prod_desc}}</td>
     <td>{{$product->prod_price}}</td>
     <td>{{$product->prod_qty}}</td>
     <td><a href="{{ route('products.edit', $product->id) }}" 
    class="btn btn-primary">Edit</a></td>
     <td>
        <form method="post" action="{{ route('products.destroy', $product->id) }}">
          @method('DELETE')
          @csrf
          <button type="submit" class="btn btn-danger">Delete</button>
        </form>
      </td>
   </tr>
   @endforeach
  </tbody>
</table>
<div class="pagination justify-content-center">
 {{ $products->links() }}
</div>
@endsection

Code the "index" function in the ProductController.php

public function index() 
  {
    $products = Product::all();
    return view('products.index', compact('products'));
  }

8: Edit and Update Data

Code the "edit" function in the ProductController.php

public function edit($id) 
  {
    $product = Product::find($id);
    return view('products.edit', compact('product'));
  }

Code "edit.blade.php"

@extends('layout')

@section('content')
<div class="card uper">
  <div class="card-header">
   <h4>Edit Product</h4>
  </div>
  <div class="card-body">
   @if ($errors->any())
     <div class="alert alert-danger">
      <ul>
        @foreach ($errors->all() as $error)
          <li>{{ $error }}</li>
          <button type="button" class="close" data-dismiss="alert" 
            aria-label="Close">
     <span aria-hidden="true">&times;</span>
            </button>
        @endforeach
      </ul>
     </div><br/>
   @endif 
   <form method="post" action="{{ route('products.update', $product->id) }}">
     @method('PATCH')
     @csrf
     <div class="form-group">
      <label for="prod_name">Product Name</label>
      <input type="text" class="form-control" name="prod_name" 
        value={{ $product->prod_name }} /> 
     </div>
     <div class="form-group">
      <label for="prod_desc">Product Description</label>
      <input type="text" class="form-control" name="prod_desc" 
        value={{ $product->prod_desc }} /> 
     </div>
     <div class="form-group">
      <label for="prod_price">Product Price</label>
      <input type="text" class="form-control" name="prod_price" 
        value={{ $product->prod_price }} /> 
     </div>
     <div class="form-group">
      <label for="prod_qty">Product Qty</label>
    <input type="text" class="form-control" name="prod_qty" 
      value={{ $product->prod_qty }} /> 
   </div>
   <button type="submit" class="btn btn-primary">Update</button>
    </form>
  </div>
</div>
@endsection

Code the "update" function in the ProductController.php

public function update(Request $request, $id)
  {
    $request->validate([
      'prod_name'  => 'required',
      'prod_desc'  => 'required',
      'prod_price' => 'required|integer',
      'prod_qty'   => 'required|integer'
    ]);
    $product = Product::find($id);
    $product->prod_name  = $request->get('prod_name');
    $product->prod_desc  = $request->get('prod_desc');
    $product->prod_price = $request->get('prod_price');
    $product->prod_qty   = $request->get('prod_qty');
    $product->save();
    return redirect('/products')->with('success', 'Product has been updated!');
  }

9: Delete the data

Code the "delete" function in ProductController.php

public function destroy($id)
  {
    $product = Product::find($id);
    $product->delete();
    return redirect('/products')->with('success', 'Product has been deleted!');
  }

10: Start the CRUD web app.

Start the server:

$> php artisan serve

Go to "http://localhost:8000/products" and will see the product index page.

11: Pagination

If it needs to have the pagination functionality, it's just as easy as doing two things.

Modify the 'index' function in ProductController.php.

a. change to pagination method.

Just change

$products = Product::all();

to:

// number: the record number per page.
$products = Product::paginate(number);  

Pagination links:

  • $products->links()
     :
    </table>
  <div class="pagination justify-content-center">
    {{ $products->links() }}
  </div>
@endsection

That's all! Isn't it simple and easy!

3 comments:

  1. Hey Nice Blog!! Thanks For Sharing!!!Wonderful blog & good post.Its really helpful for me, waiting for a more new post. Keep Blogging!
    best java training in coimbatore
    php training in coimbatore
    best php training institutes in coimbatore

    ReplyDelete
  2. This comment has been removed by a blog administrator.

    ReplyDelete
  3. Infycle Technologies, the No.1 Cloud training center offers attractive AWS training in Chennai with the remunerative DevOps Course for the candidate. Along with the courses, 100% placement training guidance will also be given for the welfare of your career. For more, reach us through calling 7502633633.

    ReplyDelete