1

I have a list of items with varying indents like so:

  • List item 1
    • List item 2
      • List item 3

I turn on contentEditable when the user clicks a list item. Now, when the user presses the up arrow key, I want to move the caret/word cursor from, say List item 3 to List item 2, while maintaining the caret's x position.

To show this graphically,

intial caret pos:

  • List item 2
    • Li | st item 3

final caret pos after user presses up arrow. x offset remains same despite the difference in indent levels:

  • List ite | m 2
    • List item 3

The aim is to simulate the behavior of a multi-line text area where moving between lines using the arrow keys preserves the caret offset. You can also see this behavior while moving between list items in Google Tasks.

After referencing a number of related SO questions, I managed to get half way to solving the problem before giving up.

Anyone aware of an elegant solution?

Community
  • 1
  • 1
vjk2005
  • 678
  • 1
  • 12
  • 23

1 Answers1

0

The general approach I'd suggest is:

  • Intercept the keydown event and prevent the browser default when up or down arrows are pressed
  • Here are some functions that allow you to get and set the position of the caret as character indices relative to a particular element. They're imperfect but would do the job in most circumstances: replace innerHTML in contenteditable div (also this jsFiddle does the same but removes the dependency on the Rangy library). Use these to get the the caret character index relative to one <li> and set the caret to the same position relative to the <li> above or below.
Community
  • 1
  • 1
Tim Down
  • 318,141
  • 75
  • 454
  • 536