To implement a multi-tab form in a Livewire component where each tab contains a different form and the user cannot move to the next tab until the fields in the current tab are filled, you can use Livewire's validation along with conditional rendering of tabs. Here's how you can achieve this:
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class TabsComponent extends Component
{
public $activeTab = 'tab1';
public $formData1 = ['name' => '', 'description' => ''];
public $formData2 = ['field1' => '', 'field2' => ''];
public $formData3 = ['field3' => '', 'field4' => ''];
public $formData4 = ['field5' => '', 'field6' => ''];
public $firstTabCompleted = false;
protected $rules1 = [
'formData1.name' => 'required',
'formData1.description' => 'required',
];
protected $rules2 = [
'formData2.field1' => 'required',
'formData2.field2' => 'required',
];
protected $rules3 = [
'formData3.field3' => 'required',
'formData3.field4' => 'required',
];
protected $rules4 = [
'formData4.field5' => 'required',
'formData4.field6' => 'required',
];
public function changeTab($tab)
{
if ($tab === 'tab1') {
$this->validate($this->rules1);
$this->firstTabCompleted = true;
} elseif ($tab === 'tab2') {
$this->validate($this->rules2);
} elseif ($tab === 'tab3') {
$this->validate($this->rules3);
} elseif ($tab === 'tab4') {
$this->validate($this->rules4);
}
$this->activeTab = $tab;
}
public function render()
{
return view('livewire.tabs-component');
}
}
In the Blade file (tabs-component.blade.php):
<div>
<div>
<!-- Circular indicator for tab 1 completion -->
<div style="width: 20px; height: 20px; border-radius: 50%; background-color: {{ $firstTabCompleted ? 'green' : 'grey' }}; display: inline-block;"></div>
</div>
<button wire:click="changeTab('tab1')">Tab 1</button>
<button wire:click="changeTab('tab2')" @if(!$firstTabCompleted) disabled @endif>Tab 2</button>
<button wire:click="changeTab('tab3')" @if(!$firstTabCompleted) disabled @endif>Tab 3</button>
<button wire:click="changeTab('tab4')" @if(!$firstTabCompleted) disabled @endif>Tab 4</button>
@if($activeTab === 'tab1')
<div id="tab1">
<input type="text" wire:model="formData1.name" placeholder="Name">
@error('formData1.name') <span class="error">{{ $message }}</span> @enderror
<input type="text" wire:model="formData1.description" placeholder="Description">
@error('formData1.description') <span class="error">{{ $message }}</span> @enderror
</div>
@elseif($activeTab === 'tab2')
<div id="tab2">
<!-- Form fields for tab 2 -->
</div>
@elseif($activeTab === 'tab3')
<div id="tab3">
<!-- Form fields for tab 3 -->
</div>
@elseif($activeTab === 'tab4')
<div id="tab4">
<!-- Form fields for tab 4 -->
</div>
@endif
</div>
Top comments (0)