11

var el = document.getElementById('action');

el.addEventListener('click', function()
{
    var t = document.getElementById('text');
    t.value = 'A should be typed later';
    t.focus();
    t.setSelectionRange(0, 0);

    setTimeout(function()
    {
        t.dispatchEvent(new Event('keypress', {keyCode: 65}))
    }, 800);

}, false);
<textarea id="text"></textarea>
<button id="action">
    Do It
</button>

What do I miss that a is not added to the beginning of the textarea?

The purpose is to genuinely simulate an actual press of a key on the keyboard, NOT (re)setting the textarea value.

UPDATE: This is not a duplicate of this question.

(i) Most of the answers use jQuery.

(ii) I couldn't find a working example from those answers for the above case.

(iii) Actually, the above code was derived from that page.

Anyway, whether this is duplicate or not. You can read the question as: Why doesn't the above straightforward code work?

Shidersz
  • 16,846
  • 2
  • 23
  • 48
Googlebot
  • 15,159
  • 44
  • 133
  • 229
  • `keyCode` should be a number, not a string. – Barmar Oct 20 '18 at 21:40
  • a handy site for getting JS key codes [keycode.info](https://keycode.info/) – Igor Milla Oct 20 '18 at 21:42
  • 1
    @Barmar you're right. That was a typo as I was trying different commands `key`, `keyCode`, etc. Anyhow, it's not the source of the problem. – Googlebot Oct 20 '18 at 21:46
  • [This](https://stackoverflow.com/questions/1233800/javascript-sending-key-codes-to-a-textarea-element) may be relevant, depending on the browser, it might not be possible. I thought you might have to use the KeyboardEvent constructor instead of the Event constructor but I can't figure out how to get it to work either. – CertainPerformance Oct 20 '18 at 21:51
  • @CertainPerformance I checked several similar questions here. I haven't seen a solution to actually trigger a key to type a letter (not just setting `element.value`). – Googlebot Oct 20 '18 at 21:54
  • 2
    Possible duplicate of [Is it possible to simulate key press events programmatically?](https://stackoverflow.com/questions/596481/is-it-possible-to-simulate-key-press-events-programmatically) – René Höhle Oct 20 '18 at 22:37
  • 1
    I've taken the liberty of editing the question title so that it asks the question you want to ask, rather than almost exactly what the duplicates answer. Feel free to rollback if it does not match your intent. – Heretic Monkey Oct 20 '18 at 23:27
  • 5
    The reason for this behavior is actually in [Dispatching keyboard event doesn't work in JavaScript](https://stackoverflow.com/q/20163708/215552). The event is dispatched, just the value is not added to the textarea. See the [Trusted events](https://www.w3.org/TR/uievents/#trusted-events) section of the UI Events spec. – Heretic Monkey Oct 20 '18 at 23:42
  • @HereticMonkey many thanks for this. – Googlebot Oct 21 '18 at 00:00

1 Answers1

3

Have to agree with Heretic Monkey - the event will 'fire' correctly however it will not actually perform the action (security - otherwise javascript could type and enter all sorts of crap into forms relatively easily!!!).

What you can do though is still create the event and simulate the result - it's a bit janky of course but this may help - this way you can still play with bubbling and other fun event-related aspects while still getting the result you're looking for. I'll admit it's pretty awkward though!

var el = document.getElementById('action');

el.addEventListener('click', function()
{
    var t = document.getElementById('text');
    t.value = 'A should be typed later';
    t.focus();
    t.setSelectionRange(0, 0);

    setTimeout(function()
    {
      var event = document.createEvent('Event');
      event.key = 65;
      event.initEvent('keypress');
      document.dispatchEvent(event);
    }, 800);

}, false);

document.addEventListener('keypress', function(e){
  let t = document.getElementById('text');
  let oldText = t.value;

    t.value = String.fromCharCode(e.key) + oldText;
    t.focus();
    t.setSelectionRange(1, 0);

});
<textarea id="text"></textarea>
<button id="action">
    Do It
</button>
NVRM
  • 11,480
  • 1
  • 88
  • 87
Mark Taylor
  • 1,128
  • 8
  • 15