From 9b5f50669409c4534565cec53d0cfd5716471c20 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Tue, 19 Feb 2013 00:09:46 -0500 Subject: [PATCH] Add autocompletion to combobox Also, don't filter results with input value when selecting the combobox, so that it behaves like a select input in this case. --- js/lib/d3.combobox.js | 44 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/js/lib/d3.combobox.js b/js/lib/d3.combobox.js index 796896b6b..63f741107 100644 --- a/js/lib/d3.combobox.js +++ b/js/lib/d3.combobox.js @@ -91,7 +91,6 @@ d3.combobox = function() { d3.event.preventDefault(); break; // escape, tab - case 9: case 13: d3.event.preventDefault(); break; @@ -136,6 +135,34 @@ d3.combobox = function() { highlight(); } + var prevValue, prevCompletion; + + function autocomplete() { + + var value = input.property('value'), + match; + + for (var i = 0; i < data.length; i++) { + if (data[i].value.indexOf(value) === 0) { + match = data[i].value; + break; + } + } + + // backspace + if (d3.event.keyCode === 8) { + prevValue = value; + prevCompletion = ''; + + } else if (value && match && value !== prevValue + prevCompletion) { + prevValue = value; + prevCompletion = match.substr(value.length); + input.property('value', prevValue + prevCompletion); + input.node().setSelectionRange(value.length, value.length + prevCompletion.length); + } + } + + function highlight() { container .selectAll('a') @@ -150,12 +177,19 @@ d3.combobox = function() { } } - function update() { + function update(value) { + + if (typeof value === 'undefined') { + value = input.property('value'); + } function render(data) { + if (data.length) show(); else hide(); + autocomplete(); + updateSize(); var options = container @@ -176,9 +210,7 @@ d3.combobox = function() { .order(); } - fetcher.apply(selection, [ - selection.select('input').property('value'), - data, render]); + fetcher.apply(selection, [value, data, render]); } // select the choice given as d @@ -191,7 +223,7 @@ d3.combobox = function() { } function mousedown() { - update(); + update(''); var entries = container.selectAll('a'), height = container.node().scrollHeight / entries[0].length,