Skip to content

Commit 4566c7c

Browse files
committed
[Map][Docs] Improve "Interact with the map" section
1 parent d097c34 commit 4566c7c

File tree

1 file changed

+243
-45
lines changed

1 file changed

+243
-45
lines changed

doc/index.rst

+243-45
Original file line numberDiff line numberDiff line change
@@ -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-
184156
Add 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

219219
Render 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+
379577
Usage with Live Components
380578
--------------------------
381579

0 commit comments

Comments
 (0)