leaflet-routing-machine
Version:
147 lines (124 loc) • 4.18 kB
JavaScript
(function() {
'use strict';
var L = require('leaflet');
var Autocomplete = require('./autocomplete');
var Localization = require('./localization');
function selectInputText(input) {
if (input.setSelectionRange) {
// On iOS, select() doesn't work
input.setSelectionRange(0, 9999);
} else {
// On at least IE8, setSeleectionRange doesn't exist
input.select();
}
}
module.exports = L.Class.extend({
includes: ((typeof L.Evented !== 'undefined' && L.Evented.prototype) || L.Mixin.Events),
options: {
createGeocoder: function(i, nWps, options) {
var container = L.DomUtil.create('div', 'leaflet-routing-geocoder'),
input = L.DomUtil.create('input', '', container),
remove = options.addWaypoints ? L.DomUtil.create('span', 'leaflet-routing-remove-waypoint', container) : undefined;
input.disabled = !options.addWaypoints;
return {
container: container,
input: input,
closeButton: remove
};
},
geocoderPlaceholder: function(i, numberWaypoints, geocoderElement) {
var l = new Localization(geocoderElement.options.language).localize('ui');
return i === 0 ?
l.startPlaceholder :
(i < numberWaypoints - 1 ?
L.Util.template(l.viaPlaceholder, {viaNumber: i}) :
l.endPlaceholder);
},
geocoderClass: function() {
return '';
},
waypointNameFallback: function(latLng) {
var ns = latLng.lat < 0 ? 'S' : 'N',
ew = latLng.lng < 0 ? 'W' : 'E',
lat = (Math.round(Math.abs(latLng.lat) * 10000) / 10000).toString(),
lng = (Math.round(Math.abs(latLng.lng) * 10000) / 10000).toString();
return ns + lat + ', ' + ew + lng;
},
maxGeocoderTolerance: 200,
autocompleteOptions: {},
language: 'en',
},
initialize: function(wp, i, nWps, options) {
L.setOptions(this, options);
var g = this.options.createGeocoder(i, nWps, this.options),
closeButton = g.closeButton,
geocoderInput = g.input;
geocoderInput.setAttribute('placeholder', this.options.geocoderPlaceholder(i, nWps, this));
geocoderInput.className = this.options.geocoderClass(i, nWps);
this._element = g;
this._waypoint = wp;
this.update();
// This has to be here, or geocoder's value will not be properly
// initialized.
// TODO: look into why and make _updateWaypointName fix this.
geocoderInput.value = wp.name;
L.DomEvent.addListener(geocoderInput, 'click', function() {
selectInputText(this);
}, geocoderInput);
if (closeButton) {
L.DomEvent.addListener(closeButton, 'click', function() {
this.fire('delete', { waypoint: this._waypoint });
}, this);
}
new Autocomplete(geocoderInput, function(r) {
geocoderInput.value = r.name;
wp.name = r.name;
wp.latLng = r.center;
this.fire('geocoded', { waypoint: wp, value: r });
}, this, L.extend({
resultFn: this.options.geocoder.geocode,
resultContext: this.options.geocoder,
autocompleteFn: this.options.geocoder.suggest,
autocompleteContext: this.options.geocoder
}, this.options.autocompleteOptions));
},
getContainer: function() {
return this._element.container;
},
setValue: function(v) {
this._element.input.value = v;
},
update: function(force) {
var wp = this._waypoint,
wpCoords;
wp.name = wp.name || '';
if (wp.latLng && (force || !wp.name)) {
wpCoords = this.options.waypointNameFallback(wp.latLng);
if (this.options.geocoder && this.options.geocoder.reverse) {
this.options.geocoder.reverse(wp.latLng, 67108864 /* zoom 18 */, function(rs) {
if (rs.length > 0 && rs[0].center.distanceTo(wp.latLng) < this.options.maxGeocoderTolerance) {
wp.name = rs[0].name;
} else {
wp.name = wpCoords;
}
this._update();
}, this);
} else {
wp.name = wpCoords;
this._update();
}
}
},
focus: function() {
var input = this._element.input;
input.focus();
selectInputText(input);
},
_update: function() {
var wp = this._waypoint,
value = wp && wp.name ? wp.name : '';
this.setValue(value);
this.fire('reversegeocoded', {waypoint: wp, value: value});
}
});
})();