I'm currently developping a project with Livewire and AlpineJS.
I have to use a div with contenteditable set to "true" to access and modify my data model.
What I want
I would like to share the state between Livewire And Alpine using @entangle.
My code
My code is in two parts. The first-part rely on a full-Page component where I simply register an array of $fruits. The second, is a component containing a "form" allowing me to access and modify the data through @entangle and a div with contenteditable set to true.
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class ListFruit extends Component
{
protected $listeners = ['addFruit'];
public array $fruits = [];
public function mount()
{
$this->addFruit();
}
public function addFruit()
{
$this->fruits[] = $this->makeBlankFruit();
}
public function makeBlankFruit(): array
{
return [
'type' => '',
'color' => ''
];
}
public function render()
{
return view('livewire.list-fruit');
}
}
The views/livewire/list-fruit.blade.php file
<div class="w-full container mx-auto">
<h3 class="text-2xl font-sembibold">
Fruits
</h3>
<div id="fruits">
@foreach($fruits as $fruitIndex=> $fruit)
<livewire:fruit :fruitIndex="$fruitIndex" :fruit="fruit" :wire:key="$fruitIndex" >
@endforeach
</div>
</div>
Fruit Component
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class Fruit extends Component
{
public array $fruit = [];
public string $fruitIndex;
public function render()
{
return view('livewire.fruit');
}
}
views/livewire/fruit.blade.php file
<div x-data="{type: @entangle('fruit.type'), color: @entangle('fruit.color')}"
x-init="console.log(type)"
>
<div>
<div x-on:blur="type = $event.target.innerHTML" contenteditable="true">{{ $fruit['type'] }}</div>
<div x-on:blur="color = $event.target.innerHTML" contenteditable="true">{{ $fruit['color'] }}</div>
</div>
<div>
$type @ Livewire: {{ $fruit['type'] }}
$color @ Livewire: {{ $fruit['color'] }}
</div>
<div>
type @ AlpineJS: <span x-text="type"></span>
color @ AlpineJS: <span x-text="color"></span>
</div>
</div>
If I had only one array with some properties in my main component, let's say :
public array $fruit = [
'type' => '',
'color' => '',
];
I would be able to access them with my fruit.blade.php
I also tried to do something like this.
{type: @entangle('fruits.'. $fruitIndex.'.color'), color: @entangle('fruits.'. $fruitIndex.'.type')}
What I obtained
In my AlpineJs component I read an [object Object] proxy and when modifying my fruit.color or fruit.type property the livewire part isn't updated.
I don't know why. In my final attempt, I tried to separate my fruits into multiple sub-components allowing me to work on a single array.
I'm a looking at a dead end, so thank you in advance for your help. Tanuki