How to get text of an input text box during onKeyPress?
Asked Answered
A

12

103

I am trying to get the text in a text box as the user types in it (jsfiddle playground):

function edValueKeyPress() {
    var edValue = document.getElementById("edValue");
    var s = edValue.value;

    var lblValue = document.getElementById("lblValue");
    lblValue.innerText = "The text box contains: " + s;

    //var s = $("#edValue").val();
    //$("#lblValue").text(s);    
}
<input id="edValue" type="text" onKeyPress="edValueKeyPress()"><br>
<span id="lblValue">The text box contains: </span>

​ The code runs without errors, except that the value of the input text box, during onKeyPress is always the value before the change:

enter image description here

Question: How do I get the text of a text box during onKeyPress?

Bonus Chatter

There are three events related to "the user is typing" in the HTML DOM:

  • onKeyDown
  • onKeyPress
  • onKeyUp

In Windows, the order of WM_Key messages becomes important when the user holds down a key, and the key begins to repeat:

  • WM_KEYDOWN('a') - user has pushed down the A key
  • WM_CHAR('a') - an a character has been received from the user
  • WM_CHAR('a') - an a character has been received from the user
  • WM_CHAR('a') - an a character has been received from the user
  • WM_CHAR('a') - an a character has been received from the user
  • WM_CHAR('a') - an a character has been received from the user
  • WM_KEYUP('a') - the user has released the A key

Will result in five characters appearing in a text control: aaaaa

The important point being that the you respond to the WM_CHAR message, the one that repeats. Otherwise you miss events when a key is pressed.

In HTML things are slightly different:

  • onKeyDown
  • onKeyPress
  • onKeyDown
  • onKeyPress
  • onKeyDown
  • onKeyPress
  • onKeyDown
  • onKeyPress
  • onKeyDown
  • onKeyPress
  • onKeyUp

Html delivers an KeyDown and KeyPress every key repeat. And the KeyUp event is only raised when the user releases the key.

Take aways

  • I can respond to onKeyDown or onKeyPress, but both are still raised before the input.value has been updated
  • I cannot respond to onKeyUp, because it doesn't happen as the text in the text-box changes.

Question: How do I get the text of a text-box during onKeyPress?

Bonus Reading

Assuasive answered 6/7, 2012 at 15:56 Comment(5)
I believe you need to append the current keypress to the value before you return it; the value gets updated on keyUp, but the data is available to you on keyDown.Pirali
Key up works for me, you don't need jQ for something like this, unless you like to add bloatScots
it is enough only onKeyUp for your taskIntuitionism
@mit Only handling onKeyUp doesn't show the changes in the text box as they happen.Assuasive
if you want to hold down any key and get result in textbox, of cause you should use both onKeyPress and onKeyDown events Jonathan M's fiddle, but if you want to get result without holding down the keys it is enough only onKeyUp my fiddle.Intuitionism
U
34

Handling the input event is a consistent solution: it is supported for textarea and input elements in all contemporary browsers and it fires exactly when you need it:

function edValueKeyPress() {
    var edValue = document.getElementById("edValue");
    var s = edValue.value;

    var lblValue = document.getElementById("lblValue");
    lblValue.innerText = "The text box contains: " + s;
}
<input id="edValue" type="text" onInput="edValueKeyPress()"><br>
<span id="lblValue">The text box contains: </span>

I'd rewrite this a bit, though:

function showCurrentValue(event)
{
    const value = event.target.value;
    document.getElementById("label").innerText = value;
}
<input type="text" onInput="showCurrentValue(event)"><br>
The text box contains: <span id="label"></span>
Urbanite answered 4/1, 2019 at 14:1 Comment(0)
S
57

Keep it simple. Use both onKeyPress() and onKeyUp():

<input id="edValue" type="text" onKeyPress="edValueKeyPress()" onKeyUp="edValueKeyPress()">

This takes care of getting the most updated string value (after key up) and also updates if the user holds down a key.

jsfiddle: http://jsfiddle.net/VDd6C/8/

Sterrett answered 6/7, 2012 at 16:4 Comment(3)
Since arnaud576875's answer had to give up and fallback to onKeyUp (defeating the purpose of using onKeypress), this is the simplest, cleanest, and closest answer anyone's gonna see. Only the most carefully observant user will notice the feedback doesn't match what they've entered.Assuasive
@Ian, glad to help. What do you mean by "feedback doesn't match what they've entered"? Is an adjustment needed?Sterrett
i remember what i meant now! The feedback i'm referring go would be coloring the <input> element red, or green, or giving some other feedback to the user that what they've typed is good or bad. While your accepted answer still suffers from the problem of always being "off-by-one" character: only the most observant user will notice the feedback doesn't match what they've entered." In reality, since the off-by-one-error only happens during key-repeat (i.e. they're holding the key down) nobody (besides me) is going to notice the problem.Assuasive
U
34

Handling the input event is a consistent solution: it is supported for textarea and input elements in all contemporary browsers and it fires exactly when you need it:

