Add marker popups
This commit is contained in:
19
resources/js/index.js
vendored
19
resources/js/index.js
vendored
@@ -8,6 +8,7 @@ import mapkit from './services/mapkit';
|
||||
import parser from './utils/parser';
|
||||
import {isDefined, logError} from './utils/helper';
|
||||
import './utils/customEventPolyfill';
|
||||
import {dispatchEventMapInitialized} from './utils/dispatchEvent';
|
||||
|
||||
const createMap = (element, createMap, createMarker) => {
|
||||
if (!isDefined(element)) {
|
||||
@@ -25,7 +26,7 @@ const createMap = (element, createMap, createMarker) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const markers = mapData.markers.map(markerData => createMarker(map, markerData));
|
||||
const markers = mapData.markers.map(markerData => createMarker(element, map, markerData));
|
||||
|
||||
return {
|
||||
map,
|
||||
@@ -39,26 +40,14 @@ const createMapService = service => {
|
||||
service.createMap,
|
||||
service.createMarker,
|
||||
);
|
||||
const selector = `[data-map-${service.NAME}]`;
|
||||
const selector = `[data-map-${service.name}]`;
|
||||
const elements = Array.prototype.slice.call(document.querySelectorAll(selector) || []);
|
||||
elements.forEach(element => {
|
||||
const data = createMapService(element);
|
||||
dispatchEvent(service.NAME, element, data);
|
||||
dispatchEventMapInitialized(service.name, element, data);
|
||||
});
|
||||
};
|
||||
|
||||
const dispatchEvent = (serviceName, element, data) => {
|
||||
const event = new CustomEvent('LaravelMapInitialized', {
|
||||
detail: {
|
||||
element: element,
|
||||
map: data.map,
|
||||
markers: data.markers || [],
|
||||
service: serviceName,
|
||||
},
|
||||
});
|
||||
window.dispatchEvent(event);
|
||||
};
|
||||
|
||||
window.onGoogleMapsReady = () => createMapService(google);
|
||||
|
||||
window.onYandexMapsReady = () => createMapService(yandex);
|
||||
|
||||
6
resources/js/services/bing.js
vendored
6
resources/js/services/bing.js
vendored
@@ -2,10 +2,10 @@ import {fadeElementIn, isDefined, logError, openUrl} from '../utils/helper';
|
||||
import 'leaflet-bing-layer';
|
||||
import {createMarker} from '../utils/leaflet';
|
||||
|
||||
// TODO: locales/culture
|
||||
const name = 'bing';
|
||||
|
||||
export default {
|
||||
NAME: 'bing',
|
||||
name,
|
||||
createMap(element, mapData) {
|
||||
if (!isDefined(window.L)) {
|
||||
logError('leaflet is undefined');
|
||||
@@ -29,5 +29,5 @@ export default {
|
||||
|
||||
return map;
|
||||
},
|
||||
createMarker,
|
||||
createMarker: createMarker.bind(null, name),
|
||||
}
|
||||
|
||||
23
resources/js/services/google.js
vendored
23
resources/js/services/google.js
vendored
@@ -1,7 +1,10 @@
|
||||
import {fadeElementIn, isDefined, logError, openUrl} from '../utils/helper';
|
||||
import {dispatchEventMarkerClicked} from '../utils/dispatchEvent';
|
||||
|
||||
const name = 'google';
|
||||
|
||||
export default {
|
||||
NAME: 'google',
|
||||
name,
|
||||
createMap(element, mapData) {
|
||||
if (!isDefined(window.google)) {
|
||||
logError('google is undefined');
|
||||
@@ -26,8 +29,8 @@ export default {
|
||||
|
||||
return map;
|
||||
},
|
||||
createMarker(map, markerData) {
|
||||
const {title, lat, lng, url, icon, iconSize, iconAnchor} = markerData;
|
||||
createMarker(element, map, markerData) {
|
||||
const {title, lat, lng, url, popup, icon, iconSize, iconAnchor} = markerData;
|
||||
|
||||
const markerOptions = {
|
||||
position: new window.google.maps.LatLng(lat, lng),
|
||||
@@ -50,11 +53,17 @@ export default {
|
||||
|
||||
const marker = new window.google.maps.Marker(markerOptions);
|
||||
|
||||
if (url) {
|
||||
marker.addListener('click', () => {
|
||||
marker.addListener('click', () => {
|
||||
dispatchEventMarkerClicked(name, element, map, marker);
|
||||
if (popup) {
|
||||
const infoWindow = new window.google.maps.InfoWindow({
|
||||
content: popup
|
||||
});
|
||||
infoWindow.open(map, marker);
|
||||
} else if (url) {
|
||||
openUrl(url);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return marker;
|
||||
},
|
||||
|
||||
41
resources/js/services/mapkit.js
vendored
41
resources/js/services/mapkit.js
vendored
@@ -1,7 +1,10 @@
|
||||
import {fadeElementIn, isDefined, logError} from '../utils/helper';
|
||||
import {fadeElementIn, isDefined, logError, openUrl} from '../utils/helper';
|
||||
import {dispatchEventMarkerClicked} from "../utils/dispatchEvent";
|
||||
|
||||
const name = 'mapkit';
|
||||
|
||||
export default {
|
||||
NAME: 'mapkit',
|
||||
name,
|
||||
createMap(element, mapData) {
|
||||
if (!isDefined(window.mapkit)) {
|
||||
logError('mapkit is undefined');
|
||||
@@ -11,14 +14,6 @@ export default {
|
||||
|
||||
window.mapkit.init({
|
||||
authorizationCallback(done) {
|
||||
/*
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', '/services/jwt');
|
||||
xhr.addEventListener('load', function() {
|
||||
done(this.responseText);
|
||||
});
|
||||
xhr.send();
|
||||
*/
|
||||
done(service.key);
|
||||
},
|
||||
});
|
||||
@@ -40,26 +35,13 @@ export default {
|
||||
|
||||
return map;
|
||||
},
|
||||
createMarker(map, markerData) {
|
||||
const {title, lat, lng, url, icon} = markerData;
|
||||
createMarker(element, map, markerData) {
|
||||
const {title, lat, lng, url, popup, icon} = markerData;
|
||||
|
||||
const coordinate = new window.mapkit.Coordinate(lat, lng);
|
||||
|
||||
const markerAnnotationOptions = {title};
|
||||
|
||||
if (url) {
|
||||
markerAnnotationOptions.callout = {
|
||||
calloutRightAccessoryForAnnotation: function() {
|
||||
const accessoryViewRight = document.createElement('a');
|
||||
accessoryViewRight.className = 'right-accessory-view';
|
||||
accessoryViewRight.href = url;
|
||||
accessoryViewRight.target = '_blank';
|
||||
accessoryViewRight.appendChild(document.createTextNode('ⓘ'));
|
||||
return accessoryViewRight;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (icon) {
|
||||
markerAnnotationOptions.glyphImage = {
|
||||
1: icon,
|
||||
@@ -68,6 +50,15 @@ export default {
|
||||
|
||||
const marker = new window.mapkit.MarkerAnnotation(coordinate, markerAnnotationOptions);
|
||||
|
||||
marker.addEventListener('select', event => {
|
||||
dispatchEventMarkerClicked(name, element, map, marker);
|
||||
if (popup) {
|
||||
// TODO
|
||||
} else if (url) {
|
||||
openUrl(url);
|
||||
}
|
||||
});
|
||||
|
||||
map.showItems([marker]); // TODO: map auto resize bugging if multiple markers
|
||||
|
||||
return marker;
|
||||
|
||||
5
resources/js/services/mapquest.js
vendored
5
resources/js/services/mapquest.js
vendored
@@ -7,9 +7,10 @@ import {createMarker} from '../utils/leaflet';
|
||||
// http://leaflet-extras.github.io/leaflet-providers/preview/
|
||||
|
||||
// TODO custom icons: https://leafletjs.com/examples/custom-icons/
|
||||
const name = 'mapquest';
|
||||
|
||||
export default {
|
||||
NAME: 'mapquest',
|
||||
name,
|
||||
createMap(element, mapData) {
|
||||
if (!isDefined(window.L)) {
|
||||
logError('leaflet is undefined');
|
||||
@@ -35,5 +36,5 @@ export default {
|
||||
|
||||
return map;
|
||||
},
|
||||
createMarker,
|
||||
createMarker: createMarker.bind(null, name),
|
||||
}
|
||||
|
||||
6
resources/js/services/osm.js
vendored
6
resources/js/services/osm.js
vendored
@@ -8,8 +8,10 @@ import {createMarker} from '../utils/leaflet';
|
||||
|
||||
// TODO custom icons: https://leafletjs.com/examples/custom-icons/
|
||||
|
||||
const name = 'osm';
|
||||
|
||||
export default {
|
||||
NAME: 'osm',
|
||||
name,
|
||||
createMap(element, mapData) {
|
||||
if (!isDefined(window.L)) {
|
||||
logError('leaflet is undefined');
|
||||
@@ -32,5 +34,5 @@ export default {
|
||||
|
||||
return map;
|
||||
},
|
||||
createMarker,
|
||||
createMarker: createMarker.bind(null, name),
|
||||
}
|
||||
|
||||
28
resources/js/services/yandex.js
vendored
28
resources/js/services/yandex.js
vendored
@@ -1,7 +1,10 @@
|
||||
import {isDefined, logError} from '../utils/helper';
|
||||
import {isDefined, logError, openUrl} from '../utils/helper';
|
||||
import {dispatchEventMarkerClicked} from '../utils/dispatchEvent';
|
||||
|
||||
const name = 'yandex';
|
||||
|
||||
export default {
|
||||
NAME: 'yandex',
|
||||
name,
|
||||
createMap(element, mapData) {
|
||||
if (!isDefined(window.ymaps)) {
|
||||
logError('ymaps is undefined');
|
||||
@@ -20,8 +23,8 @@ export default {
|
||||
|
||||
return map;
|
||||
},
|
||||
createMarker(map, markerData) {
|
||||
const {title, lat, lng, url, icon, iconSize, iconAnchor} = markerData;
|
||||
createMarker(element, map, markerData) {
|
||||
const {title, lat, lng, url, popup, icon, iconSize, iconAnchor} = markerData;
|
||||
|
||||
const placemarkProperties = {
|
||||
hintContent: title,
|
||||
@@ -40,13 +43,20 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
if (popup) {
|
||||
placemarkProperties.balloonContentBody = popup;
|
||||
}
|
||||
|
||||
const marker = new window.ymaps.Placemark([lat, lng], placemarkProperties, placemarkOptions);
|
||||
|
||||
// if (url) {
|
||||
// marker.addListener('click', () => {
|
||||
// openUrl(url);
|
||||
// });
|
||||
// }
|
||||
marker.events.add('click', e => {
|
||||
dispatchEventMarkerClicked(name, element, map, marker);
|
||||
if (popup) {
|
||||
// Handled with ballonContentBody
|
||||
} else if (url) {
|
||||
openUrl(url);
|
||||
}
|
||||
});
|
||||
|
||||
map.geoObjects.add(marker);
|
||||
|
||||
|
||||
23
resources/js/utils/dispatchEvent.js
vendored
Normal file
23
resources/js/utils/dispatchEvent.js
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
export function dispatchEventMapInitialized (serviceName, element, data) {
|
||||
const event = new CustomEvent('LaravelMaps:MapInitialized', {
|
||||
detail: {
|
||||
element: element,
|
||||
map: data.map,
|
||||
markers: data.markers || [],
|
||||
service: serviceName,
|
||||
},
|
||||
});
|
||||
window.dispatchEvent(event);
|
||||
}
|
||||
|
||||
export function dispatchEventMarkerClicked (serviceName, element, map, marker) {
|
||||
const event = new CustomEvent('LaravelMaps:MarkerClicked', {
|
||||
detail: {
|
||||
element: element,
|
||||
map: map,
|
||||
marker: marker,
|
||||
service: serviceName,
|
||||
},
|
||||
});
|
||||
window.dispatchEvent(event);
|
||||
}
|
||||
21
resources/js/utils/leaflet.js
vendored
21
resources/js/utils/leaflet.js
vendored
@@ -1,7 +1,8 @@
|
||||
import {openUrl} from './helper';
|
||||
import {dispatchEventMarkerClicked} from './dispatchEvent';
|
||||
|
||||
export function createMarker(map, markerData) {
|
||||
const {title, lat, lng, url, icon, iconSize, iconAnchor} = markerData;
|
||||
export function createMarker(service, element, map, markerData) {
|
||||
const {title, lat, lng, url, popup, icon, iconSize, iconAnchor} = markerData;
|
||||
|
||||
const markerOptions = {
|
||||
title,
|
||||
@@ -24,12 +25,18 @@ export function createMarker(map, markerData) {
|
||||
|
||||
const marker = window.L.marker([lat, lng], markerOptions);
|
||||
|
||||
if (url) {
|
||||
marker.on('click', event => {
|
||||
event.originalEvent.preventDefault();
|
||||
marker.on('click', event => {
|
||||
event.originalEvent.preventDefault();
|
||||
dispatchEventMarkerClicked(service, element, map, marker);
|
||||
if (popup) {
|
||||
window.L.popup()
|
||||
.setLatLng([lat, lng])
|
||||
.setContent(popup)
|
||||
.openOn(map);
|
||||
} else if (url) {
|
||||
openUrl(url);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
marker.addTo(map);
|
||||
|
||||
|
||||
28
resources/js/utils/parser.js
vendored
28
resources/js/utils/parser.js
vendored
@@ -1,4 +1,4 @@
|
||||
import {logError} from "./helper";
|
||||
import {logError} from './helper';
|
||||
|
||||
const parseMap = element => JSON.parse(
|
||||
element.dataset.mapGoogle
|
||||
@@ -21,15 +21,17 @@ const parseService = element => {
|
||||
const parseMarkers = element => {
|
||||
const markers = JSON.parse(element.dataset.mapMarkers) || [];
|
||||
return markers.map(marker => {
|
||||
const lat = parseFloat(marker.lat);
|
||||
const lng = parseFloat(marker.lng);
|
||||
const {title, url, icon, iconSize, iconAnchor} = marker;
|
||||
const lat = parseNumberFloat(marker.lat);
|
||||
const lng = parseNumberFloat(marker.lng);
|
||||
|
||||
const {title, url, popup, icon, iconSize, iconAnchor} = marker;
|
||||
|
||||
return {
|
||||
title,
|
||||
lat,
|
||||
lng,
|
||||
url,
|
||||
popup,
|
||||
icon,
|
||||
iconSize,
|
||||
iconAnchor,
|
||||
@@ -37,13 +39,25 @@ const parseMarkers = element => {
|
||||
});
|
||||
};
|
||||
|
||||
const parseNumberFloat = number => {
|
||||
return typeof number === 'string'
|
||||
? parseFloat(number)
|
||||
: number;
|
||||
};
|
||||
|
||||
const parseNumberInt = number => {
|
||||
return typeof number === 'string'
|
||||
? parseFloat(number)
|
||||
: number;
|
||||
};
|
||||
|
||||
export default {
|
||||
map(element) {
|
||||
try {
|
||||
const map = parseMap(element);
|
||||
const lat = parseFloat(map.lat);
|
||||
const lng = parseFloat(map.lng);
|
||||
const zoom = parseInt(map.zoom);
|
||||
const lat = parseNumberFloat(map.lat);
|
||||
const lng = parseNumberFloat(map.lng);
|
||||
const zoom = parseNumberInt(map.zoom);
|
||||
const service = parseService(element);
|
||||
const markers = parseMarkers(element);
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user