Javascript Replace KeyPress on Input - javascript

So I was trying replace the key press "K" with "Z" in an input field.
I was successfully able to do it. But there is a slight delay which makes the user see that the "K" being changed to "Z".
This is my code:
function prinner (event)
{
document.getElementById("txx").innerHTML= event.key; //Displays key pressed on screen by changing text element.
if(event.keyCode == 32){
// User has pressed space
document.getElementById("txx").innerHTML= "Space";
}
if (event.key=="k") // Trying to replace this with z.
{
var curval = $("#namaye").val(); //namaye is the ID of the input field.
var nval = curval.slice(0,(curval.length-1))+"z";
$("#namaye").val(nval);
}
}
$("#namaye").keyup(prinner);
Does anyone know a better way to achieve this without the delay?

Use keydown instead of keyup and cancel the event so the key stroke doesn't actually get printed:
function prinner (event) {
// Displays key pressed on screen by changing text element.
document.getElementById("txx").innerHTML= event.key;
if(event.keyCode == 32){
// User has pressed space
document.getElementById("txx").innerHTML= "Space";
}
// Trying to replace this with z.
if (event.key=="k") {
var curval = $("#namaye").val(); //namaye is the ID of the input field.
var nval = curval +"z";
$("#namaye").val(nval);
// Cancel the event
event.preventDefault();
event.stopPropagation();
}
}
$("#namaye").keydown(prinner);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="namaye">
<p id="txx"></p>

Use keydown event, and cancel the default behaviour when k is pressed. Also, use selectionStart and selectionEnd properties to replace the characters that were selected at the moment the key was pressed, and to put the cursor at the right position, just after the inserted z:
function prinner (event) {
$("#txx").text(event.keyCode == 32 ? "Space" : event.key);
if (event.key=="k") {
var s = $(this).val();
var i = this.selectionStart;
s = s.substr(0, i) + "z" + s.substr(this.selectionEnd);
$(this).val(s);
this.selectionStart = this.selectionEnd = i + 1;
return false;
}
}
$("#namaye").keydown(prinner);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="namaye">
<div id="txx"></div>
Since you use jQuery, use $("#....") instead of the more verbose document.getElementById("...."). Also, in the event handler, this will be input element, so use that reference.

Try using keydown? It happens before the input is actually modified: in fact, if you return false (or e.preventDefault()) inside a keydown listener, it will actually cancel the keystroke, which I think is what you want. Then you manually add your new key. Something like (untested and skipping some details for clarity):
function prinner (event)
{
if (event.key=="k")
{
event.preventDefault() // makes sure the 'k' key never goes to the input
$("#namaye").val( $("#namaye").val() + 'z' );
}
}
$("#namaye").keyup(prinner);

You have to add an event.preventDefault() inside your if clause to stop the event propagation and then you can insert your "z" key.

Related

js onkeypress not working until next input

I am trying to insert a hyphen when the input size is exactly two.
Here is my code
document.getElementById('numberInput').onkeypress = function() {
if (this.value.length == 2) {
this.value = this.value + '-';
}
}
<input type="text" id="numberInput">
But the problem is the - doesn't appears until third character is inputted. Although the hyphen is placed properly, i mean after two characters.
How can i get hyphen right after entering two characters?
I tried onkeyup but the problem is it also fires when i press backspace button. When there are two characters, the hyphen appears but at that point if I press backspace and delete the hyphen it immediately comes back. So i choose onkeypress
the value of the input text box, during onKeyPress is always the value before the change. This allows the event listener to cancel the keypress.
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:
document.getElementById('numberInput').onkeypress = function() {
// arrow function keeps scope
setTimeout(() => {
// now it is the value after the keypress
if (this.value.length == 2) {
this.value = this.value + '-';
}
}, 0);
}
<input type="text" id="numberInput">
Why not hook onto the input event instead?
document.getElementById("numberInput")
.addEventListener("input", function(e) {
if (e.target.length === 2) {
e.target.value += "-";
}
});
This is happening because of event loop. this.value is updated only after key press. So in this case you always end up with old state.
I would recommend using other listener method, in this case oninput.
And retrieving latest input value throughout function parameters
In your case fix would be:
document.getElementById('numberInput').oninput = function (event) {
if (event.target.value.length === 2) {
this.value = event.target.value + '-'
}
}

Check if text is selected on keydown event