function edValueKeyPress() {
    var edValue = document.getElementById("edValue");
    var s = edValue.value;

    var lblValue = document.getElementById("lblValue");
    lblValue.innerText = "The text box contains: " + s;
}
<input id="edValue" type="text" onInput="edValueKeyPress()"><br>
<span id="lblValue">The text box contains: </span>

I'd rewrite this a bit, though:

function showCurrentValue(event)
{
    const value = event.target.value;
    document.getElementById("label").innerText = value;
}
<input type="text" onInput="showCurrentValue(event)"><br>
The text box contains: <span id="label"></span>
Urbanite answered 4/1, 2019 at 14:1 Comment(0)
S
19

the value of the input text box, during onKeyPress is always the value before the change

This is on purpose: This allows the event listener to cancel the keypress.

If the event listeners cancels the event, the value is not updated. If the event is not canceled, the value is updated, but after the event listener was called.

To get the value after the field value has been updated, schedule a function to run on the next event loop. The usual way to do this is to call setTimeout with a timeout of 0:

$('#field').keyup(function() {
    var $field = $(this);

    // this is the value before the keypress
    var beforeVal = $field.val();

    setTimeout(function() {

        // this is the value after the keypress
        var afterVal = $field.val();
    }, 0);
});

Try here: http://jsfiddle.net/Q57gY/2/

Edit: Some browsers (e.g. Chrome) do not trigger keypress events for backspace; changed keypress to keyup in code.

Stedman answered 6/7, 2012 at 16:3 Comment(4)
Was about to post this. Here is the jsFiddle I did.Bonedry
You are right, Chrome seems to not trigger keypress events for backspace; updatedStedman
@Ian, Is the OP wanting it to update as a key is held down? Wasn't too sure if this was a requirement. This solution doesn't have that functionality, though.Sterrett
To be clear: Not to trigger keypress events for backspace is per Standard : "key that produces a character value" - for other keys use "keydown" (before change, cancellable) or "keyup" (after change)Jaw
P
5

keep it Compact.
Each time you press a key, the function edValueKeyPress() is called.
You've also declared and initialized some variables in that function - which slow down the process and requires more CPU and memory as well.
You can simply use this code - derived from simple substitution.

function edValueKeyPress()
{
    document.getElementById("lblValue").innerText =""+document.getElementById("edValue").value;
}

That's all you want, and it's faster!

Paraffin answered 22/3, 2015 at 7:40 Comment(0)
D
3
<asp:TextBox ID="txtMobile" runat="server" CssClass="form-control" style="width:92%;  margin:0px 5px 0px 5px;" onkeypress="javascript:return isNumberKey(event);" MaxLength="12"></asp:TextBox>

<script>
    function isNumberKey(evt) {
        var charCode = (evt.which) ? evt.which : event.keyCode;
        if (charCode > 31 && (charCode < 48 || charCode > 57)) {
            return false;
        }
        return true;
    }
</script>
Disbursement answered 27/9, 2014 at 12:4 Comment(0)
A
3

None of the answers so far offer a complete solution. There are quite a few issues to address:

  1. Not all keypresses are passed onto keydown and keypress handlers (e.g. backspace and delete keys are suppressed by some browsers).
  2. Handling keydown is not a good idea. There are situations where a keydown does NOT result in a keypress!
  3. setTimeout() style solutions get delayed under Google Chrome/Blink web browsers until the user stops typing.
  4. Mouse and touch events may be used to perform actions such as cut, copy, and paste. Those events will not trigger keyboard events.
  5. The browser, depending on the input method, may not deliver notification that the element has changed until the user navigates away from the field.

A more correct solution will handle the keypress, keyup, input, and change events.

Example:

<p><input id="editvalue" type="text"></p>
<p>The text box contains: <span id="labelvalue"></span></p>

<script>
function UpdateDisplay()
{
    var inputelem = document.getElementById("editvalue");
    var s = inputelem.value;

    var labelelem = document.getElementById("labelvalue");
    labelelem.innerText = s;
}

// Initial update.
UpdateDisplay();

// Register event handlers.
var inputelem = document.getElementById("editvalue");
inputelem.addEventListener('keypress', UpdateDisplay);
inputelem.addEventListener('keyup', UpdateDisplay);
inputelem.addEventListener('input', UpdateDisplay);
inputelem.addEventListener('change', UpdateDisplay);
</script>

Fiddle:

http://jsfiddle.net/VDd6C/2175/

Handling all four events catches all of the edge cases. When working with input from a user, all types of input methods should be considered and cross-browser and cross-device functionality should be verified. The above code has been tested in Firefox, Edge, and Chrome on desktop as well as the mobile devices I own.

Anaxagoras answered 30/8, 2017 at 2:36 Comment(3)
Why not just input event?Urbanite
input does not always fire. No single event covers all situations.Anaxagoras
would be nice of you if you describe "not always" in more detail, like you specified for keypress in the answerUrbanite
K
1

I normally concatenate the field's value (i.e. before it's updated) with the key associated with the key event. The following uses recent JS so would need adjusting for support in older IE's.

Recent JS example

