0

What I want is NOT to emulate a key press event in javascript, but get the value of a string after a key press.

To clarify; given a text input, I want to see what the value of my text input would be if the user pressed a certain key.

i.e, I want the following function.

function getStringValueAfterKeyPress(string, cursorPosition, keyCode) {
    // returns string value after key press with provided code on provided cursor position
}

getStringValueAfterKeyPress('test', 4, 8) // returns 'tes' (8 is keycode of backspace)
getStringValueAfterKeyPress('test', 4, 37) // returns 'test' (37 is keycode of left arrow, hence string value has not changed)
getStringValueAfterKeyPress('test', 4, 49) // returns 'test1' (49 is keycode of '1')

And so on. Is there a simple way of doing this?

P.S my use case will be to use this method on an afterKeyDown event, get the value of my input element after this key press using this method, and if it does not match a certain regex prevent the action.

Ozgur Akcali
  • 5,264
  • 2
  • 31
  • 49
  • Possible duplicate of [How to get text cursor position after keypress event happened?](https://stackoverflow.com/questions/36978192/how-to-get-text-cursor-position-after-keypress-event-happened) – Mark Schultheiss Aug 29 '18 at 11:02
  • Your wording is not very clear, but I think you are asking how to alter the string such that it will appear as if the user had pressed the key code provided? – ADyson Aug 29 '18 at 11:04
  • 1
    The only way I can think to do this is to do what you say you don't want, and emulate the keypress on an input and then get the value of it. – Reinstate Monica Cellio Aug 29 '18 at 11:04
  • 1
    @MarkSchultheiss I don't think that's it. OP is not asking how to get the cursor position after a keypress, they're asking how to process the string to change it to how it would look if the user had actually pressed the provided key while editing that string manually. – ADyson Aug 29 '18 at 11:06
  • Also possible https://stackoverflow.com/q/45850920/125981 – Mark Schultheiss Aug 29 '18 at 11:06
  • @MarkSchultheiss See the comment from ADyson above your last comment. Both your links are not relevant to what's being asked. – Reinstate Monica Cellio Aug 29 '18 at 11:06
  • @Archer What you suggested might be a solution, maybe creating a hidden input element, and emulating the key press event on that element and getting its value. But then, is it possible to do it without removing the focus from current input element? – Ozgur Akcali Aug 29 '18 at 11:08
  • OR perhaps https://stackoverflow.com/a/1846704/125981 NOTE: These are an attempt to offer assistance to a poorly worded question - which it APPEARS the critical part is "get the value of my input element after this key press using this method" – Mark Schultheiss Aug 29 '18 at 11:09
  • 1
    @MarkSchultheiss But you voted to close it as a duplicate?? – Reinstate Monica Cellio Aug 29 '18 at 11:10
  • One other thing that may perhaps be impacted is the use case where you press and hold a key down. – Mark Schultheiss Aug 29 '18 at 11:11
  • 1
    You can get the currently focused element, do any magic you need in the background to mimic a keypress in an input, and then set focus back to the original element, but I *think* you can use an element that's not part of the DOM, so you wouldn't lose focus anyway. – Reinstate Monica Cellio Aug 29 '18 at 11:12
  • Now that you've updated the question, you just need to handle the `input` event, which is triggered by all changes to an input as they happen (unlike the `change` event that is only triggered when the input loses focus). – Reinstate Monica Cellio Aug 29 '18 at 11:20
  • @Archer seems like browser is preventing programmatic changes to input elements for security reasons. element.trigger(jQuery.Event('keypress', { which: 69 })) or any other variation of this does not change input value. – Ozgur Akcali Aug 29 '18 at 11:46
  • 1
    Have a look at my posted answer - I think you're going down a long and difficult route, and it's the wrong way to go. – Reinstate Monica Cellio Aug 29 '18 at 11:47
  • 1
    Archer is totally right, I see your intent now. The word for what you're trying to do is "validation". If you search for information about that you'll see there are _much_ easier ways to achieve it in HTML / JavaScript. In HTML5 a lot of the basic validation rules you might want are provided ready-made by simply adding an attribute to your input element. For more complex requirements you can detect the user input yourself (as per Archer's answer) and write some custom JavaScript to decide if it's valid or not. See also https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Form_validation – ADyson Aug 29 '18 at 11:56

1 Answers1

1

You can validate input as it happens by handling the input event which is triggered every time there is a change in an input field, including keypresses, copy/paste, drag & drop etc..

Here's an example of validating a name input field that doesn't allow numbers...

// our validation function to stop numbers being entered
function noNumbersAllowed() {
  this.value = this.value.replace(/\d/g, "");
}

// keep a reference to the element, so we don't have to search the DOM repeatedly
var nameInput = document.getElementById("name");

// create an input event listener that removes all numbers
nameInput.addEventListener("input", noNumbersAllowed);

// set focus because we're nice like that
nameInput.focus();
<input id="name" type="text" placeholder="Enter name (no numbers)"/>

You can have multiple types of validation functions (if you need them) and assign them to whatever inputs require validation.

Reinstate Monica Cellio
  • 25,975
  • 6
  • 51
  • 67
  • In my actual usecase, I have an input element where users can enter numeric values with at most 2 decimal places. So 1.00 is valid, but 1.000 is not valid, or 1..0 is not valid. So I can not validate the input by just looking at the entered character, or by modifying user input. My input box initially has a valid value and I want to prevent any actions that would cause the input value to be invalid. – Ozgur Akcali Aug 29 '18 at 11:56
  • Yes you can - just set the input to `Number(this.value).toFixed(2);` Properly validating the input is a much easier way to go than trying to second-guess input keypresses and what they may mean. Input validation has also become native since HTML5... https://webdesign.tutsplus.com/tutorials/html5-form-validation-with-the-pattern-attribute--cms-25145 – Reinstate Monica Cellio Aug 29 '18 at 11:58
  • There's also a link from ADyson in the question comments. Either method of validation will definitely be easier to implement than your original method. – Reinstate Monica Cellio Aug 29 '18 at 12:01
  • Let's say the current value of the input is "1.00", and the user presses the '.' key. I can not convert "1.00." to a number, it results in NaN. Instead, I want to prevent user from entering the last '.' character at the end. – Ozgur Akcali Aug 29 '18 at 12:01
  • This is actually about the experience I want to provide to the user, I can end up using any validation method in the end, but just wanted to see If I could do it by preventing any keypress by the user that would make the input value invalid. – Ozgur Akcali Aug 29 '18 at 12:04
  • 1
    In that case, keep the last valid value stored as a data attribute on the element, and if it becomes invalid when it changes, set it back to the last valid value. These are obviously just quick examples - you can go as far as you want with what you do with it. Handling keypresses will be difficult to implement in all browsers and will definitely fail in future versions (of IE most likely). Using HTML5 patters is probably the most future-proof method. – Reinstate Monica Cellio Aug 29 '18 at 12:05