Laravel 10 CRUD Tutorial with all Input Type - Web Journey
This CRUD application is going to be very useful for both begineer and experienced developer because in this laravel CRUD app we will use all types of attributes like text, email, number, select, radio, checkbox, textarea, date, color and definitely file upload edit delete system.
I can assure that, you will never find a single blog where everything is covered, so that i'm decided to build a crud application where all types are included.
So for develop an amazing curd app we have to follow the bellow steps.
Step-1. Install laravel app
We can install a laravel project two ways. Firstly using laravel installer and another way is using composer.
//using laravel installer
laravel new crud-app
//using composer
composer create-project laravel/laravel crud-app
Step-2: Create Database & Update env
In this step we will create a database and set database credentials. After created database open .env file from your curd app and put database info as show in bellow.
.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=crud_app
DB_USERNAME=root
DB_PASSWORD=
Step-3: Create Model & Migration
Run the following artisan command to create model and migrations file together.
php artisan make:model CrudApp -m
After execute this command CrudApp model will create inside app\models directory and migration file will create inside app/database/migrations folder.Now open crud_apps_migrations_ file it in a editor and add required fields inside up() method.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('crud_apps', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email');
$table->string('gender');
$table->integer('age');
$table->string('occupation');
$table->string('image')->nullable();
$table->timestamp('date')->nulable();
$table->string('color');
$table->text('about');
$table->tinyInteger('check_me')->default(0);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('crud_apps');
}
};
Step-4: Run Migrate
Run the bellow artisan command to execute migrations file. After successfully execute the bellow command table will create into the database.
php artisan migrate
Check databse all tables are created successfully or not.
Step-5: Update CrudApp Model
Now we have to do some changes in our CrudApp model. Update the model as shown in bellow.
app\Models\CrudApp.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class CrudApp extends Model
{
use HasFactory;
protected $fillable = [
'name',
'email',
'gender',
'age',
'occupation',
'image',
'date',
'color',
'about',
'check_me'
];
}
Step-6: Create Routes
Now we need to create all required routes for crud app in web.php located inside routes directory. We will create 6 routes here first one is for display all records, second is for add new record, third route is for store new record, fourth one is for edit record, fifth is for update record and last route is for delete a record.
Note: don't forget to import your controller at the top of the file.
routes\web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\CrudAppController;
Route::get('/',[CrudAppController::class,'all_records'])->name('all.records');
Route::get('/add-new-record',[CrudAppController::class,'add_new_record'])->name('add.new.record');
Route::post('/store-new-record',[CrudAppController::class,'store_new_record'])->name('store.new.record');
Route::get('/edit-record/{id}',[CrudAppController::class,'edit_record'])->name('edit.record');
Route::post('/update-record/{id}',[CrudAppController::class,'update_record'])->name('update.record');
Route::get('/delete-record/{id}',[CrudAppController::class,'delete_record'])->name('delete.record');
Step-7: Create Controller
In this step we have to create a controller named CrudAppController.php. To create the controller run the following artisan command.
php artisan make:controller CrudAppController
Once the CrudAppController created successfully we have to update it look likes bellow.
CrudAppController.php
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\CrudApp;
use Session;
use File;
class CrudAppController extends Controller
{
public function all_records()
{
$all_records = CrudApp::latest()->simplePaginate(5);
return view('all_records',compact('all_records'));
}
public function add_new_record()
{
return view('add_new_record');
}
public function store_new_record(Request $request)
{
$request->validate([
'name'=>'required|regex:/^[\pL\s\-]+$/u|max:50',
'email'=>'required|regex:/(.+)@(.+)\.(.+)/i|email|max:50',
'gender'=>'required',
'age'=>'required|integer|min:1|between:1,100',
'occupation'=>'required',
'image'=>'required|mimes:jpg,jpeg,png,bmp',
'date'=>'required',
'color'=>'required',
'about'=>'required|max:300',
'check_me'=>'required'
]);
$imageName = '';
if ($image = $request->file('image')){
$imageName = time().'-'.uniqid().'.'.$image->getClientOriginalExtension();
$image->move('images/profile', $imageName);
}
CrudApp::create([
'name'=>$request->name,
'email'=>$request->email,
'gender'=>$request->gender,
'age'=>$request->age,
'occupation'=>$request->occupation,
'image'=>$imageName,
'date'=>$request->date,
'color'=>$request->color,
'about'=>$request->about,
'check_me'=>$request->check_me,
]);
Session::flash('message', 'New record added success.');
Session::flash('alert-class', 'alert-success');
return redirect()->back();
}
public function edit_record($id)
{
$record = CrudApp::findOrFail($id);
return view('edit_record',compact('record'));
}
public function update_record(Request $request,$id)
{
$record = CrudApp::findOrFail($id);
$request->validate([
'name'=>'required|regex:/^[\pL\s\-]+$/u|max:50',
'email'=>'required|regex:/(.+)@(.+)\.(.+)/i|email|max:50',
'gender'=>'required',
'age'=>'required|integer|min:1|between:1,100',
'occupation'=>'required',
'date'=>'required',
'color'=>'required',
'about'=>'required|max:300',
'check_me'=>'required'
]);
$imageName = '';
$deleteOldImg = 'images/profile/'.$record->image;
if ($image = $request->file('image')){
if(file_exists($deleteOldImg)){
File::delete($deleteOldImg);
}
$imageName = time().'-'.uniqid().'.'.$image->getClientOriginalExtension();
$image->move('images/profile', $imageName);
}else{
$imageName = $record->image;
}
CrudApp::where('id',$id)->update([
'name'=>$request->name,
'email'=>$request->email,
'gender'=>$request->gender,
'age'=>$request->age,
'occupation'=>$request->occupation,
'image'=>$imageName,
'date'=>$request->date,
'color'=>$request->color,
'about'=>$request->about,
'check_me'=>$request->check_me,
]);
Session::flash('message', 'Record updated success.');
Session::flash('alert-class', 'alert-success');
return redirect()->back();
}
public function delete_record($id)
{
$record = CrudApp::find($id);
$deleteImg = 'images/profile/'.$record->image;
if (file_exists($deleteImg)) {
File::delete($deleteImg);
}
$record->delete();
Session::flash('message', 'Record deleted success.');
Session::flash('alert-class', 'alert-danger');
return redirect()->back();
}
}
Step-8. All view files
For display data in frondend we have to create three blade files in resources/view folder.
all_records.blade.php
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Laravel crud never seen before</title>
</head>
<body>
<div class="container">
<div class="row mt-3">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<div class="title" style="float:left;">
<h2>Laravel Crud Never Seen Before</h2>
</div>
<div class="add-button" style="float:right;">
<a class="btn btn-dark" href="{{ route('add.new.record') }}">Add New Record</a>
</div>
</div>
<div class="card-body">
@if(Session::has('message'))
<p class="alert {{ Session::get('alert-class', 'alert-info') }}">{{ Session::get('message') }}</p>
@endif
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Profile Image</th>
<th>Details</th>
<th>Color</th>
<th>Date</th>
<th>About</th>
<th>Action</th>
</tr>
</thead>
<tbody>
@foreach($all_records as $key=>$record)
<tr>
<td>{{ $record->id }}</td>
<td><img src="{{ asset('images/profile/'.$record->image) }}" alt="Image" style="width:150px; height:120px;"></td>
<td>
<strong>Name:</strong> {{ $record->name }}<br>
<strong>Email:</strong> {{ $record->email }}<br>
<strong>Age:</strong> {{ $record->age }}<br>
<strong>Gender:</strong> {{ $record->gender }}<br>
<strong>Occupation:</strong> {{ $record->occupation }}<br>
</td>
<td>{{ $record->color }}</td>
<td>{{ \Carbon\Carbon::parse($record->date)->format('Y-m-d') }}</td>
<td>{{ $record->about }}</td>
<td>
<a class="btn btn-success btn-sm" href="{{ route('edit.record',$record->id) }}">Edit</a>
<a class="btn btn-danger btn-sm" onclick="return confirm('Are you sure to delete?')" href="{{ route('delete.record',$record->id) }}">Delete</a>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
<div class="card-footer">
{!! $all_records->links() !!}
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
add_new_record.blade.php
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Laravel crud never seen before</title>
</head>
<body>
<div class="container">
<div class="row mt-3">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<div class="title" style="float:left;">
<h2 class="text-left">Add New Record</h2>
</div>
<div class="add-button" style="float:right;">
<a class="btn btn-dark" href="{{ route('all.records') }}">All Records</a>
</div>
</div>
<div class="card-body">
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@if(Session::has('message'))
<p class="alert {{ Session::get('alert-class', 'alert-info') }}">{{ Session::get('message') }}</p>
@endif
<form action="{{ route('store.new.record') }}" method="post" enctype="multipart/form-data">
@csrf
<div class="row">
<div class="col-md-5">
<div class="mb-3">
<label class="mb-1">Name</label>
<input type="text" name="name" class="form-control" value="{{ old('name') }}">
</div>
<div class="mb-3">
<label class="mb-1">Email</label>
<input type="email" name="email" class="form-control" value="{{ old('email') }}">
</div>
<div class="mb-3">
<label class="mb-1">Age</label>
<input type="number" name="age" class="form-control" value="{{ old('age') }}">
</div>
<div class="mb-3">
<label class="mb-1">About</label>
<textarea name="about" rows="5" class="form-control">{{ old('about') }}</textarea>
</div>
</div>
<div class="col-md-5 offset-md-1">
<div class="form-check-inline mb-3">
<label class="form-check-label mb-1">Gender</label> <br>
<input class="form-check-input" type="radio" name="gender" value="Male"> Male
<input class="form-check-input" type="radio" name="gender" value="Female"> Female
</div>
<div class="mb-3">
<label class="mb-1">Image</label>
<input type="file" name="image" class="form-control" value="{{ old('image') }}">
</div>
<div class="mb-3">
<label class="mb-1">Date</label>
<input type="date" name="date" class="form-control" value="{{ old('date') }}">
</div>
<div class="mb-3">Occupation</label>
<select name="occupation" class="form-control">
<option value="">Select</option>
<option value="Engineer">Engineer</option>
<option value="Doctor">Doctor</option>
</select>
</div>
<div class="mb-3">
<label class="mb-1">Color</label>
<input type="color" name="color" class="form-control" value="{{ old('color') }}">
</div>
<div class="mb-3 form-check">
<input type="checkbox" name="check_me" class="form-check-input" value="1">
<label class="form-check-label">Check me</label>
</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
edit_record.blade.php
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Laravel crud never seen before</title>
</head>
<body>
<div class="container">
<div class="row mt-3">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<div class="title" style="float:left;">
<h2 class="text-left">Edit Record</h2>
</div>
<div class="add-button" style="float:right;">
<a class="btn btn-dark" href="{{ route('all.records') }}">All Records</a>
</div>
</div>
<div class="card-body">
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@if(Session::has('message'))
<p class="alert {{ Session::get('alert-class', 'alert-info') }}">{{ Session::get('message') }}</p>
@endif
<form action="{{ route('update.record',$record->id) }}" method="post" enctype="multipart/form-data">
@csrf
<div class="row">
<div class="col-md-5">
<div class="mb-3">
<label class="mb-1">Name</label>
<input type="text" name="name" class="form-control" value="{{ $record->name }}">
</div>
<div class="mb-3">
<label class="mb-1">Email</label>
<input type="email" name="email" class="form-control" value="{{ $record->email }}">
</div>
<div class="mb-3">
<label class="mb-1">Age</label>
<input type="number" name="age" class="form-control" value="{{ $record->age }}">
</div>
<div class="mb-3">
<label class="mb-1">About</label>
<textarea name="about" rows="5" class="form-control">{{ $record->about }}</textarea>
</div>
</div>
<div class="col-md-5 offset-md-1">
<div class="form-check-inline mb-3">
<label class="form-check-label mb-1">Gender</label> <br>
<input class="form-check-input" type="radio" name="gender" value="Male" @if($record->gender=='Male') checked @endif> Male
<input class="form-check-input" type="radio" name="gender" value="Female" @if($record->gender=='Female') checked @endif> Female
</div>
<div class="mb-3">
<label class="mb-1">Image</label>
<img src="{{ asset('images/profile/'.$record->image) }}" style="width:100px;margin-bottom:3px">
<input type="file" name="image" class="form-control">
</div>
<div class="mb-3">
<label class="mb-1">Date</label>
<input type="date" name="date" class="form-control" value="{{ \Carbon\Carbon::parse($record->date)->format('Y-m-d') }}">
</div>
<div class="mb-3">
<label class="mb-1">Occupation</label>
<select name="occupation" class="form-control">
<option value="">Select</option>
<option value="Engineer" @if($record->occupation=='Engineer') selected @endif>{{ __('Engineer') }}</option>
<option value="Doctor" @if($record->occupation=='Doctor') selected @endif>{{ __('Doctor') }}</option>
</select>
</div>
<div class="mb-3">
<label class="mb-1">Color</label>
<input type="color" name="color" class="form-control" value="{{ $record->color }}">
</div>
<div class="mb-3 form-check">
<input type="checkbox" name="check_me" class="form-check-input" value="1" @if($record->check_me==1) checked @endif>
<label class="form-check-label">Check me</label>
</div>
</div>
<button type="submit" class="btn btn-primary">Update</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
That's all. Start your artisan server and test crud app. It's amazing.