This commit is contained in:
Tom MacWright
2013-01-31 19:41:52 -05:00
parent 9cb0879818
commit 8eb04ddb4d
3 changed files with 360 additions and 0 deletions

170
combobox.html Normal file
View File

@@ -0,0 +1,170 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>iD</title>
<link rel='stylesheet' href='css/reset.css'>
<link rel='stylesheet' href='css/map.css'>
<link rel='stylesheet' href='css/app.css'>
<!-- mobile devices -->
<meta name='viewport' content='initial-scale=1.0 maximum-scale=1.0'>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<script src='js/lib/lodash.js'></script>
<script src='js/lib/d3.v3.js'></script>
<script src='js/lib/sha.js'></script>
<script src='js/lib/ohauth.js'></script>
<script src='js/lib/jxon.js'></script>
<script src='js/lib/d3.typeahead.js'></script>
<script src='js/lib/d3.combobox.js'></script>
<script src='js/lib/d3.geo.tile.js'></script>
<script src='js/lib/d3.size.js'></script>
<script src='js/lib/d3.trigger.js'></script>
<script src='js/lib/d3.keybinding.js'></script>
<script src='js/lib/d3.tail.js'></script>
<script src='js/lib/d3-compat.js'></script>
<script src='js/lib/bootstrap-tooltip.js'></script>
<script src='js/lib/rtree.js'></script>
<script src='js/id/id.js'></script>
<script src='js/id/util.js'></script>
<script src='js/id/oauth.js'></script>
<script src='js/id/services/taginfo.js'></script>
<script src="js/id/geo.js"></script>
<script src="js/id/geo/extent.js"></script>
<script src='js/id/renderer/background.js'></script>
<script src='js/id/renderer/background_source.js'></script>
<script src='js/id/renderer/map.js'></script>
<script src='js/id/renderer/hash.js'></script>
<script src="js/id/svg.js"></script>
<script src="js/id/svg/areas.js"></script>
<script src="js/id/svg/lines.js"></script>
<script src="js/id/svg/member_classes.js"></script>
<script src="js/id/svg/midpoints.js"></script>
<script src="js/id/svg/multipolygons.js"></script>
<script src="js/id/svg/points.js"></script>
<script src="js/id/svg/surface.js"></script>
<script src="js/id/svg/tag_classes.js"></script>
<script src="js/id/svg/vertices.js"></script>
<script src="js/id/svg/labels.js"></script>
<script src="js/id/ui.js"></script>
<script src='js/id/ui/radial_menu.js'></script>
<script src='js/id/ui/inspector.js'></script>
<script src='js/id/ui/modal.js'></script>
<script src='js/id/ui/confirm.js'></script>
<script src='js/id/ui/commit.js'></script>
<script src='js/id/ui/success.js'></script>
<script src='js/id/ui/loading.js'></script>
<script src='js/id/ui/userpanel.js'></script>
<script src='js/id/ui/layerswitcher.js'></script>
<script src='js/id/ui/contributors.js'></script>
<script src='js/id/ui/geocoder.js'></script>
<script src='js/id/ui/geolocate.js'></script>
<script src='js/id/ui/notice.js'></script>
<script src='js/id/ui/flash.js'></script>
<script src='js/id/ui/save.js'></script>
<script src='js/id/ui/tag_reference.js'></script>
<script src='js/id/ui/key_reference.js'></script>
<script src='js/id/actions.js'></script>
<script src="js/id/actions/add_midpoint.js"></script>
<script src='js/id/actions/add_entity.js'></script>
<script src='js/id/actions/add_vertex.js'></script>
<script src='js/id/actions/change_tags.js'></script>
<script src='js/id/actions/delete_node.js'></script>
<script src="js/id/actions/delete_way.js"></script>
<script src='js/id/actions/move_node.js'></script>
<script src='js/id/actions/move_way.js'></script>
<script src='js/id/actions/circularize.js'></script>
<script src='js/id/actions/noop.js'></script>
<script src='js/id/actions/reverse_way.js'></script>
<script src='js/id/actions/split_way.js'></script>
<script src='js/id/actions/unjoin_node.js'></script>
<script src='js/id/behavior.js'></script>
<script src='js/id/behavior/add_way.js'></script>
<script src='js/id/behavior/drag.js'></script>
<script src='js/id/behavior/drag_midpoint.js'></script>
<script src='js/id/behavior/drag_node.js'></script>
<script src='js/id/behavior/draw.js'></script>
<script src='js/id/behavior/draw_way.js'></script>
<script src='js/id/behavior/hover.js'></script>
<script src='js/id/behavior/select.js'></script>
<script src='js/id/modes.js'></script>
<script src='js/id/modes/add_area.js'></script>
<script src='js/id/modes/add_point.js'></script>
<script src='js/id/modes/add_line.js'></script>
<script src='js/id/modes/browse.js'></script>
<script src='js/id/modes/draw_area.js'></script>
<script src='js/id/modes/draw_line.js'></script>
<script src='js/id/modes/move_way.js'></script>
<script src='js/id/modes/select.js'></script>
<script src='js/id/operations.js'></script>
<script src='js/id/operations/circularize.js'></script>
<script src='js/id/operations/delete.js'></script>
<script src='js/id/operations/move.js'></script>
<script src='js/id/operations/reverse.js'></script>
<script src='js/id/operations/split.js'></script>
<script src='js/id/operations/unjoin.js'></script>
<script src='js/id/graph/entity.js'></script>
<script src='js/id/graph/graph.js'></script>
<script src='js/id/graph/history.js'></script>
<script src='js/id/graph/node.js'></script>
<script src='js/id/graph/relation.js'></script>
<script src='js/id/graph/way.js'></script>
<script src='js/id/controller.js'></script>
<script src='js/id/validate.js'></script>
<script src='js/id/connection.js'></script>
<script src='locale/locale.js'></script>
<script src='locale/en.js'></script>
<style>
body {
margin:20px;
}
#foo, #bar {
position:relative;
}
</style>
</head>
<body>
<div id='foo'><input /></div>
<div id='bar'><input /></div>
<div id="iD"></div><script>
var options = d3.range(0, 50).map(function(i) {
return {
value: i * 10,
title: i * 10
};
});
d3.select('#foo').call(d3.combobox()
.data(function(selection, cb) {
cb(options);
}));
d3.select('#bar').call(d3.combobox()
.data(function(selection, cb) {
cb(options);
}));
</script></body>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-38039653-2']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</html>

