In Laravel 10/ livewire 3 / tailwindcss 3 app I need to make several dynamic checkboxes, where user can select several elements and I defined in a component:
namespace App\Livewire;
use App\Enums\ReactionActionEnum;
use App\Enums\AppImageUsedInSubscriptionEnum;
use Livewire\Component;
class UserReaction extends Component
{
public int $id;
public string $dataType;
public array $reactionActions = [];
public function mount(int $id, string $dataType)
{
$this->id = $id;
$this->dataType = $dataType;
$reactionActions = ReactionActionEnum::getSelectionItems();
$this->reactionActions = [];
foreach ($reactionActions as $key => $label)
$this->reactionActions[] = [
'key' => $key,
'label' => $label,
'checked' => false,
];
}
public function render()
{
return view('livewire.user-reaction');
}
public function updated($key, $value)
{
\Log::info(varDump($key, ' -1 updated $key::')); // THIS METHOD IS NOT EVEN CALLED
\Log::info(varDump($value, ' -1 updated $value::'));
}
}
and in blade file :
$reactionActions:: {{ print_r($reactionActions, true) }}
@foreach($reactionActions as $reactionAction)
<div class="relative inline-block w-10 mr-2 align-middle select-none transition duration-200 ease-in">
<label for="reaction_actions">{{ $reactionAction['label'] }}</label>
<input type="checkbox" wire:model="reactionActions.{{ $reactionAction['key'] }}" name="reaction_actions" value="{{ $reactionAction['key'] }}">
</div>
@endforeach
I expected when checkbox is clicked checked property of $reactionAction array would be changed and/or updated method would be raised. But this did not happen.
How can I make it working ?
UPDATED CODE :
$reactionActions var is created based on enum :
$reactionActions = ReactionActionEnum::getSelectionItems();
$this->reactionActions = [];
foreach ($reactionActions as $key => $label)
$this->reactionActions[] = [
'key' => $key,
'label' => $label,
'checked' => false,
];
\Log::info(varDump($this->reactionActions, ' -1 $this->reactionActions::'));
ande checking debug info I see that checked rendered as empty string(boll type is lost >) :
Array
(
[0] => Array
(
[key] => 1
[label] => Like
[checked] =>
)
[1] => Array
(
[key] => 2
[label] => Love
[checked] =>
)
[2] => Array
(
[key] => 3
[label] => Dislike
[checked] =>
)
[3] => Array
(
[key] => 4
[label] => Hate
[checked] =>
)
In I used ".live" : I got different error :
The same error with uncommented label
I am not sure if I need to use "checked" key in :
<input type="checkbox" wire:model.live="reactionActions.{{ $reactionAction['checked'] }}" name="reaction_actions" value="{{ $reactionAction['key'] }}">
But I got the same error.
In Livewire 3 wire:model is deferred by default. To allow a contextual response you can use instead wire:model.live
To let the loop work properly, a wire:key valued with an unique key is also needed, otherwise the view could be updated in an inconsistent way. In my example I use $reactionAction['key'] supposing that it's a unique value, if not you must choose a different value, e.g. a record id
@foreach($reactionActions as $reactionAction)
<div class="relative inline-block w-10 mr-2 align-middle select-none transition duration-200 ease-in"
wire:key="{{ $reactionAction['key'] }}"
>
<label>
{{ $reactionAction['label'] }}
<input type="checkbox"
wire:model.live="reactionActions.{{ $reactionAction['key'] }}"
name="reaction_actions"
value="{{ $reactionAction['key'] }}"
>
</label>
</div>
@endforeach
Here I have also fixed the labels
Note that your wire:model value could be not properly set: take a look here for the details
The fact that clicking on a checkbox a call to the backend is made, means that now the event is intercepted.
As already suggested, the way you reference the checkboxes is not properly set, that is the cause of the error. If you want to maintain your data structure, you can consider evaluating each checkbox as a checkbox in its own right, so the view portion will become:
@foreach($reactionActions as $index => $reactionAction)
<div class="some-classes" wire:key="actions-{{$reactionAction['key']}}">
<label>
{{ $reactionAction['label']}}
<input type="checkbox"
wire:model.live="reactionActions.{{$index}}.checked" {{-- NOTE THIS --}}
>
</label>
</div>
@endforeach
Also the output that you are showing is generated by print_r which outputs false and null values as empty strings (like echo does), if you want to see those values printed, you can use var_export().
I don't know where your varDump() function comes from, anyway a working updated() method to log the changes can be:
public function updated($varName, $value)
{
Log::info("key: $varName");
Log::info("value: $value (" . var_export($value, true) . ')');
}