Inline Editing
This recipe demonstrates the click-to-edit pattern where users can edit content directly in place without navigating to a separate form.
What We're Building
An editable task list with:
- Click to edit mode
- Save/cancel actions
- Optimistic updates
Complete Implementation
Blade Template
Create resources/views/tasks/list.blade.php:
blade
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Editable Tasks</title>
@hyper
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-50">
<div class="max-w-2xl mx-auto px-4 py-12 space-y-4">
@foreach ($tasks as $task)
<div
@signals([
"_showEdit_{$task->id}" => false,
"title_{$task->id}" => $task->title
])
class="flex items-center justify-between shadow-lg p-2 rounded-md">
<div class="flex items-center gap-2 flex-grow">
<!-- Displayed title -->
<p
data-show="!$_showEdit_{{ $task->id }}"
data-text="$title_{{ $task->id }}"
class="px-2 flex-grow">
</p>
<!-- Editable input -->
<input
data-show="$_showEdit_{{ $task->id }}"
data-bind="title_{{ $task->id }}"
type="text"
class="border border-gray-300 rounded-sm p-1 flex-grow"
/>
</div>
<div class="flex items-center gap-2">
<!-- Edit -->
<button
data-on:click="$_showEdit_{{ $task->id }} = true"
data-show="!$_showEdit_{{ $task->id }}"
class="cursor-pointer text-white bg-blue-500 hover:bg-blue-400 rounded-sm p-1">
Edit
</button>
<!-- Save + Cancel -->
<div data-show="$_showEdit_{{ $task->id }}" class="flex gap-1">
<button
data-on:click="@putx('/tasks/{{ $task->id }}')"
class="cursor-pointer text-white bg-green-500 hover:bg-green-400 rounded-sm p-1">
Save
</button>
<button
data-on:click="$_showEdit_{{ $task->id }} = false; $title_{{ $task->id }} = '{{ addslashes($task->title) }}'"
class="cursor-pointer text-white bg-gray-400 hover:bg-gray-300 rounded-sm p-1">
Cancel
</button>
</div>
</div>
</div>
@endforeach
</div>
</body>
</html>Controller
Create app/Http/Controllers/TaskController.php:
php
<?php
namespace App\Http\Controllers;
use App\Models\Task;
class TaskController extends Controller
{
public function index()
{
$tasks = Task::all();
return view('tasks.list', [
'tasks' => $tasks
]);
}
}Routing
In your web.php
php
use App\Http\Controllers\TaskController;
use App\Models\Task;
Route::get('/tasks', [TaskController::class, 'index']);
Route::put('/tasks/{task}', function (Task $task) {
$validated = signals()->validate([
"title_{$task->id}" => 'required|string|max:255',
]);
$task->update(['title' => $validated["title_{$task->id}"]]);
return hyper()->signals([
"_showEdit_{$task->id}" => false,
"title_{$task->id}" => $task->title,
]);
});How It Works
Edit Mode Toggle
Local signals _showEdit control the view/edit state:
blade
@signals="{ _showEdit: false }"Clicking "Edit" toggles the mode and initializes the temp value:
blade
<button data-on:click="$_showEdit = true">Edit</button>Cancel Action
Canceling discards the temp value and exits edit mode:
blade
<button data-on:click="$_showEdit = false">
Cancel
</button>Key Takeaways
1. Local Signals for Edit State: Using _showEdit (Datastar local signals) keeps edit state client-side without server involvement.