View File

@@ -1267,3 +1267,46 @@ a.success-action {
.icon.icon-pre-text { margin-right: 0px;}
.save .label, .apply .label { display: block;}
}
div.combobox {
width:155px;
z-index: 9999;
display: none;
box-shadow: 0 5px 10px 0 rgba(0,0,0,.2);
margin-top: -1px;
background: white;
max-height: 180px;
overflow: auto;
border: 1px solid #ccc;
}
div.combobox a {
height: 25px;
line-height: 25px;
cursor: pointer;
display: block;
border-top:1px solid #ccc;
background-color: #fff;
padding:1px 4px;
white-space: nowrap;
}
div.combobox a:hover,
div.combobox a.selected {
background: #e1e8ff;
color: #154dff;
}
div.combobox a:first-child {
border-top: 0;
}
div.combobox-carat {
cursor: pointer;
padding:0 5px;
vertical-align:middle;
}

147
js/lib/d3.combobox.js Normal file
View File

@@ -0,0 +1,147 @@
d3.combobox = function() {
var event = d3.dispatch('accept'),
autohighlight = false,
autofilter = false,
input,
container,
data;
var typeahead = function(selection) {
var hidden, idx = autohighlight ? 0 : -1;
var rect = selection.select('input').node().getBoundingClientRect();
input = selection.select('input');
container = selection
.insert('div', ':first-child')
.attr('class', 'combobox')
.style({
position: 'absolute',
display: 'none',
left: '0px',
width: rect.width + 'px',
top: rect.height + 'px'
});
carat = selection
.insert('div', ':first-child')
.attr('class', 'combobox-carat')
.text('+')
.style({
position: 'absolute',
left: (rect.width - 20) + 'px',
top: '0px'
})
.on('click', function() {
update();
show();
});
selection
.on('keyup.typeahead', key);
hidden = false;
function hide() {
idx = autohighlight ? 0 : -1;
hidden = true;
}
function show() {
container.style('display', 'block');
}
function slowHide() {
if (autohighlight && container.select('a.selected').node()) {
select(container.select('a.selected').datum());
event.accept();
}
window.setTimeout(hide, 150);
}
selection
.on('focus.typeahead', show)
.on('blur.typeahead', slowHide);
function key() {
var len = container.selectAll('a').data().length;
if (d3.event.keyCode === 40) {
idx = Math.min(idx + 1, len - 1);
return highlight();
} else if (d3.event.keyCode === 38) {
idx = Math.max(idx - 1, 0);
return highlight();
} else if (d3.event.keyCode === 13) {
if (container.select('a.selected').node()) {
select(container.select('a.selected').datum());
}
event.accept();
hide();
} else {
update();
}
}
function highlight() {
container
.selectAll('a')
.classed('selected', function(d, i) { return i == idx; });
}
function update() {
function run(data) {
container.style('display', function() {
return data.length ? 'block' : 'none';
});
var options = container
.selectAll('a')
.data(data, function(d) { return d.value; });
options.enter()
.append('a')
.text(function(d) { return d.value; })
.attr('title', function(d) { return d.title; })
.on('click', select);
options.exit().remove();
options
.classed('selected', function(d, i) { return i == idx; });
}
if (typeof data === 'function') data(selection, run);
else run(data);
}
function select(d) {
input
.property('value', d.value)
.trigger('change');
container.style('display', 'none');
}
};
typeahead.data = function(_) {
if (!arguments.length) return data;
data = _;
return typeahead;
};
typeahead.autofilter = function(_) {
if (!arguments.length) return autofilter;
autofilter = _;
return typeahead;
};
typeahead.autohighlight = function(_) {
if (!arguments.length) return autohighlight;
autohighlight = _;
return typeahead;
};
return d3.rebind(typeahead, event, 'on');
};