I have a scenario where i prevent user from entering 2nd numeric after a decimal.I have my code on keydown event.
Below is my code:
$scope.Inputkeydown = function (event, value) {
if (event.keyCode != 8) {
if (value != null && value != undefined && value != "") {
var regex = /^\d*\.\d$/; //this regex passes only decimal numbers with one digit after decimal
if (regex.test(value)) {
event.preventDefault();
}
}
}
};
Now the trouble is if user selects on the text(say 50.0) in the textbox and say presses 5 at that time it is getting prevented too, as in the textbox value is 50.0 and regex allows it go and it is getting prevented from being typed in.
Can i check on keydown if text is being copied?? or is there any other way around?
Instead of preventing the user from entering it, you could just remove it after keypress:
function filterDecimals(inp) {
return inp.replace(/^(\d*\.\d)\d*$/g, '$1');
}
Or, if you want to remove everything after it, replace the second \d* with .*
EDIT (example of usage)
This function takes the text as input and returns the new filtered text. To use this, just attach an event handler on keypress like so:
<input type="text" id="filteredbox">
<script>
var txt = document.getElementById("filteredbox");
// on keyup event (you can change to keypress if you want, but this is more logical here
txt.addEventListener("keyup", function(){
// sets value of txt to the returned data from filterDecimals()
// if statement: only filters it if necessary; this eliminates the "selected text" issue you mentioned
if (this.value !== filterDecimals(this.value)) {
this.value = filterDecimals(this.value);
}
});
</script>

Detect AltGr key using JavaScript