document.querySelector('#test').addEventListener('keypress', function(evt) {
    var real_val = this.value + String.fromCharCode(evt.which);
    if (evt.which == 8) real_val = real_val.substr(0, real_val.length - 2);
    alert(real_val);
}, false);

Support for older IEs example

//get field
var field = document.getElementById('test');

//bind, somehow
if (window.addEventListener)
    field.addEventListener('keypress', keypress_cb, false);
else
    field.attachEvent('onkeypress', keypress_cb);

//callback
function keypress_cb(evt) {
    evt = evt || window.event;
    var code = evt.which || evt.keyCode,
        real_val = this.value + String.fromCharCode(code);
    if (code == 8) real_val = real_val.substr(0, real_val.length - 2);
}

[EDIT - this approach, by default, disables key presses for things like back space, CTRL+A. The code above accommodates for the former, but would need further tinkering to allow for the latter, and a few other eventualities. See Ian Boyd's comment below.]

Kerrill answered 6/7, 2012 at 16:5 Comment(2)
@bažmegakapa Or with the delete key, or if the user presses a key that doesn't modify the contents (Ctrl+A), or if the user selects some text and then presses a to replace a subset. It's a fine idea, Utkanos, but a fragile one.Assuasive
Agreed. I'll leave it up as there is some mileage in it but, as you say, you'd have to build in allowances for these caveats.Kerrill
O
1

easy...

In your keyPress event handler, write

void ValidateKeyPressHandler(object sender, KeyPressEventArgs e)
{
    var tb = sender as TextBox;
    var startPos = tb.SelectionStart;
    var selLen= tb.SelectionLength;

    var afterEditValue = tb.Text.Remove(startPos, selLen)
                .Insert(startPos, e.KeyChar.ToString()); 
    //  ... more here
}
Overmantel answered 2/5, 2013 at 16:33 Comment(2)
What happens if e.KeyChar is the Backspace key? Or the Delete key? Or Ctrl+A?Assuasive
Is this even JavaScript? void? object? first-upper-case methods?Urbanite
I
1

So there are advantages and disadvantages to each event. The events onkeypress and onkeydown don't retrieve the latest value, and onkeypress doesn't fire for non-printable characters in some browsers. The onkeyup event doesn't detect when a key is held down for multiple characters.

This is a little hacky, but doing something like

function edValueKeyDown(input) {
    var s = input.value;

    var lblValue = document.getElementById("lblValue");
    lblValue.innerText = "The text box contains: "+s;

    //var s = $("#edValue").val();
    //$("#lblValue").text(s);    
}
<input id="edValue" type="text" onkeydown="setTimeout(edValueKeyDown, 0, this)" />

seems to handle the best of all worlds.

Isidora answered 11/9, 2015 at 18:28 Comment(0)
S
1

By using event.key we can get values prior entry into HTML Input Text Box. Here is the code.

function checkText()
{
  console.log("Value Entered which was prevented was - " + event.key);
  
  //Following will prevent displaying value on textbox
  //You need to use your validation functions here and return value true or false.
  return false;
}
<input type="text" placeholder="Enter Value" onkeypress="return checkText()" />
Shearin answered 3/5, 2017 at 8:12 Comment(2)
This falls apart when the text is changed through something that is not a keypress (cut, paste, delete selected, etc)Assuasive
@IanBoyd yes agreed. To keep the example simple I have implemented only keypress validations.Shearin
A
0

Try to concatenate the event charCode to the value you get. Here is a sample of my code:

<input type="text" name="price" onkeypress="return (cnum(event,this))" maxlength="10">
<p id="demo"></p>

js:

function cnum(event, str) {
    var a = event.charCode;
    var ab = str.value + String.fromCharCode(a);
    document.getElementById('demo').innerHTML = ab;
}

The value in ab will get the latest value in the input field.

Acid answered 13/7, 2016 at 7:29 Comment(5)
Sorry, I noticed another post with even better approach in this page after i posted this. I didn't see that before posting. But i think mine is simpler to understand the concept.Acid
That falls apart pretty quick when the key is delete, backspace, Ctrl+X or Ctrl+V, or when the mouse selected all the text and i press SpaceAssuasive
I just wrote my idea. you can implement it by according to your requirement by using keycodes or other methods. This is just my idea.Acid
Ideas are not answers. Answers on SO should be concise solutions that definitively answer the OP's question so that everyone can benefit. This clearly does not meet that criteria.Anaxagoras
Good idea with String.fromCharCode(a). Thank.Otes
E
0

There is a better way to do this. Use the concat Method. Example

declare a global variable. this works good on angular 10, just pass it to Vanilla JavaScript. Example:

HTML

<input id="edValue" type="text" onKeyPress="edValueKeyPress($event)"><br>
<span id="lblValue">The text box contains: </span>

CODE

emptyString = ''

edValueKeyPress ($event){
   this.emptyString = this.emptyString.concat($event.key);
   console.log(this.emptyString);
}
Eterne answered 9/8, 2020 at 3:32 Comment(1)
And when the key is Delete, Ctrl+X, Ctrl+V, Backspace? Or if they've selected some text, and then press A?Assuasive

© 2022 - 2024 — McMap. All rights reserved.