From 60c14dc7ac3074c7d39c025dd037a2e6170dfb61 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Thu, 31 Jan 2013 14:24:05 -0500 Subject: [PATCH] Use typeahead for preset search, support changing presets. Fixes #577 --- js/id/ui/preset.js | 2 ++ js/id/ui/presetsearch.js | 45 +++++++++++++++++----------------------- js/lib/d3.typeahead.js | 25 ++++++++++++++++++---- 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/js/id/ui/preset.js b/js/id/ui/preset.js index 173599a01..4badadaf5 100644 --- a/js/id/ui/preset.js +++ b/js/id/ui/preset.js @@ -54,6 +54,8 @@ iD.ui.preset = function() { } function presets(selection) { + selection.html(''); + var sections = selection.selectAll('div.preset-section') .data(preset.main) .enter() diff --git a/js/id/ui/presetsearch.js b/js/id/ui/presetsearch.js index c543089c9..7e888e3a1 100644 --- a/js/id/ui/presetsearch.js +++ b/js/id/ui/presetsearch.js @@ -9,41 +9,34 @@ iD.ui.presetsearch = function() { value = value.toLowerCase(); return viable.filter(function(v) { return v.name.toLowerCase().indexOf(value) !== -1; + }).map(function(v) { + return { + title: v.name, + value: v.name + }; }); } - function showResults() { - var values = filter(this.value).slice(0, 10); - - var res = search_output.selectAll('button.preset-search-result') - .data(values, function(d) { return d.name; }); - - res.exit().remove(); - - res.enter() - .append('button') - .attr('class', 'preset-search-result') - .text(function(d) { - return d.name; - }) - .on('click', function(d) { - search_output - .selectAll('button.preset-search-result') - .remove(); - event.choose(d); - }); + function find(value) { + value = value; + return _.find(viable, function(v) { + return v.name == value; + }); } - selection.append('div') + var preset_search_input = selection.append('div') .attr('class', 'preset-search-input') .append('h3') .append('input') .attr('placeholder', 'preset search') - .on('keyup', showResults) - .on('change', showResults); - - var search_output = selection.append('div') - .attr('class', 'preset-search-output'); + .call(d3.typeahead() + .autohighlight(true) + .data(function(_, callback) { + callback(filter(preset_search_input.property('value'))); + }) + .on('accept', function() { + event.choose(find(preset_search_input.property('value'))); + })); } search.presetData = function(_) { diff --git a/js/lib/d3.typeahead.js b/js/lib/d3.typeahead.js index 08a1a36ec..249512730 100644 --- a/js/lib/d3.typeahead.js +++ b/js/lib/d3.typeahead.js @@ -1,8 +1,12 @@ d3.typeahead = function() { - var data; + var event = d3.dispatch('accept'), + autohighlight = false, + data; var typeahead = function(selection) { - var container, hidden, idx = -1; + var container, + hidden, + idx = autohighlight ? 0 : -1; function setup() { var rect = selection.node().getBoundingClientRect(); @@ -20,11 +24,17 @@ d3.typeahead = function() { function hide() { container.remove(); - idx = -1; + idx = autohighlight ? 0 : -1; hidden = true; } function slowHide() { + if (autohighlight) { + if (container.select('a.selected').node()) { + select(container.select('a.selected').datum()); + event.accept(); + } + } window.setTimeout(hide, 150); } @@ -44,6 +54,7 @@ d3.typeahead = function() { if (container.select('a.selected').node()) { select(container.select('a.selected').datum()); } + event.accept(); hide(); } else { update(); @@ -95,5 +106,11 @@ d3.typeahead = function() { return typeahead; }; - return typeahead; + typeahead.autohighlight = function(_) { + if (!arguments.length) return autohighlight; + autohighlight = _; + return typeahead; + }; + + return d3.rebind(typeahead, event, 'on'); };