I first used the onKeyUp event to detect input changes in a textbox. However, when the user enters in a French character using ALT+Num, the event doesn't detect the change until i enter the next character...
Which event should I be using to detect the special character changes. I've tried onChange but does not seem to be working.
I've tried using onkeypress event because I notice that it triggers it after i release the ALT key, however even though once the ALT is release, the onkeypress is triggered and you see the accented character, but when I use this.value for the inputbox, it only registers up to and before the new ALT+Num character is input.
for example: i entered vidé, but the search would not dynamically find vidé, but only vid because the é has not been saved in the - this.value yet, until another key event is triggered.
Hence I was wondering if there's way to simulate/send a key press to trigger it.
FINALLY FIGURED IT OUT!! :D
here's the code, however the String converting event.which code does not work on the jsFiddle though, nonetheless the code works :)
$('#i').keydown(function() {
document.getElementById('j').value = "down";
$('#k').val($('#i').val())
});
$('#i').keyup(function() {
document.getElementById('j').value = "up";
$('#k').val($('#i').val())
});
$('#i').keypress(function(event) {
$('#k').val(String.fromCharCode(event.keycode));
});
$('#i').change(function() {
document.getElementById('j').value = "change";
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="i" type="text" /><br />
<input id="j" type="text" />
<input id="k" type="text" />
View on JSFiddle
use keyup. The new character will not be added until the user releases the ALT key and at that point the keyup event will fire.
There's a reference at http://unixpapa.com/js/key.html which might be a good idea to have a look at, and according to section 2.1, ALT should generate a keydown and keyup in modern browsers..
I would suggest you use jQuery or a similar library to ease the issues you're facing cross-browser. Have a look at http://jsfiddle.net/qvDbu/1/ for a proof of concept which works fine.
Keypress is not triggered by only modifier-presses, so that's probably the way to go, it allows you to pick up the character entered as well, rather then which key is pressed. Edit: Seems to not be the case in Fx that keypress is triggered by modifiers, but I'm not able to reproduce actually loosing any characters.
The character entered with the ALT+NUM combination will only be added to the input element's value after the keyup event triggers, so you won't be able to read it in that event handler.
In order to solve this problem you could set a timeout on the ALT keyup event before reading the input element's value:
$('input').on('keyup', function (e) {
var _this = this;
var ALT_KEY_CODE = 18;
if (e.which == ALT_KEY_CODE) {
setTimeout(function () {
handleKeyup.call(_this , e);
}, 1);
} else {
handleKeyup.call(_this , e);
}
});
function handleKeyup (e) {
// $(this).val() now holds the ALT+NUM char
}
You need to bind onkeypress, which won't fire until you finish entering the alt code.
document.getElementById('input').onkeypress = function() {
alert('fired');
}
<input id='input' type='text' />
View on JSFiddle
Related
Is there any way to replay a keyboard event to a textfield and also make the receiving input field add that character to its text? Because I can't make it to work.
Let's say I press a on the keyboard and a global handler on body captures it. Now I want to replay it to a given textfield. So if the user presses a on the keyboard it would show up inside the textfield, solely based on the event. The event pops up at the input, but the character is not inputted. Is this possible? I want to avoid manipulating the input text with .val();
Example:
$('body').on('keyup', eKeyUp);
$('#mancineni').on('keyup', eKeyUpINPUT);
function eKeyUp(e)
{
$e = $.Event('keyup');
$e.which = e.which;
$e.charCode = e.charCode;
$e.keyCode = e.keyCode;
$e.shiftKey = e.shiftKey;
$e.key = e.key;
$('#mancineni').trigger($e);
//$('#mancineni').focus();
}
function eKeyUpINPUT(e)
{
console.log('g', e)
e.stopPropagation();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="mancineni">
It feels like you are making this much more difficult than it actually is. Just set the value of the input to event.key while handling it at the body level. Not sure why the need to avoid doing that, perhaps you could explain.
$('body').on('keyup', eKeyUp);
$('#mancineni').on('keyup', eKeyUpINPUT);
function eKeyUp(e){
$('#mancineni').val(event.key);
}
function eKeyUpINPUT(e){
e.stopPropagation();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="mancineni">
I would like to trigger a click if enter is pressed inside an input tag, but would like to have the default event strategy in all other cases. I have tried it this way:
$("#keywords").keypress(function(e) {
if (e.charCode === 13) {
$("#campus-search").click();
} else {
$("#keywords").val($("#keywords").val() + String.fromCharCode(e.charCode));
}
});
It works, but I am still not satisfied, because when I click inside the input somewhere in the middle of text or press the left button, or home button and then try to type some text, it will show it at the end of the input, which is bad user-experience. Can I keep the input to work in the default way except the case when enter is pressed?
I think what you are looking for is this:
$(document).ready(function () {
$("#test").keyup(function (event) {
if (event.keyCode == 13) {
$("#campus-search").click();
}
});
$("#campus-search").click(function () {
console.log("BUTTON IS CLICKED");
});
});
The input will act completely normal and everything works on default, unless when you press the enter button (keyCode = 13), then the button .click() event will be triggered.
Working Fiddle: http://jsfiddle.net/Mz2g8/3/
————
# Update: Just one hint for the code in your question, do not use charCode, as it is deprecated.
This feature has been removed from the Web. Though some browsers may still support it, it is in the process of being dropped. Do not use it in old or new projects. Pages or Web apps using it may break at any time.
(E.g. charCode does not work with FF v29.0.1)
And something different but important to know:
charCode is never set in the keydown and keyup events. In these cases, keyCode is set instead.
Source: https://developer.mozilla.org/en-US/docs/Web/API/event.charCode
This should work
$("#keywords").keypress(function(e) {
if (e.charCode === 13) {
e.preventDefault(); // prevent default action of the event if the event is keypress of enter key
$("#campus-search").click();
} else {
$("#keywords").val($("#keywords").val() + String.fromCharCode(e.charCode));
}
});
I think you can eliminate the else clause entirely to get your desired result.
Look at this jsfiddle.
The keypress function does not capture non-printing keys, such as shift, esc, delete, and enter, so the best way to go about this would be have two event handlers: one for keypress, as you have defined above, and one for keydown that checks for the charCode 13 and then performs the click() event on $(#campus-search) if that keycode is passed (by an enter press).
Demo
This is what you are looking for:
HTML:
<input id="keywords" type="text" value="" />
<input id="campus-search" type="button" value="Campus Search" />
JavaScript / jQuery:
$("#keywords").keypress(function (e) {
if (e.charCode === 13) {
$("#campus-search").click();
} else {
$("#keywords").val($("#keywords").val() + String.fromCharCode(e.charCode));
}
});
$("#campus-search").on("click", function () {
alert("Searching..");
});
Live Demo
I'm having a problem capturing Tab Keydown events on date inputs. Say I have a form with five inputs, the first and last of which are date inputs (the html here is for reference... I know it's missing ID, tabindex, etc.):
<form id="heyImAForm">
<input type="date" id="in1" />
<input type="text" id="notimportant2" />
<input type="text" id="notimportant3" />
<input type="text" id="notimportant4" />
<input type="date" id="in5" />
</div>
What I'd like to do is call a method when the user Shift-Tabs out of the first input, and when the user Tabs out of the last input.
The problem is, I'd like to preserve the native Tab key behavior for date inputs, which is to move between days/months/years. So, something like this:
$('#in1').keydown(function(e) {
if (e.which == 9 && e.shiftKey) {
doAThing();
}
});
$('#in5').keydown(function(e) {
if (e.which == 9) {
doADifferentThing();
}
});
.... "works", but effectively kills that native Tab key behavior. So, long story short, is there a way to only trigger the Tab key event if the focus shifts away from the date input, as opposed to moving between day/month/year?
After trying a few things I think the best solution would be what you see here but please read on to get a full understanding of what I am doing. We are setting the focusout when the user hits shift-tab on the first element or shift without tab on the second element. We must unbind this action if the user hit something else so we don't fire the action if they shift-tab but stay within the element then shift out of it. So try something like this:
$('#in1').keydown(function(e) {
if (e.which == 9 && e.shiftKey) {
$(document).mousedown(function(){
$('#in1').unbind('focusout');
$(document).unbind('mousedown');
});
$('#in1').focusout(function(){
doAThing();
});
} else {
$('#in1').unbind('focusout');
$(document).unbind('mousedown');
}
});
$('#in5').keydown(function(e) {
if (e.which == 9 && !e.shiftKey) {
$(document).mousedown(function(){
$('#in5').unbind('focusout');
$(document).unbind('mousedown');
});
$('#in5').focusout(function(){
doADifferentThing();
});
} else {
$('#in5').unbind('focusout');
$(document).unbind('mousedown');
}
});
You can see we are also setting mousedown of the entire document when the shift-tab(in1) or tab-without-shift(in5) is being hit. In the mousedown we are unbinding the focusout so if the focus leaves because of a mouse click we don't fire doAThing(). We also unbind mousedown on the document because you don't want it firing every time the user clicks after tabbing(in5) or shift-tabbing(in1) on those elements.
You may also be interested in seeing what I did on this fiddle. This isn't the best solution because the setTimeout's can cause some problems and undesired effect in many cases.
Also, in your provided code the closing tag should be </form> not </div>.
I have an input element and I want to keep checking the length of the contents and whenever the length becomes equal to a particular size, I want to enable the submit button, but I am facing a problem with the onchange event of Javascript as the event fires only when the input element goes out of scope and not when the contents change.
<input type="text" id="name" onchange="checkLength(this.value)" />
----onchange does not fire on changing contents of name, but only fires when name goes out of focus.
Is there something I can do to make this event work on content change? or some other event I can use for this?
I found a workaround by using the onkeyup function, but that does not fire when we select some content from the auto completer of the browser.
I want something which can work when the content of the field change whether by keyboard or by mouse... any ideas?
(function () {
var oldVal;
$('#name').on('change textInput input', function () {
var val = this.value;
if (val !== oldVal) {
oldVal = val;
checkLength(val);
}
});
}());
This will catch change, keystrokes, paste, textInput, input (when available). And not fire more than necessary.
http://jsfiddle.net/katspaugh/xqeDj/
References:
textInput — a W3C DOM Level 3 event type. http://www.w3.org/TR/DOM-Level-3-Events/#events-textevents
A user agent must dispatch this event when one or more characters have
been entered. These characters may originate from a variety of
sources, e.g., characters resulting from a key being pressed or
released on a keyboard device, from the processing of an input method
editor, or resulting from a voice command. Where a “paste” operation
generates a simple sequence of characters, i.e., a text passage
without any structure or style information, this event type should be
generated as well.
input — an HTML5 event type.
Fired at controls when the user changes the value
Firefox, Chrome, IE9 and other modern browsers support it.
This event occurs immediately after modification, unlike the onchange event, which occurs when the element loses focus.
It took me 30 minutes to find it, but this is working in June 2019.
<input type="text" id="myInput" oninput="myFunction()">
and if you want to add an event listener programmatically in js
inputElement.addEventListener("input", event => {})
As an extention to katspaugh's answer, here's a way to do it for multiple elements using a css class.
$('.myclass').each(function(){
$(this).attr('oldval',$(this).val());
});
$('.myclass').on('change keypress paste focus textInput input',function(){
var val = $(this).val();
if(val != $(this).attr('oldval') ){
$(this).attr('oldval',val);
checkLength($(this).val());
}
});
Do it the jQuery way:
<input type="text" id="name" name="name"/>
$('#name').keyup(function() {
alert('Content length has changed to: '+$(this).val().length);
});
You can use onkeyup
<input id="name" onkeyup="checkLength(this.value)" />
You would have to use a combination of onkeyup and onclick (or onmouseup) if you want to catch every possibility.
<input id="name" onkeyup="checkLength(this.value)" onmouseup="checkLength(this.value)" />
Here is another solution I develop for the same problem. However I use many input boxes so I keep old value as an user-defined attribute of the elements itself: "data-value". Using jQuery it is so easy to manage.
$(document).delegate('.filterBox', 'keyup', { self: this }, function (e) {
var self = e.data.self;
if (e.keyCode == 13) {
e.preventDefault();
$(this).attr('data-value', $(this).val());
self.filterBy(this, true)
}
else if (e.keyCode == 27) {
$(this).val('');
$(this).attr('data-value', '');
self.filterBy(this, true)
}
else {
if ($(this).attr('data-value') != $(this).val()) {
$(this).attr('data-value', $(this).val());
self.filterBy(this);
}
}
});
here is, I used 5-6 input boxes have class 'filterBox',
I make filterBy method run only if data-value is different than its own value.
i have a function that currently working on .keypress event when the user right something in the textbox it do some code, but i want the same event to be triggered also when the user clear the textbox .change doesn't help since it fires after the user change the focus to something else
Thanks
The keyup event will detect if the user has cleared the box as well (i.e. backspace raises the event but backspace does not raise the keypress event in IE)
$("#inputname").keyup(function() {
if (!this.value) {
alert('The box is empty');
}
});
jsFiddle
As Josh says, this gets fired for every character code that is pressed in the input. This is mostly just showing that you need to use the keyup event to trigger backspace, rather than the keypress event you are currently using.
The solution by Jonathon Bolster does not cover all cases. I adapted it to also cover modifications by cutting and pasting:
$("#inputname").on('change keyup copy paste cut', function() {
//!this.value ...
});
see http://jsfiddle.net/gonfidentschal/XxLq2/
Unfortunately it's not possible to catch the cases where the field's value is set using javascript. If you set the value yourself it's not an issue because you know when you do it... but when you're using a library such as AngularJS that updates the view when the state changes then it can be a bit more work. Or you have to use a timer to check the value.
Also see the answer for Detecting input change in jQuery? which suggests the 'input' event understood by modern browsers. So just:
$("#inputname").on('input', function() {
//!this.value ...
});
Another way that does this in a concise manner is listening for "input" event on textarea/input-type:text fields
/**
* Listens on textarea input.
* Considers: undo, cut, paste, backspc, keyboard input, etc
*/
$("#myContainer").on("input", "textarea", function() {
if (!this.value) {
}
});
You can check the value of the input field inside the on input' function() and combine it with an if/else statement and it will work very well as in the code below :
$( "#myinputid" ).on('input', function() {
if($(this).val() != "") {
//Do action here like in this example am hiding the previous table row
$(this).closest("tr").prev("tr").hide(); //hides previous row
}else{
$(this).closest("tr").prev("tr").show(); //shows previous row
}
});
Inside your .keypress or .keyup function, check to see if the value of the input is empty. For example:
$("#some-input").keyup(function(){
if($(this).val() == "") {
// input is cleared
}
});
<input type="text" id="some-input" />