tourgent-ember-g-map
Version:
An ember-cli addon for integration with google maps.
171 lines (138 loc) • 4.4 kB
JavaScript
import Ember from 'ember';
import layout from '../templates/components/g-map-infowindow';
import GMapComponent from './g-map';
import GMapMarkerComponent from './g-map-marker';
const { isEmpty, isPresent, observer, computed, run, assert, typeOf } = Ember;
const OPEN_CLOSE_EVENTS = Ember.A(
[ 'click', 'dblclick', 'rightclick', 'mouseover', 'mouseout' ]
);
const GMapInfowindowComponent = Ember.Component.extend({
layout: layout,
classNames: ['g-map-marker'],
map: computed.alias('mapContext.map'),
marker: computed.alias('mapContext.marker'),
init() {
this._super(arguments);
const mapContext = this.get('mapContext');
const hasMap = mapContext instanceof GMapComponent;
const hasMarker = mapContext instanceof GMapMarkerComponent;
assert('Must be inside {{#g-map}} or {{#g-map-marker}} components with context set',
hasMarker || hasMap);
this.set('hasMarker', hasMarker);
},
didInsertElement() {
this._super();
if (isEmpty(this.get('infowindow'))) {
const infowindow = this.buildInfowindow();
this.set('infowindow', infowindow);
}
this.setPosition();
this.setMap();
this.setMarker();
this.setOptions();
},
willDestroyElement() {
this.close();
if (this.get('hasMarker')) {
this.get('mapContext').unregisterInfowindow();
}
},
optionsChanged: observer('disableAutoPan', 'maxWidth', 'pixelOffset', function() {
run.once(this, 'setOptions');
}),
setOptions() {
const infowindow = this.get('infowindow');
const options = ['disableAutoPan', 'maxWidth', 'pixelOffset'];
const infoWindowOptions = {};
for (let i = 0; i < options.length; i++) {
const value = this.get(options[i]);
if (isPresent(value)) {
infoWindowOptions[options[i]] = value;
}
}
if (isPresent(infowindow) && Object.keys(infoWindowOptions).length !== 0) {
infowindow.setOptions(infoWindowOptions);
}
},
buildInfowindow() {
const infowindow = new google.maps.InfoWindow({
content: this.get('element')
});
if (isPresent(this.get('attrs.onClose'))) {
infowindow.addListener('closeclick', () => this.handleCloseClickEvent());
}
return infowindow;
},
handleCloseClickEvent() {
const { onClose } = this.attrs;
if (typeOf(onClose) === 'function') {
onClose();
} else {
this.sendAction('onClose');
}
},
open() {
const infowindow = this.get('infowindow');
const map = this.get('map');
const marker = this.get('marker');
this.set('isOpen', true);
if (isPresent(map) && isPresent(marker)) {
infowindow.open(map, marker);
} else if (isPresent(map)) {
infowindow.open(map);
}
},
close() {
const infowindow = this.get('infowindow');
if (isPresent(infowindow)) {
this.set('isOpen', false);
infowindow.close();
}
},
mapWasSet: observer('map', function() {
run.once(this, 'setMap');
}),
setMap() {
if (this.get('hasMarker') === false) {
this.open();
}
},
markerWasSet: observer('marker', function() {
run.once(this, 'setMarker');
}),
setMarker() {
const map = this.get('map');
const marker = this.get('marker');
const context = this.get('mapContext');
const infowindow = this.get('infowindow');
if (isPresent(infowindow) && isPresent(map) && isPresent(marker)) {
const openEvent = this.retrieveOpenEvent();
const closeEvent = this.retrieveCloseEvent();
context.registerInfowindow(this, openEvent, closeEvent);
}
},
coordsChanged: observer('lat', 'lng', function() {
run.once(this, 'setPosition');
}),
setPosition() {
const infowindow = this.get('infowindow');
const lat = this.get('lat');
const lng = this.get('lng');
if (isPresent(infowindow) && isPresent(lat) && isPresent(lng)) {
const position = new google.maps.LatLng(lat, lng);
infowindow.setPosition(position);
}
},
retrieveOpenEvent() {
const openEvent = this.get('openOn');
return OPEN_CLOSE_EVENTS.contains(openEvent) ? openEvent : 'click';
},
retrieveCloseEvent() {
const closeEvent = this.get('closeOn');
return OPEN_CLOSE_EVENTS.contains(closeEvent) ? closeEvent : null;
}
});
GMapInfowindowComponent.reopenClass({
positionalParams: ['mapContext']
});
export default GMapInfowindowComponent;