@@ -153,34 +153,6 @@ A ``Marker`` can be customized with an ``Icon`` instance, which can either be an
153153 icon: $icon
154154 ));
155155
156- Remove elements from Map
157- ~~~~~~~~~~~~~~~~~~~~~~~~
158-
159- It is possible to remove elements like ``Marker ``, ``Polygon `` and ``Polyline `` instances by using ``Map::remove*() `` methods::
160-
161- // Add elements
162- $map->addMarker($marker = new Marker(/* ... */));
163- $map->addPolygon($polygon = new Polygon(/* ... */));
164- $map->addPolyline($polyline = new Polyline(/* ... */));
165-
166- // And later, remove those elements
167- $map->removeMarker($marker);
168- $map->removePolygon($polygon);
169- $map->removePolyline($polyline);
170-
171- If unfortunately you were unable to store an element instance, you can still remove them by passing the identifier string::
172-
173- $map = new Map(/* ... */);
174- // Add elements
175- $map->addMarker(new Marker(id: 'my-marker', /* ... */));
176- $map->addPolygon(new Polygon(id: 'my-polygon', /* ... */));
177- $map->addPolyline(new Polyline(id: 'my-marker', /* ... */));
178-
179- // And later, remove those elements
180- $map->removeMarker('my-marker');
181- $map->removePolygon('my-polygon');
182- $map->removePolyline('my-marker');
183-
184156Add Polygons
185157~~~~~~~~~~~~
186158
@@ -215,6 +187,34 @@ You can add Polylines, which represents a path made by a series of ``Point`` ins
215187 ),
216188 ));
217189
190+ Remove elements from Map
191+ ~~~~~~~~~~~~~~~~~~~~~~~~
192+
193+ It is possible to remove elements like ``Marker ``, ``Polygon `` and ``Polyline `` instances by using ``Map::remove*() `` methods.
194+ It's useful when :ref: `using a Map inside a Live Component <map-live-component >`::
195+
196+ // Add elements
197+ $map->addMarker($marker = new Marker(/* ... */));
198+ $map->addPolygon($polygon = new Polygon(/* ... */));
199+ $map->addPolyline($polyline = new Polyline(/* ... */));
200+
201+ // And later, remove those elements
202+ $map->removeMarker($marker);
203+ $map->removePolygon($polygon);
204+ $map->removePolyline($polyline);
205+
206+ If you haven't stored the element instance, you can still remove them by passing the identifier string::
207+
208+ $map = new Map(/* ... */);
209+ // Add elements
210+ $map->addMarker(new Marker(id: 'my-marker', /* ... */));
211+ $map->addPolygon(new Polygon(id: 'my-polygon', /* ... */));
212+ $map->addPolyline(new Polyline(id: 'my-marker', /* ... */));
213+
214+ // And later, remove those elements
215+ $map->removeMarker('my-marker');
216+ $map->removePolygon('my-polygon');
217+ $map->removePolyline('my-marker');
218218
219219Render a map
220220------------
@@ -233,7 +233,6 @@ You can add custom HTML attributes too:
233233
234234 {{ ux_map(my_map, { style: 'height: 300px', id: 'events-map', class: 'mb-3' }) }}
235235
236-
237236 Twig Function ``ux_map() ``
238237~~~~~~~~~~~~~~~~~~~~~~~~~~
239238
@@ -308,6 +307,10 @@ Symfony UX Map allows you to extend its default behavior using a custom Stimulus
308307 this .element .addEventListener (' ux:map:marker:after-create' , this ._onMarkerAfterCreate );
309308 this .element .addEventListener (' ux:map:info-window:before-create' , this ._onInfoWindowBeforeCreate );
310309 this .element .addEventListener (' ux:map:info-window:after-create' , this ._onInfoWindowAfterCreate );
310+ this .element .addEventListener (' ux:map:polygon:before-create' , this ._onPolygonBeforeCreate );
311+ this .element .addEventListener (' ux:map:polygon:after-create' , this ._onPolygonAfterCreate );
312+ this .element .addEventListener (' ux:map:polyline:before-create' , this ._onPolylineBeforeCreate );
313+ this .element .addEventListener (' ux:map:polyline:after-create' , this ._onPolylineAfterCreate );
311314 }
312315
313316 disconnect () {
@@ -318,51 +321,114 @@ Symfony UX Map allows you to extend its default behavior using a custom Stimulus
318321 this .element .removeEventListener (' ux:map:marker:after-create' , this ._onMarkerAfterCreate );
319322 this .element .removeEventListener (' ux:map:info-window:before-create' , this ._onInfoWindowBeforeCreate );
320323 this .element .removeEventListener (' ux:map:info-window:after-create' , this ._onInfoWindowAfterCreate );
324+ this .element .removeEventListener (' ux:map:polygon:before-create' , this ._onPolygonBeforeCreate );
325+ this .element .removeEventListener (' ux:map:polygon:after-create' , this ._onPolygonAfterCreate );
326+ this .element .removeEventListener (' ux:map:polyline:before-create' , this ._onPolylineBeforeCreate );
327+ this .element .removeEventListener (' ux:map:polyline:after-create' , this ._onPolylineAfterCreate );
321328 }
322329
330+ /**
331+ * This event is triggered when the map is not created yet
332+ * You can use this event to configure the map before it is created
333+ */
323334 _onPreConnect (event ) {
324- // The map is not created yet
325- // You can use this event to configure the map before it is created
326335 console .log (event .detail .options );
327336 }
328337
338+ /**
339+ * This event is triggered when the map and all its elements (markers, info windows, ...) are created.
340+ * The instances depend on the renderer you are using.
341+ */
329342 _onConnect (event ) {
330- // The map, markers and infoWindows are created
331- // The instances depend on the renderer you are using
332343 console .log (event .detail .map );
333344 console .log (event .detail .markers );
334345 console .log (event .detail .infoWindows );
346+ console .log (event .detail .polygons );
347+ console .log (event .detail .polylines );
335348 }
336349
350+ /**
351+ * This event is triggered before creating a marker.
352+ * You can use this event to fine-tune it before its creation.
353+ */
337354 _onMarkerBeforeCreate (event ) {
338- // The marker is not created yet
339- // You can use this event to configure the marker before it is created
340355 console .log (event .detail .definition );
356+ // { title: 'Paris', position: { lat: 48.8566, lng: 2.3522 }, ... }
357+
358+ // Example: uppercase the marker title
359+ event .detail .definition .title = event .detail .definition .title .toUpperCase ();
341360 }
342361
362+ /**
363+ * This event is triggered after creating a marker.
364+ * You can access the created marker instance, which depends on the renderer you are using.
365+ */
343366 _onMarkerAfterCreate (event ) {
344- // The marker is created
345- // The instance depends on the renderer you are using
367+ // The marker instance
346368 console .log (event .detail .marker );
347369 }
348370
371+ /**
372+ * This event is triggered before creating an info window.
373+ * You can use this event to fine-tune the info window before its creation.
374+ */
349375 _onInfoWindowBeforeCreate (event ) {
350- // The infoWindow is not created yet
351- // You can use this event to configure the infoWindow before it is created
352376 console .log (event .detail .definition );
353- // The associated marker instance is also available
354- console .log (event .detail .marker );
377+ // { headerContent: 'Paris', content: 'The capital of France', ... }
355378 }
356379
380+ /**
381+ * This event is triggered after creating an info window.
382+ * You can access the created info window instance, which depends on the renderer you are using.
383+ */
357384 _onInfoWindowAfterCreate (event ) {
358- // The infoWindow is created
359- // The instance depends on the renderer you are using
385+ // The info window instance
360386 console .log (event .detail .infoWindow );
361- // The associated marker instance is also available
387+
388+ // The associated element instance is also available, e.g. a marker...
362389 console .log (event .detail .marker );
390+ // ... or a polygon
391+ console .log (event .detail .polygon );
392+ // ... or a polyline
393+ console .log (event .detail .polyline );
394+ }
395+
396+ /**
397+ * This event is triggered before creating a polygon.
398+ * You can use this event to fine-tune it before its creation.
399+ */
400+ _onPolygonBeforeCreate (event ) {
401+ console .log (event .detail .definition );
402+ // { title: 'My polygon', points: [ { lat: 48.8566, lng: 2.3522 }, { lat: 45.7640, lng: 4.8357 }, { lat: 43.2965, lng: 5.3698 }, ... ], ... }
403+ }
404+
405+ /**
406+ * This event is triggered after creating a polygon.
407+ * You can access the created polygon instance, which depends on the renderer you are using.
408+ */
409+ _onPolygonAfterCreate (event ) {
410+ // The polygon instance
411+ console .log (event .detail .polygon );
412+ }
413+
414+ /**
415+ * This event is triggered before creating a polyline.
416+ * You can use this event to fine-tune it before its creation.
417+ */
418+ _onPolylineBeforeCreate (event ) {
419+ console .log (event .detail .definition );
420+ // { title: 'My polyline', points: [ { lat: 48.8566, lng: 2.3522 }, { lat: 45.7640, lng: 4.8357 }, { lat: 43.2965, lng: 5.3698 }, ... ], ... }
363421 }
364- }
365422
423+ /**
424+ * This event is triggered after creating a polyline.
425+ * You can access the created polyline instance, which depends on the renderer you are using.
426+ */
427+ _onPolylineAfterCreate (event ) {
428+ // The polyline instance
429+ console .log (event .detail .polyline );
430+ }
431+ }
366432
367433 Then, you can use this controller in your template:
368434
@@ -376,6 +442,138 @@ Then, you can use this controller in your template:
376442 `Symfony UX Map Google Maps brige docs `_ to learn about the exact code
377443 needed to customize the markers.
378444
445+ Advanced: Low-level options
446+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
447+
448+ UX Map is renderer-agnostic and provides a high-level API to configure
449+ maps and their elements. However, you might occasionally find this
450+ abstraction limiting and need to configure low-level options directly.
451+
452+ Fortunately, you can customize these low-level options through the UX Map
453+ events ``ux:map:*:before-create `` using the special ``rawOptions `` property:
454+
455+ .. code-block :: javascript
456+
457+ // assets/controllers/mymap_controller.js
458+
459+ import { Controller } from ' @hotwired/stimulus' ;
460+
461+ export default class extends Controller {
462+ connect () {
463+ this .element .addEventListener (' ux:map:marker:before-create' , this ._onMarkerBeforeCreate );
464+ this .element .addEventListener (' ux:map:info-window:before-create' , this ._onInfoWindowBeforeCreate );
465+ this .element .addEventListener (' ux:map:polygon:before-create' , this ._onPolygonBeforeCreate );
466+ this .element .addEventListener (' ux:map:polyline:before-create' , this ._onPolylineBeforeCreate );
467+ }
468+
469+ _onMarkerBeforeCreate (event ) {
470+ // When using Google Maps, to configure a `google.maps.AdvancedMarkerElement`
471+ event .detail .definition .rawOptions = {
472+ gmpDraggable: true ,
473+ // ...
474+ };
475+
476+ // When using Leaflet, to configure a `L.Marker` instance
477+ event .detail .definition .rawOptions = {
478+ riseOnHover: true ,
479+ // ...
480+ };
481+ }
482+
483+ _onInfoWindowBeforeCreate (event ) {
484+ // When using Google Maps, to configure a `google.maps.InfoWindow` instance
485+ event .detail .definition .rawOptions = {
486+ maxWidth: 200 ,
487+ // ...
488+ };
489+
490+ // When using Leaflet, to configure a `L.Popup` instance
491+ event .detail .definition .rawOptions = {
492+ direction: ' left' ,
493+ // ...
494+ };
495+ }
496+
497+ _onPolygonBeforeCreate (event ) {
498+ // When using Google Maps, to configure a `google.maps.Polygon`
499+ event .detail .definition .rawOptions = {
500+ strokeColor: ' red' ,
501+ // ...
502+ };
503+
504+ // When using Leaflet, to configure a `L.Polygon`
505+ event .detail .definition .rawOptions = {
506+ color: ' red' ,
507+ // ...
508+ };
509+ }
510+
511+ _onPolylineBeforeCreate (event ) {
512+ // When using Google Maps, to configure a `google.maps.Polyline`
513+ event .detail .definition .rawOptions = {
514+ strokeColor: ' red' ,
515+ // ...
516+ };
517+
518+ // When using Leaflet, to configure a `L.Polyline`
519+ event .detail .definition .rawOptions = {
520+ color: ' red' ,
521+ // ...
522+ };
523+ }
524+ }
525+
526+ Advanced: Passing extra data from PHP to the Stimulus controller
527+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
528+
529+ For greater customization and extensibility, you can pass additional data from PHP
530+ to the Stimulus controller. This can be useful when associating extra information
531+ with a specific marker; for example, indicating the type of location it represents.
532+
533+ These additional data points are defined and used exclusively by you; UX Map
534+ only forwards them to the Stimulus controller.
535+
536+ To pass extra data from PHP to the Stimulus controller, you must use the ``extra `` property
537+ available in ``Marker ``, ``InfoWindow ``, ``Polygon `` and ``Polyline `` instances::
538+
539+ $map->addMarker(new Marker(
540+ position: new Point(48.822248, 2.337338),
541+ title: 'Paris - Parc Montsouris',
542+ extra: [
543+ 'type' => 'Park',
544+ // ...
545+ ],
546+ ));
547+
548+ On the JavaScript side, you can access your extra data via the
549+ ``event.detail.definition.extra `` object, available in the
550+ ``ux:map:*:before-create `` and ``ux:map:*:after-create `` events:
551+
552+ .. code-block :: javascript
553+
554+ // assets/controllers/mymap_controller.js
555+
556+ import { Controller } from ' @hotwired/stimulus' ;
557+
558+ export default class extends Controller {
559+
560+ // ...
561+
562+ _onMarkerBeforeCreate (event ) {
563+ console .log (event .detail .definition .extra );
564+ // { type: 'Park', ...}
565+ }
566+
567+ _onMarkerAfterCreate (event ) {
568+ console .log (event .detail .definition .extra );
569+ // { type: 'Park', ...}
570+ }
571+
572+ // ...
573+ }
574+
575+ .. _map-live-component :
576+
379577Usage with Live Components
380578--------------------------
381579
0 commit comments