diff --git a/index.html b/index.html
index 8428b300f..0d917d083 100644
--- a/index.html
+++ b/index.html
@@ -17,6 +17,7 @@
+
diff --git a/js/id/connection.js b/js/id/connection.js
index baf767c6a..7e81fd779 100644
--- a/js/id/connection.js
+++ b/js/id/connection.js
@@ -131,16 +131,16 @@ iD.Connection = function() {
});
}
- connection.url = function(x) {
+ connection.url = function(_) {
if (!arguments.length) return apiURL;
- apiURL = x;
- oauth.api(x);
+ apiURL = _;
+ oauth.api(_);
return connection;
};
- connection.user = function(x) {
+ connection.user = function(_) {
if (!arguments.length) return user;
- user = x;
+ user = _;
return connection;
};
diff --git a/js/id/taginfo.js b/js/id/taginfo.js
index d6524c9ca..680dbe37a 100644
--- a/js/id/taginfo.js
+++ b/js/id/taginfo.js
@@ -1,20 +1,10 @@
-// Taginfo
-iD.taginfo = (function() {
-
+iD.taginfo = function() {
var taginfo = {},
endpoint = 'http://taginfo.openstreetmap.org/api/2/';
- function qsString(obj) {
- return Object.keys(obj).sort().map(function(key) {
- return encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]);
- }).join('&');
- }
-
- // Given a key, return common values
- // TODO: get type, count correctly based on it
taginfo.values = function(key, callback) {
- d3.json(endpoint + 'db/keys/values' +
- qsString({
+ d3.json(endpoint + 'db/keys/values?' +
+ iD.Util.qsString({
key: key,
sortname: 'count_all',
sortorder: 'desc',
@@ -22,5 +12,11 @@ iD.taginfo = (function() {
}), callback);
};
+ taginfo.endpoint = function(_) {
+ if (!arguments.length) return endpoint;
+ endpoint = _;
+ return taginfo;
+ };
+
return taginfo;
-})();
+};
diff --git a/js/id/ui/inspector.js b/js/id/ui/inspector.js
index 4f54f020e..7e9ea12bb 100644
--- a/js/id/ui/inspector.js
+++ b/js/id/ui/inspector.js
@@ -1,5 +1,6 @@
iD.Inspector = function() {
- var event = d3.dispatch('changeTags', 'changeWayDirection', 'update', 'remove', 'close');
+ var event = d3.dispatch('changeTags', 'changeWayDirection', 'update', 'remove', 'close'),
+ taginfo = iD.taginfo();
function drawhead(selection) {
selection.html('');
@@ -72,6 +73,15 @@ iD.Inspector = function() {
.on('keyup', function(d, i) {
d[i ? 'value' : 'key'] = this.value;
update();
+ })
+ .each(function(d, i) {
+ var selection = this;
+ if (i == 1) {
+ taginfo.values(d.key, function(vals) {
+ d3.select(selection).call(d3.typeahead()
+ .data(vals));
+ });
+ }
});
row.append('td').attr('class', 'tag-help').append('a')
diff --git a/js/id/util.js b/js/id/util.js
index 69af16e26..b0ded6130 100644
--- a/js/id/util.js
+++ b/js/id/util.js
@@ -49,3 +49,9 @@ iD.Util.tagText = function(entity) {
return e.key + ': ' + e.value;
}).join('\n');
};
+
+iD.Util.qsString = function(obj) {
+ return Object.keys(obj).sort().map(function(key) {
+ return encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]);
+ }).join('&');
+};
diff --git a/js/lib/d3.typeahead.js b/js/lib/d3.typeahead.js
new file mode 100644
index 000000000..08703c86c
--- /dev/null
+++ b/js/lib/d3.typeahead.js
@@ -0,0 +1,48 @@
+d3.typeahead = function() {
+
+ var data = [], limit = 10;
+
+ 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
+ });
+
+ 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();
+ });
+ };
+
+ typeahead.limit = function(_) {
+ if (!arguments.length) return limit;
+ limit = _;
+ return typeahead;
+ };
+
+ typeahead.data = function(_) {
+ if (!arguments.length) return data;
+ data = _;
+ return typeahead;
+ };
+
+ return typeahead;
+
+};