Welcome to Part 2 of our tutorial on creating the simplest CRUD (Create, Read, Update, Delete) application using Laravel. In this part, we’ll enhance our application by adding form validation, improving the user interface with some basic styling, and handling errors gracefully.
Step 7: Adding Form Validation
Laravel makes it easy to validate incoming data. We have already added basic validation in our ItemController
. Let’s refine it a bit.
Updating Validation Rules
Open the ItemController
and update the store
and update
methods to include more detailed validation rules:
public function store(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'description' => 'required|string',
]);
Item::create($request->all());
return redirect()->route('items.index')
->with('success', 'Item created successfully.');
}
public function update(Request $request, Item $item)
{
$request->validate([
'name' => 'required|string|max:255',
'description' => 'required|string',
]);
$item->update($request->all());
return redirect()->route('items.index')
->with('success', 'Item updated successfully.');
}
Displaying Validation Errors
Next, we need to display validation errors in our forms. Update the create.blade.php
and edit.blade.php
files to include error messages:
create.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<h1>Add New Item</h1>
<form action="{{ route('items.store') }}" method="POST">
@csrf
<div class="form-group">
<label for="name">Name</label>
<input type="text" name="name" class="form-control" required>
@error('name')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea name="description" class="form-control" required></textarea>
@error('description')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
</div>
<button type="submit" class="btn btn-primary">Save</button>
</form>
</div>
@endsection
edit.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<h1>Edit Item</h1>
<form action="{{ route('items.update', $item->id) }}" method="POST">
@csrf
@method('PUT')
<div class="form-group">
<label for="name">Name</label>
<input type="text" name="name" class="form-control" value="{{ $item->name }}" required>
@error('name')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea name="description" class="form-control" required>{{ $item->description }}</textarea>
@error('description')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
</div>
<button type="submit" class="btn btn-primary">Update</button>
</form>
</div>
@endsection
Step 8: Improving the User Interface
To make our application look better, we’ll add some basic styling using Bootstrap, a popular CSS framework. Laravel includes Bootstrap out of the box, so we can start using it right away.
Adding Bootstrap to the Layout
Open the resources/views/layouts/app.blade.php
file and make sure it includes Bootstrap:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple CRUD</title>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Simple CRUD</a>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="{{ route('items.index') }}">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ route('items.create') }}">Add Item</a>
</li>
</ul>
</div>
</nav>
<div class="container mt-5">
@yield('content')
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>
Enhancing the Item Views
Now let’s make some improvements to our item views:
index.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<h1>Items</h1>
<a href="{{ route('items.create') }}" class="btn btn-primary mb-3">Add Item</a>
@if ($message = Session::get('success'))
<div class="alert alert-success">
{{ $message }}
</div>
@endif
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Description</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach ($items as $item)
<tr>
<td>{{ $item->id }}</td>
<td>{{ $item->name }}</td>
<td>{{ $item->description }}</td>
<td>
<a href="{{ route('items.show', $item->id) }}" class="btn btn-info">View</a>
<a href="{{ route('items.edit', $item->id) }}" class="btn btn-warning">Edit</a>
<form action="{{ route('items.destroy', $item->id) }}" method="POST" style="display:inline;">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endsection
show.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<h1>Item Details</h1>
<table class="table table-bordered">
<tr>
<th>ID</th>
<td>{{ $item->id }}</td>
</tr>
<tr>
<th>Name</th>
<td>{{ $item->name }}</td>
</tr>
<tr>
<th>Description</th>
<td>{{ $item->description }}</td>
</tr>
</table>
<a href="{{ route('items.index') }}" class="btn btn-primary">Back to List</a>
</div>
@endsection
Step 9: Handling Errors Gracefully
To handle errors gracefully, we need to customize the error pages. Laravel provides default error pages located in the resources/views/errors
directory. We can customize these pages to match the style of our application.
Customizing the 404 Error Page
Create a new file named 404.blade.php
in the resources/views/errors
directory and add the following content:
@extends('layouts.app')
@section('content')
<div class="container">
<h1>Page Not Found</h1>
<p>Sorry, the page you are looking for could not be found.</p>
<a href="{{ route('items.index') }}" class="btn btn-primary">Back to Home</a>
</div>
@endsection
Customizing the 500 Error Page
Create a new file named 500.blade.php
in the resources/views/errors
directory and add the following content:
@extends('layouts.app')
@section('content')
<div class="container">
<h1>Server Error</h1>
<p>Sorry, something went wrong on our end. Please try again later.</p>
<a href="{{ route('items.index') }}" class="btn btn-primary">Back to Home</a>
</div>
@endsection
Conclusion
In this second part of the tutorial, we’ve enhanced our CRUD application by adding form validation, improving the user interface with Bootstrap, and handling errors gracefully with custom error pages. Your application should now be more user-friendly and robust.
Stay tuned for Part 3, where we’ll dive deeper into more advanced features and enhancements for our CRUD application!