@@ -153,34 +153,6 @@ A ``Marker`` can be customized with an ``Icon`` instance, which can either be an
153
153
icon: $icon
154
154
));
155
155
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
-
184
156
Add Polygons
185
157
~~~~~~~~~~~~
186
158
@@ -215,6 +187,34 @@ You can add Polylines, which represents a path made by a series of ``Point`` ins
215
187
),
216
188
));
217
189
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');
218
218
219
219
Render a map
220
220
------------
@@ -233,7 +233,6 @@ You can add custom HTML attributes too:
233
233
234
234
{{ ux_map(my_map, { style: 'height: 300px', id: 'events-map', class: 'mb-3' }) }}
235
235
236
-
237
236
Twig Function ``ux_map() ``
238
237
~~~~~~~~~~~~~~~~~~~~~~~~~~
239
238
@@ -308,6 +307,10 @@ Symfony UX Map allows you to extend its default behavior using a custom Stimulus
308
307
this .element .addEventListener (' ux:map:marker:after-create' , this ._onMarkerAfterCreate );
309
308
this .element .addEventListener (' ux:map:info-window:before-create' , this ._onInfoWindowBeforeCreate );
310
309
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 );
311
314
}
312
315
313
316
disconnect () {
@@ -318,51 +321,114 @@ Symfony UX Map allows you to extend its default behavior using a custom Stimulus
318
321
this .element .removeEventListener (' ux:map:marker:after-create' , this ._onMarkerAfterCreate );
319
322
this .element .removeEventListener (' ux:map:info-window:before-create' , this ._onInfoWindowBeforeCreate );
320
323
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 );
321
328
}
322
329
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
+ */
323
334
_onPreConnect (event ) {
324
- // The map is not created yet
325
- // You can use this event to configure the map before it is created
326
335
console .log (event .detail .options );
327
336
}
328
337
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
+ */
329
342
_onConnect (event ) {
330
- // The map, markers and infoWindows are created
331
- // The instances depend on the renderer you are using
332
343
console .log (event .detail .map );
333
344
console .log (event .detail .markers );
334
345
console .log (event .detail .infoWindows );
346
+ console .log (event .detail .polygons );
347
+ console .log (event .detail .polylines );
335
348
}
336
349
350
+ /**
351
+ * This event is triggered before creating a marker.
352
+ * You can use this event to fine-tune it before its creation.
353
+ */
337
354
_onMarkerBeforeCreate (event ) {
338
- // The marker is not created yet
339
- // You can use this event to configure the marker before it is created
340
355
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 ();
341
360
}
342
361
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
+ */
343
366
_onMarkerAfterCreate (event ) {
344
- // The marker is created
345
- // The instance depends on the renderer you are using
367
+ // The marker instance
346
368
console .log (event .detail .marker );
347
369
}
348
370
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
+ */
349
375
_onInfoWindowBeforeCreate (event ) {
350
- // The infoWindow is not created yet
351
- // You can use this event to configure the infoWindow before it is created
352
376
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', ... }
355
378
}
356
379
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
+ */
357
384
_onInfoWindowAfterCreate (event ) {
358
- // The infoWindow is created
359
- // The instance depends on the renderer you are using
385
+ // The info window instance
360
386
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...
362
389
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 }, ... ], ... }
363
421
}
364
- }
365
422
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
+ }
366
432
367
433
Then, you can use this controller in your template:
368
434
@@ -376,6 +442,138 @@ Then, you can use this controller in your template:
376
442
`Symfony UX Map Google Maps brige docs `_ to learn about the exact code
377
443
needed to customize the markers.
378
444
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
+
379
577
Usage with Live Components
380
578
--------------------------
381
579
0 commit comments