To achieve this with Livewire, you’ll want to build a component that reacts to the user’s selections, loads related data, and exposes it to your view. Here’s a step-by-step example of how to set this up.
1. Livewire Component Setup
Generate a Livewire component (if you haven’t yet):
php artisan make:livewire BroughtInventoryBrowser
2. Component Class Example
use Livewire\Component;
use App\Models\Store;
use App\Models\BroughtInventoryInfo;
use App\Models\BroughtInventory;
class BroughtInventoryBrowser extends Component
{
public $storeFromId;
public $storeToId;
public $broughtDate;
public $trackingNo;
public $status;
public $storeFromOptions = [];
public $storeToOptions = [];
public $filteredInventories = [];
public function mount()
{
$this->storeFromOptions = Store::all();
}
public function updatedStoreFromId($value)
{
// Find all store_to (store_id of BroughtInventory) based on store_from (store_id of BroughtInventoryInfo)
// First fetch the BroughtInventoryInfo IDs that match the selected store_from
$infoIds = BroughtInventoryInfo::where('store_id', $value)->pluck('id');
// Next, get store_to IDs from BroughtInventory records linked to those infos
$this->storeToOptions = Store::whereIn(
'id',
BroughtInventory::whereIn('brought_inventory_info_id', $infoIds)->pluck('store_id')->unique()
)->get();
// Reset other fields
$this->storeToId = null;
$this->filteredInventories = [];
}
public function search()
{
$query = BroughtInventoryInfo::query();
if ($this->storeFromId) {
$query->where('store_id', $this->storeFromId);
}
if ($this->trackingNo) {
$query->where('tracking_no', $this->trackingNo);
}
if ($this->broughtDate) {
$query->whereDate('brought_date', $this->broughtDate);
}
if ($this->status) {
$query->where('status', $this->status);
}
$query->with(['broughtInventories' => function($q) {
if ($this->storeToId) {
$q->where('store_id', $this->storeToId);
}
}, 'store']);
$this->filteredInventories = $query->get();
}
public function render()
{
return view('livewire.brought-inventory-browser', [
'storeFromOptions' => $this->storeFromOptions,
'storeToOptions' => $this->storeToOptions,
'results' => $this->filteredInventories
]);
}
}
3. Livewire Blade View Example
<div>
<form wire:submit.prevent="search">
<label>Store From:</label>
<select wire:model="storeFromId">
<option value="">Select Store From</option>
@foreach($storeFromOptions as $store)
<option value="{{ $store->id }}">{{ $store->name }}</option>
@endforeach
</select>
<label>Store To:</label>
<select wire:model="storeToId" @if(!$storeFromId) disabled @endif>
<option value="">Select Store To</option>
@foreach($storeToOptions as $store)
<option value="{{ $store->id }}">{{ $store->name }}</option>
@endforeach
</select>
<label>Tracking No:</label>
<input type="text" wire:model="trackingNo" />
<label>Brought Date:</label>
<input type="date" wire:model="broughtDate" />
<label>Status:</label>
<input type="text" wire:model="status" />
<button type="submit">Search</button>
</form>
<hr>
@if($results)
<table>
<tr>
<th>Tracking No</th>
<th>Brought Date</th>
<th>Store From</th>
<th>Store To(s)</th>
<th>Status</th>
</tr>
@foreach($results as $info)
<tr>
<td>{{ $info->tracking_no }}</td>
<td>{{ $info->brought_date }}</td>
<td>{{ $info->store->name ?? '-' }}</td>
<td>
@foreach ($info->broughtInventories as $bi)
{{ $bi->store->name ?? '-' }}<br>
@endforeach
</td>
<td>{{ $info->status }}</td>
</tr>
@endforeach
</table>
@endif
</div>
How it works:
- The user selects “Store From” (store_from) and Livewire loads related “Store To” options.
- User can further filter by tracking_no, brought_date, or status.
- Upon submitting, it queries with the related relationships and displays the results.
Tips:
- Adjust relationships and column names if your actual schema varies.
- Use eager loading judiciously to avoid N+1 queries.
Let me know if you need a more specific implementation or extra refinements!