diff --git a/css/app.css b/css/app.css index 99904d953..35f7c3821 100644 --- a/css/app.css +++ b/css/app.css @@ -848,6 +848,21 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;} margin: 4px; } +.geocode-control div { + top: 50px; + width: 340px; + margin: 4px; + padding: 5px; +} +.geocode-control div span { + display: inline-block; + border-bottom: 1px solid #333; +} + +.geocode-control div span:hover { + background-color: #333; +} + /* Geolocator */ .geolocate-control { diff --git a/js/id/ui/geocoder.js b/js/id/ui/geocoder.js index 8883dc934..22c897653 100644 --- a/js/id/ui/geocoder.js +++ b/js/id/ui/geocoder.js @@ -8,19 +8,48 @@ iD.ui.geocoder = function() { d3.event.preventDefault(); var searchVal = this.value; d3.json('http://nominatim.openstreetmap.org/search/' + - encodeURIComponent(searchVal) + '?limit=10&format=json', function(err, resp) { - if (err) return hide(); - hide(); - if (!resp.length) { - return iD.ui.flash(context.container()) - .select('.content') - .append('h3') - .text('No location found for "' + searchVal + '"'); - } - var bounds = resp[0].boundingbox; - map.extent(iD.geo.Extent([parseFloat(bounds[3]), parseFloat(bounds[0])], [parseFloat(bounds[2]), parseFloat(bounds[1])])); - if (map.zoom() > 19) map.zoom(19); - }); + encodeURIComponent(searchVal) + '?limit=10&format=json', function (err, resp) { + if (err) return hide(); + if (!resp.length) { + return iD.ui.flash(context.container()) + .select('.content') + .append('h3') + .text('No location found for "' + searchVal + '"'); + } + if(resp.length > 1) { + var spans = resultsList.selectAll('span') + .data(resp, function (d) { return d.place_id; }); + spans.enter() + .append('span') + .text(function(d) { + return d.type.charAt(0).toUpperCase() + d.type.slice(1) + ': '; + }) + .append('a') + .text(function(d) { + if(d.display_name > 80) return d.display_name.substr(0,80) + '...'; + return d.display_name; + }) + .on('click', clickResult); + spans.exit().remove(); + resultsList.classed('hide',false); + } else { + var bounds = resp[0].boundingbox; + var extent = iD.geo.Extent([parseFloat(bounds[3]), parseFloat(bounds[0])], [parseFloat(bounds[2]), parseFloat(bounds[1])]); + applyBounds(extent); + } + }); + } + + function clickResult(data) { + var bounds = data.boundingbox; + var extent = iD.geo.Extent([parseFloat(bounds[3]), parseFloat(bounds[0])], [parseFloat(bounds[2]), parseFloat(bounds[1])]); + applyBounds(extent); + } + + function applyBounds(extent) { + hide(); + map.extent(extent); + if (map.zoom() > 19) map.zoom(19); } function clickoutside(selection) { @@ -38,6 +67,7 @@ iD.ui.geocoder = function() { function setVisible(show) { button.classed('active', show); gcForm.classed('hide', !show); + if (!show) resultsList.classed('hide', !show); if (show) inputNode.node().focus(); else inputNode.node().blur(); } @@ -55,6 +85,9 @@ iD.ui.geocoder = function() { .attr({ type: 'text', placeholder: t('geocoder.find_a_place') }) .on('keydown', keydown); + var resultsList = selection.append('div') + .attr('class','content fillD map-overlay hide'); + selection.call(clickoutside); }