1

I've got an interactive graph built with d3, and I capture the backspace key to remove elements from the graph. However, I also have a text box on the page, and I'd like to be able to use backspace while typing. Is there a way to allow the backspace through in the text box, or to only capture it in the main svg of the graph?

My code:

var BACKSPACE_KEY = 8;

d3.select(window).on("keydown", function() {
  switch (d3.event.keyCode) {
    case BACKSPACE_KEY:
      // So that the browser doesn't go back
      d3.event.preventDefault();

      // Clean up my graph with the backspace key
      // ...
  }
})

A fiddle demonstrating the problem: https://jsfiddle.net/5pamrn3m/

Kyle Heuton
  • 9,318
  • 4
  • 40
  • 52
  • 1
    I might be being very stupid here, but just [not using preventDefault](https://jsfiddle.net/5pamrn3m/1/) seems to do the trick – TKoL Oct 17 '17 at 14:08
  • 1
    @TKoL yeah, but he wants to preventDefault when event occurs outside of input and in some browsers (in most of them until recently) backspace navigated browser to previous page. – Walk Oct 17 '17 at 14:17
  • I guess I've got the site set to no let you leave without saving, so that would probably work even if the browser did try to send you back. But yeah, Walk is right about the reasons why it's there – Kyle Heuton Oct 17 '17 at 15:09

4 Answers4

3

Use event taget (MDN) to check that it was <input> to be able to break the procedure:

var BACKSPACE_KEY = 8;

d3.select(window).on("keydown", function() {
  switch (d3.event.keyCode) {
    case BACKSPACE_KEY:

      // So that the browser doesn't go back
      d3.event.preventDefault();

      // BACKSPACE_KEY was fired in <input id="textbox">
      if(d3.event.target.id === 'textbox') {
        break;
      }    

      // Clean up my graph with the backspace key
      // ...
  }
})

I used id due to your fiddle, but the condition could be more generic

// BACKSPACE_KEY was fired in any <input>
if(d3.event.target.nodeName.toLowerCase() === 'input') {
  break;
}
dhilt
  • 18,707
  • 8
  • 70
  • 85
2

Use event.stopPropagation();

https://jsfiddle.net/x64hcktt/

More about event propagation: https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Examples#Example_5:_Event_Propagation

Walk
  • 737
  • 4
  • 15
1

You can prevent the default behaviour of the backspace key on the whole page except a certain input if you check for the focused element's id using :

if (document.activeElement.id !== "textbox")
    d3.event.preventDefault();

See this Fiddle

Paul-Etienne
  • 796
  • 9
  • 23
0

Here is another way to do it:

d3.select('input').on('keydown', () => d3.event.stopPropagation())

This stops the keydown event from propagating to other handlers.

mvr
  • 1,732
  • 16
  • 11