I am trying to update data on a Livewire component in nested arrays, but they are not functioning as I would have hoped. I am trying to leverage the use of multidimensional arrays to manage the data of several inputs, as seen below.
@foreach ($items as $item)
<input wire:model="items.{{ $item->id }}.employee_id" type="text">
<input wire:model="items.{{ $item->id }}.name" type="text">
@endforeach
I am running into problems when typing data into these inputs. It will update one value (such as items.3.name
) and reset all other data in the multidimensional array back to their original values.
I have tried changing the rules on the page after reading that Livewire requires them, but that hasn't helped. Here is a snippet of my controller:
public $items = [];
protected $rules = [
'items.*.employee_id' => 'required',
'items.*.name' => 'required',
];
public function mount() {
$this->items = Employees::all()->toArray();
}
public function render() {
return view('livewire.employees');
}
public function updatedName() {
dd($this->items);
}
As far as I can tell, this should be working. What am I missing?
If $items is an array, you should know that the array index begins in 0. So, when you code this in the blade
<input wire:model="items.{{ $item->id }}.employee_id" type="text">
the $item->id value could be eg. 200, but the array doesn't have an index 200, then you are looping over array index, and not over model id values
When you reference this:
$this->items = User::all()->toArray();
the output is something like this:
array: 3 [
0 => array:6[
"id" => 34
"name" => "First Name"
"email" => "firstname@email.com"
//...
]
1 => array:6[
"id" => 47
"name" => "Second Name"
"email" => "secondname@email.com"
//...
]
2 => array:6[]
]
I think the correct way is to loop like:
@foreach($items as $key => $item)
<input wire:model="items.{{ $key }}.name" type="text">
<input wire:model="items.{{ $key }}.email" type="email">
@endforeach
and of course, like Qirel said, you should wrap it in a root element and add the wire:key directive
@foreach($items as $key => $item)
<div wire:key="input-group-{{ $key }}">
<input wire:model="items.{{ $key }}.name" type="text">
<input wire:model="items.{{ $key }}.email" type="email">
</div>
@endforeach