keydown event new value

William Isted picture William Isted · Jun 6, 2012 · Viewed 22.9k times · Source

Browser: Google Chrome V19.0.1084.52

I have a textbox which needs to be a number less than or equal to 255, on keydown I want to check if this value is above or equal to 255 else prevent the event.

In the Console when I console.log the event it will show event.srcElement.value as the value will appear i.e. from 12 => 123, when I console.log just event.srcElement.value it will show as the input was, not will be.

Console.log's are happening one after the other, nothing in between, no pauses.

How can I find what the new value of a textbox will be on keydown and why is the console.log returning different results?

Here's my code:

function inputNumeric(event,max) {

    console.log (event);
    console.log ('event.originalEvent.srcElement.value: '+event.originalEvent.srcElement.value);
    console.log ('event.srcElement.value: '+event.srcElement.value);

}

$("#rs485addr").keydown(function(event) {
    inputNumeric(event);
});

Console.log:

event.originalEvent.srcElement.value: 12
event.srcElement.value: 12

event.srcElement:

accept: ""
accessKey: ""
align: ""
alt: ""
attributes: NamedNodeMap
autocomplete: ""
autofocus: false
baseURI: "http://10.50.50.60/controller/?bid=10"
checked: false
childElementCount: 0
childNodes: NodeList[0]
children: HTMLCollection[0]
classList: DOMTokenList
className: "width-60"
clientHeight: 18
clientLeft: 2
clientTop: 2
clientWidth: 62
contentEditable: "inherit"
dataset: DOMStringMap
defaultChecked: false
defaultValue: "1"
dir: ""
dirName: ""
disabled: false
draggable: false
files: null
firstChild: null
firstElementChild: null
form: null
formAction: ""
formEnctype: "application/x-www-form-urlencoded"
formMethod: "get"
formNoValidate: false
formTarget: ""
hidden: false
id: "rs485addr"
incremental: false
indeterminate: false
innerHTML: ""
innerText: ""
isContentEditable: false
jQuery17102950612970162183: 22
labels: NodeList[1]
lang: ""
lastChild: null
lastElementChild: null
localName: "input"
max: ""
maxLength: 3
min: ""
multiple: false
name: ""
namespaceURI: "http://www.w3.org/1999/xhtml"
nextElementSibling: null
nextSibling: Text
nodeName: "INPUT"
nodeType: 1
nodeValue: null
offsetHeight: 22
offsetLeft: 183
offsetParent: HTMLBodyElement
offsetTop: 365
offsetWidth: 66
onabort: null
onbeforecopy: null
onbeforecut: null
onbeforepaste: null
onblur: null
onchange: null
onclick: null
oncontextmenu: null
oncopy: null
oncut: null
ondblclick: null
ondrag: null
ondragend: null
ondragenter: null
ondragleave: null
ondragover: null
ondragstart: null
ondrop: null
onerror: null
onfocus: null
oninput: null
oninvalid: null
onkeydown: null
onkeypress: null
onkeyup: null
onload: null
onmousedown: null
onmousemove: null
onmouseout: null
onmouseover: null
onmouseup: null
onmousewheel: null
onpaste: null
onreset: null
onscroll: null
onsearch: null
onselect: null
onselectstart: null
onsubmit: null
onwebkitfullscreenchange: null
onwebkitfullscreenerror: null
onwebkitspeechchange: null
outerHTML: "<input class="width-60" id="rs485addr" maxlength="3" type="textbox" value="1">"
outerText: ""
ownerDocument: HTMLDocument
parentElement: HTMLSpanElement
parentNode: HTMLSpanElement
pattern: ""
placeholder: ""
prefix: null
previousElementSibling: HTMLLabelElement
previousSibling: Text
readOnly: false
required: false
scrollHeight: 16
scrollLeft: 0
scrollTop: 0
scrollWidth: 60
selectionDirection: "forward"
selectionEnd: 3
selectionStart: 3
size: 20
spellcheck: true
src: ""
step: ""
style: CSSStyleDeclaration
tabIndex: 0
tagName: "INPUT"
textContent: ""
title: ""
translate: true
type: "text"
useMap: ""
validationMessage: ""
validity: ValidityState
value: "123"
valueAsDate: null
valueAsNumber: NaN
webkitGrammar: false
webkitRegionOverflow: "undefined"
webkitSpeech: false
webkitdirectory: false
webkitdropzone: ""
willValidate: true

Answer

Kane Cohen picture Kane Cohen · Jun 6, 2012

I'm not sure if it could be of any help, but when I had to deal with a similar situation in an event listener I used a setTimeout() with 1ms timeout where I put the main functionality checking for the value, etc.

That is because when the keydown event is fired the input field is not yet populated with the new data.

Simple jQuery example:

$('#input').on('keydown', function(e) {
  var field = $(this);
  var prevValue = field.val();
  setTimeout(function() {
    // check if new value is more or equal to 255
    if (field.val() >= 255) {
      // fill with previous value
      field.val(prevValue);
    }

  }, 1);
});

UPDATE

Use 'input' event in modern browsers.

var prevValue = 0;
$('#input').on('input', function(e) {
  var field = $(this);
  // check if new value is more or equal to 255
  if (field.val() >= 255) {
    // fill with previous value
    field.val(prevValue);
  } else {
    // If value is lower than 255 set it in prev value.
    prevValue = field.val();
  }
});