Skip to main content

Black Friday 2025! Only until December 1st: coupon FRIDAY25 for 40% off Yearly/Lifetime membership!

Read more here

Edit Product Form: Reusable Form Object?

Premium
9 min read

We have made a create page. Now we need a page for editing records. Forms can be made in two ways. The first one, make a new component and add everything, or the second, extract parts in the Form Object.


Separate Component

First, we need a new component and a route mapped to it. Then we can link the edit button to that route.

php artisan make:livewire ProductsEdit

routes/web.php:

Route::get('products', [\App\Http\Controllers\ProductController::class, 'index']);
Route::get('products/create', \App\Livewire\ProductsCreate::class)->name('products.create');
Route::get('products/{product}/edit', \App\Livewire\ProductsEdit::class)->name('products.edit');

resources/views/livewire/products.blade.php:

<div class="space-y-6">
// ...
<td>
<a href="{{ route('products.edit', $product) }}" class="inline-flex items-center px-4 py-2 bg-gray-800 rounded-md font-semibold text-xs text-white uppercase tracking-widest">
Edit </a>
<a wire:click="deleteProduct({{ $product->id }})" onclick="return confirm('Are you sure?') || event.stopImmediatePropagation()" href="#" class="inline-flex items-center px-4 py-2 bg-red-600 rounded-md font-semibold text-xs text-white uppercase tracking-widest">
Delete </a>
</td>
// ...
</div>

The form itself is the same as for the create product.

resources/views/products-edit.blade.php:

<form method="POST" wire:submit="save">
<div>
<label for="name" class="block font-medium text-sm text-gray-700">Name</label>
<input id="name" class="block mt-1 w-full border-gray-300 rounded-md shadow-sm" type="text" wire:model="name" />
@error('name')
<span class="mt-2 text-sm text-red-600">{{ $message }}</span>
@enderror
</div>
 
<div class="mt-4">
<label for="description" class="block font-medium text-sm text-gray-700">Description</label>
<textarea id="description" class="block mt-1 w-full border-gray-300 rounded-md shadow-sm" wire:model="description"></textarea>
@error('description')
<span class="mt-2 text-sm text-red-600">{{ $message }}</span>
@enderror
</div>
 
<div class="mt-4">
<label for="category">Category</label>
<select wire:model="category_id" name="category" id="category" class="block mt-1 w-full border-gray-300 rounded-md shadow-sm">
<option value="0">-- CHOOSE CATEGORY --</option>
@foreach($categories as $id => $category)
<option value="{{ $id }}">{{ $category }}</option>
@endforeach
</select>
@error('category_id')
<span class="mt-2 text-sm text-red-600">{{ $message }}</span>
@enderror
</div>
 
<button class="mt-4 px-4 py-2 bg-gray-800 rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700">
Save Product
</button>
</form>

In the Livewire components class, first, we need to assign all the properties to values from the product. Because we are using Route Model Binding, we can accept Product parameter in the...

The Full Lesson is Only for Premium Members

Want to access all of our courses? (29 h 14 min)

You also get:

54 courses
Premium tutorials
Access to repositories
Private Discord
Get Premium for $129/year or $29/month

Already a member? Login here

Comments & Discussion

A
AlexSteele ✓ Link copied!

What is the significance of changing the render to the create, vs edit? Why did we do that?

N
Nerijus ✓ Link copied!

To use the same blade file. You can name it whatever you want

A
AlexSteele ✓ Link copied!

makes perfect sense - reducing the number of files to decrease complexity

C
Chris ✓ Link copied!

But why to make ProductsCreate and ProductsEdit component, cant we just make livewire component called ProductsForm and both create and edit logic to there?

N
Nerijus ✓ Link copied!

You can do it this way

M
muuucho ✓ Link copied!

What way?

N
Nerijus ✓ Link copied!

you can check the quiz livewire course which was just updated to livewire v3 and uses one component for the

M
muuucho ✓ Link copied!

Where did the "Lock logic" went when you refactored the Edit page into the Form page?

N
Nerijus ✓ Link copied!

Because in the form object we are binding to the model the id of it is automatically locked. This is mentioned in the Livewire

LA
Luis Alberto Oliveira ✓ Link copied!

Hi, when I try to use the same form to create and edit an user I have the following issue.

The code wire:click="edit({{ $user->id }})" do not bring the value to the input, I've to use ' ' between ('{{ $user->id }}').

Why this happens?

N
Nerijus ✓ Link copied!

Should work without ' '. This is how it is in the docs also https://livewire.laravel.com/docs/actions#passing-parameters

SI
Solomon Iroegbu ✓ Link copied!

Cannot assign Illuminate\Support\Collection to property App\Livewire\ProductsEdit::$categories of type App\Livewire\Collection

What should i do?

N
Nerijus ✓ Link copied!

Import the collection

SI
Solomon Iroegbu ✓ Link copied!

Thank you. it worked

LK
Latif Kasuli ✓ Link copied!

Can I use the same blade file for creating and editing in Class-based Volt components?

N
Nerijus ✓ Link copied!

Never used volt. You should just try

C
C4 ✓ Link copied!

Lets say I have a checkout page that allows the customer to submit multiple address's if there is more than 1 of something (qty). How can I assign a public array variable to multiple wire:model inputs? Feels like something like this should work, but it doesnt. Ive tried a lot & ran out of ideas.
wire:model.lazy="form.address[0]" wire:model.lazy="form.address[1]"

Im not working with validation for testing.

Figured it out Ill keep it here, incase there is anyone else like me. In blade or livewire not sure, you gotta assign array keys with a period apparently sooo wire:model.lazy="form.address.1"

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.