Alcadur
Alcadur

Reputation: 685

Simulate typing in input/textarea

It looks like old questions but all answers I found are not working.

Maybe I missed something and currently, it is impossible to write programmatic in input/textarea.

And input.value = 'new value' also does not do the job.

What have I tried

const input = document.querySelector('input');


input.focus();
setTimeout(() => input.dispatchEvent(eventFactory('keydown')), 10)
setTimeout(() => input.dispatchEvent(eventFactory('beforeinput')), 20)
setTimeout(() => input.dispatchEvent(eventFactory('keypress')), 30)
setTimeout(() => input.dispatchEvent(eventFactory('input')), 40)
setTimeout(() => input.dispatchEvent(eventFactory('change')), 50)
setTimeout(() => input.dispatchEvent(eventFactory('keyup')), 60)

function eventFactory(eventName) {
  return new KeyboardEvent(eventName, {
    key: "e",
    keyCode: 69, // example values.
    code: "KeyE", // put everything you need in this object.
    which: 69,
    shiftKey: false, // you don't need to include values
    ctrlKey: false,  // if you aren't going to use them.
    metaKey: false   // these are here for example's sake.
  });
}
<input> 

Upvotes: 0

Views: 1843

Answers (2)

shreyasm-dev
shreyasm-dev

Reputation: 2834

I found a solution to this.

Code with comments explaining it:

const input = document.querySelector('input');


function insertAtCursor(myField, myValue) { // Exactly what is sounds like - Inserts text at caret
  //IE support
  if (document.selection) {
    myField.focus();
    sel = document.selection.createRange();
    sel.text = myValue;
  }
  //MOZILLA and others
  else if (myField.selectionStart || myField.selectionStart == '0') {
    var startPos = myField.selectionStart;
    var endPos = myField.selectionEnd;
    myField.value = myField.value.substring(0, startPos) +
      myValue +
      myField.value.substring(endPos, myField.value.length);
  } else {
    myField.value += myValue;
  }
}

function simulate(e) { // Simulates the key event
  try {
    if (e.key.split('-').length === 2 && e.key.split('-')[1] === 'true') { // Checks for the condition
      insertAtCursor(input, e.key.split('-')[0]) // Insert it
    }
  } catch (e) {
    if (e.name !== 'TypeError') {
      throw e
    }
  }
}


var arr = ['keydown', 'beforeinput', 'keypress', 'input', 'change', 'keyup'] // Array of desired events

arr.forEach(function(event) {
  input.addEventListener(event, simulate) // Dynamically add event listeners
})

input.focus();
setTimeout(() => input.dispatchEvent(eventFactory('keydown')), 10)
setTimeout(() => input.dispatchEvent(eventFactory('beforeinput')), 20)
setTimeout(() => input.dispatchEvent(eventFactory('keypress')), 30)
setTimeout(() => input.dispatchEvent(eventFactory('input')), 40)
setTimeout(() => input.dispatchEvent(eventFactory('change')), 50)
setTimeout(() => input.dispatchEvent(eventFactory('keyup')), 60)

function eventFactory(eventName) {
  return new KeyboardEvent(eventName, {
    key: "e-true", // It is modified to e-true instead of e to allow us to check
    keyCode: 69, // example values.
    code: "KeyE", // put everything you need in this object.
    which: 69,
    shiftKey: false, // you don't need to include values
    ctrlKey: false, // if you aren't going to use them.
    metaKey: false, // these are here for example's sake.
  });
}
<input>

Alternatively, you could use input.value += 'Text to append'

const input = document.querySelector('input');

function simulate(e) { // Simulates the key event
  try {
    if (e.key.split('-').length === 2 && e.key.split('-')[1] === 'true') { // Checks for the condition
      input.value += e.key.split('-')[0] // Insert it
    }
  } catch (e) {
    if (e.name !== 'TypeError') {
      throw e
    }
  }
}


var arr = ['keydown', 'beforeinput', 'keypress', 'input', 'change', 'keyup'] // Array of desired events

arr.forEach(function(event) {
  input.addEventListener(event, simulate) // Dynamically add event listeners
})

input.focus();
setTimeout(() => input.dispatchEvent(eventFactory('keydown')), 10)
setTimeout(() => input.dispatchEvent(eventFactory('beforeinput')), 20)
setTimeout(() => input.dispatchEvent(eventFactory('keypress')), 30)
setTimeout(() => input.dispatchEvent(eventFactory('input')), 40)
setTimeout(() => input.dispatchEvent(eventFactory('change')), 50)
setTimeout(() => input.dispatchEvent(eventFactory('keyup')), 60)

function eventFactory(eventName) {
  return new KeyboardEvent(eventName, {
    key: "e-true", // It is modified to e-true instead of e to allow us to check
    keyCode: 69, // example values.
    code: "KeyE", // put everything you need in this object.
    which: 69,
    shiftKey: false, // you don't need to include values
    ctrlKey: false, // if you aren't going to use them.
    metaKey: false, // these are here for example's sake.
  });
}
<input>

Upvotes: 1

CamiEQ
CamiEQ

Reputation: 771

Events are actually being triggered in your code, but for security reasons (https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent), you need to manually define what the effect on the event will be.

const input = document.querySelector('input');

const addInput = (event) => {
   console.log(`Event type: ${event.type}`);
   console.log(`Key pressed: ${event.key}`);
   input.value = input.value + event.key;
};

input.addEventListener('keydown', addInput, false);
input.addEventListener('beforeinput', addInput, false);
input.addEventListener('keypress', addInput, false);
input.addEventListener('input', addInput, false);
input.addEventListener('change', addInput, false);
input.addEventListener('keyup', addInput, false);


input.focus();
setTimeout(() => input.dispatchEvent(eventFactory('keydown')), 10)
setTimeout(() => input.dispatchEvent(eventFactory('beforeinput')), 20)
setTimeout(() => input.dispatchEvent(eventFactory('keypress')), 30)
setTimeout(() => input.dispatchEvent(eventFactory('input')), 40)
setTimeout(() => input.dispatchEvent(eventFactory('change')), 50)
setTimeout(() => input.dispatchEvent(eventFactory('keyup')), 60)

function eventFactory(eventName) {
  return new KeyboardEvent(eventName, {
    key: "e",
    keyCode: 69, // example values.
    code: "KeyE", // put everything you need in this object.
    which: 69,
    shiftKey: false, // you don't need to include values
    ctrlKey: false,  // if you aren't going to use them.
    metaKey: false   // these are here for example's sake.
  });
}
<input> 

Upvotes: 0

Related Questions