How can I clarify ALT+CTRL and ALTGR key press?
I found this code here as possible solution, but it's doesn't work:
if (event.ctrlKey && event.altKey) {
}
This code is true for alt+ctr and for altGr as well.
I have situation like this: for alt+ctrl+e (for example e, it's no matter) I want one thing and for altGr+e another, how can I do this?
If anyone have some idea, please tell me.
You can detect which key is pressed (from right key or left key) by value of location property in event object. If value of location property is 1 (e.location=1) then left key is pressed. if value is 2 then right key is pressed.
Here I have providing my code for RightAlter+RightCtrl+<any_valid_key>
Check this Example
var isRightAltKey=false;
var isRightCtrlKey=false;
var validKeys=['a','s','d','f','g']; //keep empty array if no need to check key
document.addEventListener("keydown", function(e) {
if(e.key=="Alt"){
// when right Alter pressed make isRightAltKey true
isRightAltKey= (e.location==2);
}
else if(e.key=="Control"){
// when right Control pressed make isRightCtrlKey true,
//if you need any ctrl key pressed then simply set isRightCtrlKey= true;
isRightCtrlKey= (e.location==2);
}
// checking both right key is pressed already or not?
var isRightKeys= isRightAltKey && isRightCtrlKey;
// validate other keys [optional]
var isValidKey=((typeof validKeys === "undefined") || validKeys.length==0 || validKeys.indexOf(e.key.toLowerCase())>=0);
if (isRightKeys && isValidKey){
document.getElementById("detect_key").innerHTML = "RightAlt + RightCtrl + "+e.key;
}
else
{
document.getElementById("detect_key").innerHTML="";
}
}, false);
document.addEventListener("keyup", function(e) {
if(e.key=="Alt"){
// when right Alter released make isRightAltKey false
isRightAltKey= false;
}
else if(e.key=="Control"){
// when right Control released make isRightCtrlKey false
isRightCtrlKey= false;
}
}, false);
<div id="detect_key"></div>
Why attached keyup event listner?
Here we have to detect key location when Ctrl and Alt key is pressed (on keydown event). and we have to store it in flag variable and make it true. when key is released (on keyup event) have to mark as false. Otherwise those flags always remain true. on Next key press it will always true
You can use the location to determined which alt is being pressed.
In order to support Alt+Ctrl we'll save the last location of the pressed Alt.
Location = 1 // Left
Location = 2 // Right
Then, once both Alt and Ctrl are pressed, do your thing. In this example, we'll just write the Alt side in the result div. You can add the "e" pressed condition as well:
if (e.ctrlKey && e.altKey && e.key == "e"){
Example
HTML
<div class="cont">
Click Alt + Ctrl<br /><br />
<div id="res"></div>
</div>
Javascript
var lastAltLocation;
document.addEventListener("keydown", function(e) {
if (e.key == "Alt"){
lastAltLocation = e.location;
}
if (e.ctrlKey && e.altKey){
if (lastAltLocation == 1){
document.getElementById("res").innerHTML = "Left";
}
if (lastAltLocation == 2){
document.getElementById("res").innerHTML = "Right";
}
}
}, false);
Sticking strictly to your question here are the codes for both the required cases:
document.addEventListener ("keydown", function (zEvent) {
if (zEvent.altKey && zEvent.code === "KeyE") {
if(zEvent.ctrlKey) {
//Do Ctrl+Alt+E Stuff Here.
} else {
//Do Alt+E Stuff Here.
}
});
Now breaking down the things going on here. keydown allows you to detect multiple keypresses.
First we check if the Alt and E keys are pressed. If yes, we then go on to check in the Ctrl key is also active and take the appropriate action as needed.

Disable spaces in Input, AND allow back arrow?

I am trying to disable spaces in the Username text field, however my code disables using the back arrow too. Any way to allow the back arrow also?
$(function() {
var txt = $("input#UserName");
var func = function() {
txt.val(txt.val().replace(/\s/g, ''));
}
txt.keyup(func).blur(func);
});
fiddle: http://jsfiddle.net/EJFbt/
You may add keydown handler and prevent default action for space key (i.e. 32):
$("input#UserName").on({
keydown: function(e) {
if (e.which === 32)
return false;
},
change: function() {
this.value = this.value.replace(/\s/g, "");
}
});
DEMO: http://jsfiddle.net/EJFbt/1/
This seems to work for me:
<input type="text" onkeypress="return event.charCode != 32">
It doesn't "disable" the back arrow — your code keeps replacing all the text outright, whenever you press a key, and every time that happens the caret position is lost.
Simply don't do that.
Use a better mechanism for banning spaces, such as returning false from an onkeydown handler when the key pressed is space:
$(function() {
$("input#Username").on("keydown", function (e) {
return e.which !== 32;
});​​​​​
});
This way, your textbox is prohibited from receiving the spaces in the first place and you don't need to replace any text. The caret will thus remain unaffected.
Update
#VisioN's adapted code will also add this space-banning support to copy-paste operations, whilst still avoiding text-replacement-on-keyup handlers that affect your textbox value whilst your caret is still active within it.
So here's the final code:
$(function() {
// "Ban" spaces in username field
$("input#Username").on({
// When a new character was typed in
keydown: function(e) {
// 32 - ASCII for Space;
// `return false` cancels the keypress
if (e.which === 32)
return false;
},
// When spaces managed to "sneak in" via copy/paste
change: function() {
// Regex-remove all spaces in the final value
this.value = this.value.replace(/\s/g, "");
}
// Notice: value replacement only in events
// that already involve the textbox losing
// losing focus, else caret position gets
// mangled.
});​​​​​
});
Try checking for the proper key code in your function:
$(function(){
var txt = $("input#UserName");
var func = function(e) {
if(e.keyCode === 32){
txt.val(txt.val().replace(/\s/g, ''));
}
}
txt.keyup(func).blur(func);
});
That way only the keyCode of 32 (a space) calls the replace function. This will allow the other keypress events to get through. Depending on comparability in IE, you may need to check whether e exists, use e.which, or perhaps use the global window.event object. There are many question on here that cover such topics though.
If you're unsure about a certain keyCode try this helpful site.
One liner:
onkeypress="return event.which != 32"

jQuery how to figure out if user inputed ' ' in text input area?

we have an input type="text" user prints into it some string. each time he inputs empty space char we want to call some function. How to do such thing with jQuery?
$(input).keydown(function (e) {
if ( e.which === 32 ) {
// do your thing
}
});
where input is a reference to your INPUT element.
Live demo: http://jsfiddle.net/uHpLg/
Check out jQuery's keypress event:
$("#YourInputId").keypress(function() {
var code = (e.keyCode ? e.keyCode : e.which);
if(code == 32) { // 32 = space keycode
//Do something
}
});
Here's a web page that has a list of javascript key codes.
Bind a listener to the input onchange event.
Compare the current value to the last value and check is the new character is a space
If so, call a function.
you can select the input text box and bind to it a change listener
but this will work only when the box is unfocused and the new value is different than the old value
$(document).ready(function () {
$('#mytextbox').change(function(){
if ($(this).val() == ' ')
{
// do whatever u want
}
});
});
but if u wanted something like autosuggestion (don't wait for user to unfocus the text input ) u can create ur own listener
is when the user focus the text box ,key press u check the pressed key and if it's is = " " do whatever u want
and when the user unfocus the input , it stops checking it
$('#mytextbox').keypress(function (e){
if (e.keycode == 32 )
{
// do your code here
}
});
for more info about keycodes : http://asquare.net/javascript/tests/KeyCode.html
on keypress Jquery function documentation : http://api.jquery.com/keypress/

Categories

Resources