afterStateUpdated() Not Triggering in a Custom Filament Field

Thread Title: Issue with afterStateUpdated() Not Triggering in a Custom Filament Field with OpenLayers Body of the Post: Hello everyone, I am working with Filament to develop a form that includes an OpenLayers map. I have a custom field that allows users to select a location on the map, and I need the afterStateUpdated() method to trigger every time the latitude or longitude is updated via a click on the map. Here is the JavaScript snippet:
this.map.on('singleclick', (event) => {
const coords = ol.proj.toLonLat(event.coordinate);
this.$wire.set('latitude', coords[1]);
this.$wire.set('longitude', coords[0]);
});

this.map.on('singleclick', (event) => {
const coords = ol.proj.toLonLat(event.coordinate);
this.$wire.set('latitude', coords[1]);
this.$wire.set('longitude', coords[0]);
});

- Field Configuration in Filament: My field is configured to handle updates to these properties. However, even though the latitude and longitude properties update correctly, the afterStateUpdated() method that I expect to trigger does not. Here is the relevant configuration:
OpenLayers::make('prueba')
->height(350)
->latitude(-50.9032800)
->longitude(-23.1881600)
->afterStateUpdated(function ($state, Forms\Get $get, Forms\Set $set) {
// set the coords here
});

OpenLayers::make('prueba')
->height(350)
->latitude(-50.9032800)
->longitude(-23.1881600)
->afterStateUpdated(function ($state, Forms\Get $get, Forms\Set $set) {
// set the coords here
});

Problem: Despite the latitude and longitude properties updating correctly, the afterStateUpdated() method does not trigger as expected. I would like this method to fire to perform additional logic every time the coordinates change through a map click. Does anyone have experience with this kind of setup or any suggestions on how I might ensure that afterStateUpdated() triggers correctly when updating coordinates? I would appreciate any help or suggestions.
Solution:
Solved, change the implementation to, and now works. ```javascript <script src="https://cdn.jsdelivr.net/npm/ol@9.1.0/dist/ol.js"></script> <link href="https://cdn.jsdelivr.net/npm/ol@9.1.0/ol.min.css" rel="stylesheet">...
Jump to solution
2 Replies
Chaloman
Chaloman3mo ago
Here the complete template
<script src="https://cdn.jsdelivr.net/npm/ol@9.1.0/dist/ol.js"></script>
<link href="https://cdn.jsdelivr.net/npm/ol@9.1.0/ol.min.css" rel="stylesheet">

<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
@php
$latitude = $getLatitude();
$longitude = $getLongitude();
$height = $getHeight() . "px";
$zoom = $getZoom();
@endphp

<div
x-data="{
state: $wire.entangle('{{ $getStatePath() }}'),
init() {
this.map = new ol.Map({
target: this.$refs.map,
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
center: ol.proj.fromLonLat([{{ $longitude }}, {{ $latitude }}]),
zoom: {{ $zoom }}
})
});

this.map.on('singleclick', (event) => {

const coords = ol.proj.toLonLat(event.coordinate);
console.log(coords);
$wire.set('latitude', coords[1]);
$wire.set('longitude', coords[0]);
});
}
}"
x-init="init"
wire:ignore
>
<div x-ref="map"
class="w-full"
style="
height: {{ $height }};
min-height: 30vh;
z-index: 1 !important;
"
>
</div>
</div>
</x-dynamic-component>
<script src="https://cdn.jsdelivr.net/npm/ol@9.1.0/dist/ol.js"></script>
<link href="https://cdn.jsdelivr.net/npm/ol@9.1.0/ol.min.css" rel="stylesheet">

<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
@php
$latitude = $getLatitude();
$longitude = $getLongitude();
$height = $getHeight() . "px";
$zoom = $getZoom();
@endphp

<div
x-data="{
state: $wire.entangle('{{ $getStatePath() }}'),
init() {
this.map = new ol.Map({
target: this.$refs.map,
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
center: ol.proj.fromLonLat([{{ $longitude }}, {{ $latitude }}]),
zoom: {{ $zoom }}
})
});

this.map.on('singleclick', (event) => {

const coords = ol.proj.toLonLat(event.coordinate);
console.log(coords);
$wire.set('latitude', coords[1]);
$wire.set('longitude', coords[0]);
});
}
}"
x-init="init"
wire:ignore
>
<div x-ref="map"
class="w-full"
style="
height: {{ $height }};
min-height: 30vh;
z-index: 1 !important;
"
>
</div>
</div>
</x-dynamic-component>
Solution
Chaloman
Chaloman3mo ago
Solved, change the implementation to, and now works.
<script src="https://cdn.jsdelivr.net/npm/ol@9.1.0/dist/ol.js"></script>
<link href="https://cdn.jsdelivr.net/npm/ol@9.1.0/ol.min.css" rel="stylesheet">

<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
@php
$latitude = $getLatitude();
$longitude = $getLongitude();
$height = $getHeight() . "px";
$zoom = $getZoom();
@endphp

<div
x-data="{state: $wire.entangle('{{ $getStatePath() }}')}"
x-init="
const map = new ol.Map({
target: $refs.map,
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
center: ol.proj.fromLonLat([{{ $longitude }}, {{ $latitude }}]),
zoom: {{ $zoom }}
})
});

map.on('singleclick', (event) => {
const coords = ol.proj.toLonLat(event.coordinate);
const [lat, lng] = coords;
state = {lat, lng};
$wire.set('latitude', lat);
$wire.set('longitude', lng);
});
"
wire:ignore
>
<div x-ref="map"
class="w-full"
style="
height: {{ $height }};
min-height: 30vh;
z-index: 1 !important;
"
>
</div>
</div>
</x-dynamic-component>
<script src="https://cdn.jsdelivr.net/npm/ol@9.1.0/dist/ol.js"></script>
<link href="https://cdn.jsdelivr.net/npm/ol@9.1.0/ol.min.css" rel="stylesheet">

<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
@php
$latitude = $getLatitude();
$longitude = $getLongitude();
$height = $getHeight() . "px";
$zoom = $getZoom();
@endphp

<div
x-data="{state: $wire.entangle('{{ $getStatePath() }}')}"
x-init="
const map = new ol.Map({
target: $refs.map,
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
center: ol.proj.fromLonLat([{{ $longitude }}, {{ $latitude }}]),
zoom: {{ $zoom }}
})
});

map.on('singleclick', (event) => {
const coords = ol.proj.toLonLat(event.coordinate);
const [lat, lng] = coords;
state = {lat, lng};
$wire.set('latitude', lat);
$wire.set('longitude', lng);
});
"
wire:ignore
>
<div x-ref="map"
class="w-full"
style="
height: {{ $height }};
min-height: 30vh;
z-index: 1 !important;
"
>
</div>
</div>
</x-dynamic-component>