How to make undo work in HTML textbox after setting value?

I have an element <textarea>

from which I listen for certain keystrokes. For example, if the user types in a key Tab, I prevent the default focus change action and add the tab character at the correct position.

The problem is when users press one of the keys I'm listening to, the undo goes a little glitch. How can I use the undo / redo functionality? I was thinking about listening to ctrl / cmd-z and ctrl / cmd-shift-z keys, recording everything and handling undo / redo, but then the edit and context menu options didn't work ...

You can see by typing the tabbed letters and typing and then trying to undo and redo:

const textarea = document.querySelector('textarea')
textarea.addEventListener('keydown', function (event) {
  if (event.key == "Tab") {
    event.preventDefault()
    const cursor = textarea.selectionStart
    textarea.value = textarea.value.slice(0, cursor) + '\t' + textarea.value.slice(textarea.selectionEnd)
    textarea.selectionStart = textarea.selectionEnd = cursor + 1
  } else if (event.key == "Enter") {
    event.preventDefault()
    const cursor = textarea.selectionStart
    textarea.value = textarea.value.slice(0, cursor) + '\n' + textarea.value.slice(textarea.selectionEnd)
    textarea.selectionStart = textarea.selectionEnd = cursor + 1
  }
})
      

<textarea cols="50" rows="20"></textarea>
      

Run codeHide result


+3


source to share


1 answer


I believe the main problem is the lack of interaction between Javascript and default browser deactivation methods. Adding Javascript text to the text box does not in any way tell the browser to "undo" to remove the added text, since the browser "undo" is only intended to remove text that the user enters, not text that is entered in Javascript.

Take your code for example. Pressing Enter will tell the eventListener to prevent Default, which will still prevent the input key from being entered from adding the user to the textbox anyway. You then synthesize the input using Javascript, which the "undo" browser doesn't track.



You can overcome this lack of interoperability using Document.execCommand () . You can check browser support at the link.

const textarea = document.querySelector('textarea');
textarea.addEventListener('keydown', function (event) {
    const cursor = textarea.selectionStart;
    if(event.key == "Tab"){
        event.preventDefault();
        document.execCommand("insertText", false, '\t');//appends a tab and makes the browser default undo/redo aware and automatically moves cursor
    } else if (event.key == "Enter") {
        event.preventDefault();
        document.execCommand("insertText", false, '\n');
    }

});

      

+1


source







All Articles