Back to Course |
React.js + Inertia in Laravel 11: From Scratch

Delete Record with Confirmation

Another common feature is deleting a record with a confirmation message.


First, let's take care of the back-end part.

app/Http/Controllers/PostController.php:

class PostController extends Controller
{
// ...
 
public function destroy(Post $post): RedirectResponse
{
$post->delete();
 
return redirect()->route('posts.index')
->with('message', 'Post deleted successfully');
}
}

For the front-end, first, let's add the button.

resources/js/Pages/Posts/Index.jsx:

import AppLayout from '../../Layouts/AppLayout.jsx';
import { Head, Link } from '@inertiajs/react';
 
export default function PostsIndex({ posts }) {
return (
<AppLayout>
<Head>
<title>Posts</title>
</Head>
 
<div>
<Link href={route('posts.create')} className="mb-4 inline-block rounded-md bg-blue-500 px-4 py-3 text-xs font-semibold uppercase tracking-widest text-white shadow-sm">
Add new post
</Link>
 
<table className="min-w-full divide-y divide-gray-200 border">
<thead>
<tr>
<th className="px-6 py-3 bg-gray-50 text-left">
<span className="text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">ID</span>
</th>
<th className="px-6 py-3 bg-gray-50 text-left">
<span className="text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">Title</span>
</th>
<th className="px-6 py-3 bg-gray-50 text-left">
<span className="text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">Content</span>
</th>
<th className="px-6 py-3 bg-gray-50 text-left">
<span className="text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">Created At</span>
</th>
<th className="px-6 py-3 bg-gray-50 text-left">
</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200 divide-solid">
{posts && posts && posts.map((post) => (
<tr key={post.id}>
<td className="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-900">
{post.id}
</td>
<td className="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-900">
{post.title}
</td>
<td className="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-900">
{post.content}
</td>
<td className="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-900">
{post.created_at}
</td>
<td className="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-900">
<button type="button" className="rounded-md bg-red-600 px-3 py-2 text-xs font-semibold uppercase tracking-widest text-white shadow-sm">
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
</AppLayout>
);
};

The delete button will have a click event. When the button is clicked, we can use the form helper again, but this time, we will make a manual visit.

For that, we will create a function destroy(), which will accept the id as a parameter and call it when the button clicks.

resources/js/Pages/Posts/Index.jsx:

import AppLayout from '../../Layouts/AppLayout.jsx';
import { Head, Link } from '@inertiajs/react';
 
export default function PostsIndex({ posts }) {
const destroy = (id) => {
 
}
 
return (
// ...
<tbody className="bg-white divide-y divide-gray-200 divide-solid">
{posts && posts && posts.map((post) => (
<tr key={post.id}>
// ...
<td className="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-900">
<button type="button" className="rounded-md bg-red-600 px-3 py-2 text-xs font-semibold uppercase tracking-widest text-white shadow-sm">
<button onClick={() => destroy(post.id)} type="button" className="rounded-md bg-red-600 px-3 py-2 text-xs font-semibold uppercase tracking-widest text-white shadow-sm">
Delete
</button>
</td>
</tr>
))}
</tbody>
// ...
);
};

In the destroy() function, we will use the native browser confirmation and, after confirming, call the delete method for the posts.destroy route.

resources/js/Pages/Posts/Index.jsx:

import AppLayout from '../../Layouts/AppLayout.jsx';
import { Head, Link } from '@inertiajs/react';
import { Head, Link, router } from '@inertiajs/react';
 
export default function PostsIndex({ posts }) {
const destroy = (id) => {
if (confirm('Are you sure?')) {
router.delete(route('posts.destroy', { id }));
}
}
 
return (
// ...
);
};

After pressing the delete button, confirmation is shown.

After confirming the delete, the post is deleted, and a success message appears. And the main thing of SPA and Inertia: it all happened without a full page refresh.


So this is how we can perform the delete, and this is also how you can process the form manually if, for some reason, you don't want to use the form helper from Inertia.