From 772eb0255272f3bc78e56e35a6580424ea9c0abb Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Tue, 4 Dec 2012 10:58:55 -0500 Subject: [PATCH] Taginfo autocomplete --- css/app.css | 11 ++++++ js/id/taginfo.js | 1 + js/id/ui/inspector.js | 4 +-- js/lib/d3.typeahead.js | 78 +++++++++++++++++++++++++----------------- 4 files changed, 60 insertions(+), 34 deletions(-) diff --git a/css/app.css b/css/app.css index bbe4cac7e..f9034d209 100644 --- a/css/app.css +++ b/css/app.css @@ -238,6 +238,17 @@ input#geocode-location { cursor: pointer; } +div.typeahead { + background:#fff; + padding:2px 4px; + width:148px; + border:1px solid #ccc; +} + +div.typeahead a { + display:block; +} + .modal { width:640px; height:550px; diff --git a/js/id/taginfo.js b/js/id/taginfo.js index 680dbe37a..4444bf52b 100644 --- a/js/id/taginfo.js +++ b/js/id/taginfo.js @@ -6,6 +6,7 @@ iD.taginfo = function() { d3.json(endpoint + 'db/keys/values?' + iD.Util.qsString({ key: key, + rp: 20, sortname: 'count_all', sortorder: 'desc', page: 1 diff --git a/js/id/ui/inspector.js b/js/id/ui/inspector.js index 96c6185a2..45d8e6df9 100644 --- a/js/id/ui/inspector.js +++ b/js/id/ui/inspector.js @@ -77,9 +77,9 @@ iD.Inspector = function() { .each(function(d, i) { var selection = this; if (i == 1) { - taginfo.values(d.key, function(vals) { + taginfo.values(d.key, function(err, data) { d3.select(selection).call(d3.typeahead() - .data(vals)); + .data(data.data)); }); } }); diff --git a/js/lib/d3.typeahead.js b/js/lib/d3.typeahead.js index 08703c86c..ad933b3bc 100644 --- a/js/lib/d3.typeahead.js +++ b/js/lib/d3.typeahead.js @@ -1,40 +1,55 @@ d3.typeahead = function() { - - var data = [], limit = 10; + var data; var typeahead = function(selection) { - var option_div = d3.select(document.body).append('div') - .attr({ - 'class': 'typeahead', - position: 'absolute', - left: selection.node().offsetLeft, - top: selection.node().offsetTop - }); + var container; + function setup() { + var rect = selection.node().getBoundingClientRect(); + d3.select(document.body) + .append('div').attr('class', 'typeahead') + .style({ + position: 'absolute', + left: rect.left + 'px', + top: rect.bottom + 'px' + }); + selection + .on('keyup', update); + } + + function hide() { + window.setTimeout(function() { + d3.selectAll('div.typeahead').remove(); + }, 500); + } selection - .on('keyup', function() { - var val = d3.select(d3.event.target).property('value'); - var matches = data.filter(function(d) { - return d.toLowerCase().indexOf(val) === 0; - }); - if (matches.length === 1 && matches[0] === val) { - matches = []; - } - var options = option_div.selectAll('a').data(matches); - options.enter() - .append('a') - .text(String) - .on('click', function(d) { - selection.property('value', d); - }); - options.exit().remove(); - }); - }; + .on('focus', setup) + .on('blur', hide); - typeahead.limit = function(_) { - if (!arguments.length) return limit; - limit = _; - return typeahead; + function update() { + var val = selection.property('value'), + matches = data.filter(function(d) { + return d.value.toLowerCase().indexOf(val) === 0; + }).map(function(d) { + return { value: d.value, description: d.description }; + }), + container = d3.select('div.typeahead') + .style('display', function() { + return matches.length ? 'block' : 'none'; + }), + options = container + .selectAll('a') + .data(matches, function(d) { return d.value; }); + + options.enter() + .append('a') + .text(function(d) { return d.value; }) + .attr('title', function(d) { return d.description; }) + .on('click', function(d) { + selection.property('value', d.value); + }); + options.exit().remove(); + } }; typeahead.data = function(_) { @@ -44,5 +59,4 @@ d3.typeahead = function() { }; return typeahead; - };