Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programmatically dispatching key characters to input/contenteditable

Tags:

javascript

dom

I can set the value of an input-style DOM elements (input/div contenteditable=true) quite easily, by either setting their .value or innerText properties via JS.

But is it possible to dispatch keyboard events to them, loaded with a character, so that it inserts the dispatched character to the current cursor position?

Here's an example that doesn't work.

'use strict'

const btn = document.querySelector('#btn')
const editable = document.querySelector('#editable')

btn.addEventListener('mousedown', e => {
  // prevent unfocus when clicking button
  e.preventDefault()
  
  const customEvt = new KeyboardEvent('keypress', {
    bubbles: true, 
    cancelable: true, 
    key: 'X', 
    char: 'X'
  })

  editable.dispatchEvent(customEvt)
})
#editable {
  border: 1px solid;
  padding: 8px 12px;
}
<p> Make sure the editable is focused before pressing button</p>
<div id="editable" contenteditable="true">Lorem Ipsum</div>
<button id="btn"> Add 'X' character at cursor position</button>

Why I need this:

We are building a symbols keyboard for an app, that will allow users to add symbols to the current cursor position.

Tracking the current cursor position in a contenteditable, so we can insert the clicked symbol, is error-prone and requires extra (and often ugly) code. I'd like to avoid it.

I'm guessing this can't be done, as it could be a security risk but It never hurts to ask.

like image 445
nicholaswmin Avatar asked Oct 18 '25 16:10

nicholaswmin


1 Answers

You can't fake a keypress, but you can use document.execCommand.insertText, which should give more or less the same result. See https://developer.mozilla.org/en-US/docs/Web/API/document/execCommand

'use strict'

const btn = document.querySelector('#btn')
const editable = document.querySelector('#editable')

btn.addEventListener('mousedown', e => {
  // prevent unfocus when clicking button
  e.preventDefault() 
  console.log(document.execCommand('insertText', false, 'X'));
  

  
})
#editable {
  border: 1px solid;
  padding: 8px 12px;
}
<p> Make sure the editable is focused before pressing button</p>
<div id="editable" contenteditable="true">Lorem Ipsum</div>
<button id="btn"> Add 'X' character at cursor position</button>
like image 73
Julien Grégoire Avatar answered Oct 20 '25 06:10

Julien Grégoire