Files
iD/js/lib/d3.typeahead.js
2012-12-06 10:39:08 -05:00

79 lines
2.6 KiB
JavaScript

d3.typeahead = function() {
var data, hidden;
var typeahead = function(selection) {
var container;
function setup() {
var rect = selection.node().getBoundingClientRect();
container = d3.select(document.body)
.append('div').attr('class', 'typeahead')
.style({
position: 'absolute',
left: rect.left + 'px',
top: rect.bottom + 'px'
});
selection
.on('keyup.typeahead', update);
hidden = false;
}
function hide() {
window.setTimeout(function() {
container.remove();
idx = 0;
hidden = true;
}, 500);
}
selection
.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';
});
var 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(_) {
if (!arguments.length) return data;
data = _;
return typeahead;
};
return typeahead;
};