Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery: Getting new value in keydown handler

I came across this question: onKeyPress Vs. onKeyUp and onKeyDown, from where I found that keypress is supposed to fire whenever a character is typed into the text input. I am trying to run this following code. It is supposed to make the input's background yellow the moment its text length exceeds 0, or white the moment it is 0. I can't make it work. If I try to do keydown, I have the following problems:

  1. If I just type one character and let go, the background remains white.

  2. If then, I press backspace, thus clearing that one character, it turns yellow (just opposite of what I want!). If I press any other key now (Alt,Shift) it will turn white again. In fact, if instead of Alt or Shift I type a character, it will still remain white, taking us back to the first problem.

  3. If I type press a character key and keep it pressed, the background remains white for the first character, and turns yellow 2nd character onwards.

If I try keyup only, these are the problems (as expected):

  1. The background doesn't change as long as the keys are kept pressed, even when a character is added to the empty input or the entire text deleted.

If I try keypress, I face the same problems as keydown, even though it is supposed to work.

If I bind 3 handlers for keyup, keydown and keypress (God I am desperate!), almost all problems are solved except problem 3 of keydown: if I type press a character key and keep it pressed, the background remains white for the first character, and turns yellow 2nd character onwards.

How do I solve this problem?

JS:

$(document).ready(function() {

    $("input").bind("keydown", function() {
        if ($(this).val().length == 0) {
            $(this).css('background', 'white');
        } else {
            $(this).css('background', 'yellow');
        }
    });

    $("input").bind("keypress", function() {
        if ($(this).val().length == 0) {
            $(this).css('background', 'white');
        } else {
            $(this).css('background', 'yellow');
        }
    });

    $("input").bind("keyup", function() {
        if ($(this).val().length == 0) {
            $(this).css('background', 'white');
        } else {
            $(this).css('background', 'yellow');
        }
    });

});

HTML:

<input type='text' />
like image 499
SexyBeast Avatar asked Aug 07 '13 22:08

SexyBeast


2 Answers

When the keydown event is fired, the character is not yet written to the input box.

I did some research and it's recommended to use timeout in order to get the behaviour you want. Apparently, during the tiny delay, a change event on the input is fired, and .val() then returns the new content.

Here's a working code:

$(document).ready(function () {
    var field = $("input");

    field.on("keydown", function (e) {
        setTimeout(function () {
            if (field.val().length == 0) {
                field.css('background', 'white');
            } else {
                field.css('background', 'yellow');
            }
        }, 1);
    });
});

Accompanied by a jsFiddle

like image 79
MightyPork Avatar answered Oct 04 '22 20:10

MightyPork


Although it is an old post, I came by the same question. The best way to achieve this without a timer is with input event:

$('#inputText').on('input', function() {
      const inputText = $(this).val()
      console.log(inputText)
  })
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-group">
  <input type="text" class="form-control" id="inputText">
</div>
like image 27
Eduardo Lazcano Avatar answered Oct 04 '22 21:10

Eduardo Lazcano