mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-13 01:02:58 +00:00
Taginfo typeahead on keys as well as values
This commit is contained in:
@@ -2,23 +2,29 @@ iD.taginfo = function() {
|
||||
var taginfo = {},
|
||||
endpoint = 'http://taginfo.openstreetmap.org/api/2/';
|
||||
|
||||
taginfo.values = function(key, callback) {
|
||||
d3.json(endpoint + 'db/keys/values?' +
|
||||
iD.util.qsString({
|
||||
key: key,
|
||||
taginfo.keys = function(parameters, callback) {
|
||||
d3.json(endpoint + 'db/keys?' +
|
||||
iD.util.qsString(_.extend({
|
||||
rp: 20,
|
||||
sortname: 'count_all',
|
||||
sortorder: 'desc',
|
||||
page: 1
|
||||
}), callback);
|
||||
}, parameters)), callback);
|
||||
};
|
||||
|
||||
taginfo.docs = function(keyvalue, callback) {
|
||||
taginfo.values = function(parameters, callback) {
|
||||
d3.json(endpoint + 'db/keys/values?' +
|
||||
iD.util.qsString(_.extend({
|
||||
rp: 20,
|
||||
sortname: 'count_all',
|
||||
sortorder: 'desc',
|
||||
page: 1
|
||||
}, parameters)), callback);
|
||||
};
|
||||
|
||||
taginfo.docs = function(parameters, callback) {
|
||||
d3.json(endpoint + 'wiki/tags?' +
|
||||
iD.util.qsString({
|
||||
key: keyvalue.key,
|
||||
value: keyvalue.value
|
||||
}), callback);
|
||||
iD.util.qsString(parameters), callback);
|
||||
};
|
||||
|
||||
taginfo.endpoint = function(_) {
|
||||
|
||||
@@ -52,12 +52,26 @@ iD.Inspector = function() {
|
||||
}
|
||||
}
|
||||
|
||||
function bindTypeahead(d, i) {
|
||||
var selection = d3.select(this);
|
||||
selection.call(d3.typeahead()
|
||||
.data(function(selection, callback) {
|
||||
taginfo.values(selection.datum().key, function(err, data) {
|
||||
callback(data.data);
|
||||
function bindTypeahead() {
|
||||
var row = d3.select(this),
|
||||
key = row.selectAll('.key'),
|
||||
value = row.selectAll('.value');
|
||||
|
||||
key.call(d3.typeahead()
|
||||
.data(function(_, callback) {
|
||||
taginfo.keys({query: key.property('value')}, function(err, data) {
|
||||
callback(data.data.map(function (d) {
|
||||
return {value: d.key};
|
||||
}));
|
||||
});
|
||||
}));
|
||||
|
||||
value.call(d3.typeahead()
|
||||
.data(function(_, callback) {
|
||||
taginfo.values({key: key.property('value'), query: value.property('value')}, function(err, data) {
|
||||
callback(data.data.map(function (d) {
|
||||
return {value: d.value, title: d.description};
|
||||
}));
|
||||
});
|
||||
}));
|
||||
}
|
||||
@@ -84,8 +98,9 @@ iD.Inspector = function() {
|
||||
.property('type', 'text')
|
||||
.attr('class', 'value')
|
||||
.property('value', function(d) { return d.value; })
|
||||
.on('keydown.push-more', pushMore)
|
||||
.each(bindTypeahead);
|
||||
.on('keydown.push-more', pushMore);
|
||||
|
||||
inputs.each(bindTypeahead);
|
||||
|
||||
var removeBtn = row.append('button')
|
||||
.attr('tabindex', -1)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
d3.typeahead = function() {
|
||||
var data, hidden;
|
||||
var data;
|
||||
|
||||
var typeahead = function(selection) {
|
||||
var container;
|
||||
var container, hidden, idx = 0;
|
||||
|
||||
function setup() {
|
||||
var rect = selection.node().getBoundingClientRect();
|
||||
container = d3.select(document.body)
|
||||
@@ -29,40 +30,35 @@ d3.typeahead = function() {
|
||||
.on('focus.typeahead', setup)
|
||||
.on('blur.typeahead', hide);
|
||||
|
||||
var idx = 0;
|
||||
function update() {
|
||||
if (hidden) setup();
|
||||
|
||||
if (d3.event.keyCode === 40) idx++;
|
||||
if (d3.event.keyCode === 38) idx--;
|
||||
if (d3.event.keyCode === 13) {
|
||||
selection.property('value', container.select('a.selected').datum().value);
|
||||
hide();
|
||||
}
|
||||
|
||||
container
|
||||
.selectAll('a')
|
||||
.classed('selected', function(d, i) { return i == idx; });
|
||||
// if (d3.event.keyCode === 13) // return
|
||||
|
||||
data(selection, function(data) {
|
||||
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.style('display', function() {
|
||||
return matches.length ? 'block' : 'none';
|
||||
return data.length ? 'block' : 'none';
|
||||
});
|
||||
|
||||
var options = container
|
||||
.selectAll('a')
|
||||
.data(matches, function(d) { return d.value; });
|
||||
.data(data, 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);
|
||||
});
|
||||
.attr('title', function(d) { return d.title; })
|
||||
.on('click', function(d) { selection.property('value', d.value); });
|
||||
|
||||
options.exit().remove();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -131,6 +131,7 @@
|
||||
<script src="spec/ui/geocoder.js"></script>
|
||||
<script src="spec/connection.js"></script>
|
||||
<script src="spec/oauth.js"></script>
|
||||
<script src="spec/taginfo.js"></script>
|
||||
<script src="spec/util.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
<script src="spec/ui/inspector.js"></script>
|
||||
<script src="spec/connection.js"></script>
|
||||
<script src="spec/oauth.js"></script>
|
||||
<script src="spec/taginfo.js"></script>
|
||||
<script src="spec/util.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
72
test/spec/taginfo.js
Normal file
72
test/spec/taginfo.js
Normal file
@@ -0,0 +1,72 @@
|
||||
describe("iD.taginfo", function() {
|
||||
var server;
|
||||
|
||||
beforeEach(function() {
|
||||
server = sinon.fakeServer.create();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
server.restore();
|
||||
});
|
||||
|
||||
function query(url) {
|
||||
return iD.util.stringQs(url.substring(url.indexOf('?') + 1));
|
||||
}
|
||||
|
||||
describe("#keys", function() {
|
||||
it("calls the given callback with the results of the keys query", function() {
|
||||
var taginfo = iD.taginfo(),
|
||||
callback = sinon.spy();
|
||||
|
||||
taginfo.keys({query: "amen"}, callback);
|
||||
|
||||
server.respondWith("GET", new RegExp("http://taginfo.openstreetmap.org/api/2/db/keys"),
|
||||
[200, { "Content-Type": "application/json" },
|
||||
'{"data":[{"count_all":5190337,"key":"amenity"}]}']);
|
||||
server.respond();
|
||||
|
||||
expect(query(server.requests[0].url)).to.eql(
|
||||
{query: "amen", page: "1", rp: "20", sortname: "count_all", sortorder: "desc"});
|
||||
expect(callback).to.have.been.calledWith(null,
|
||||
{"data":[{"count_all":5190337,"key":"amenity"}]});
|
||||
});
|
||||
});
|
||||
|
||||
describe("#values", function() {
|
||||
it("calls the given callback with the results of the values query", function() {
|
||||
var taginfo = iD.taginfo(),
|
||||
callback = sinon.spy();
|
||||
|
||||
taginfo.values({key: "amenity", query: "par"}, callback);
|
||||
|
||||
server.respondWith("GET", new RegExp("http://taginfo.openstreetmap.org/api/2/db/keys/values"),
|
||||
[200, { "Content-Type": "application/json" },
|
||||
'{"data":[{"value":"parking","description":"A place for parking cars"}]}']);
|
||||
server.respond();
|
||||
|
||||
expect(query(server.requests[0].url)).to.eql(
|
||||
{key: "amenity", query: "par", page: "1", rp: "20", sortname: 'count_all', sortorder: 'desc'});
|
||||
expect(callback).to.have.been.calledWith(null,
|
||||
{"data":[{"value":"parking","description":"A place for parking cars"}]});
|
||||
});
|
||||
});
|
||||
|
||||
describe("#docs", function() {
|
||||
it("calls the given callback with the results of the docs query", function() {
|
||||
var taginfo = iD.taginfo(),
|
||||
callback = sinon.spy();
|
||||
|
||||
taginfo.docs({key: "amenity", value: "parking"}, callback);
|
||||
|
||||
server.respondWith("GET", new RegExp("http://taginfo.openstreetmap.org/api/2/wiki/tags"),
|
||||
[200, { "Content-Type": "application/json" },
|
||||
'[{"on_way":false,"lang":"en","on_area":true,"image":"File:Car park2.jpg"}]']);
|
||||
server.respond();
|
||||
|
||||
expect(query(server.requests[0].url)).to.eql(
|
||||
{key: "amenity", value: "parking"});
|
||||
expect(callback).to.have.been.calledWith(null,
|
||||
[{"on_way":false,"lang":"en","on_area":true,"image":"File:Car park2.jpg"}]);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user