I'm working on a project for school and I'm writing a calculator.
I got to the point where I'm programming the keydown event, the numbers aren't causing any problems, but I got stuck at the %, * and +.
The output I receive in the console.log is correct - I'm getting the asterisk * each time I press shift + 8, not when I press shift or 8 individually. But what I'm getting in the #output.innerHTML is " *8 ", since I also have an event listener for number 8, as seen above.
function forDisplay(value) {
document.getElementById("output").innerHTML += value;
}
document.addEventListener('keydown', (event)=>{
if(event.keyCode === 56 || event.keyCode === 104){
document.getElementById("output").innerHTML += 8
}
if(event.shiftKey && event.keyCode === 56){
console.log('*')
forDisplay('*')
}
})
Is there any way I can make the code work in the output too, since it's working correctly in the console.log?
Thanks!
I see your problem - the first if is firing, and so is the second if when you press Shift and 8. Simply check for the Shift and 8 first, then add an else if statement, in case the condition is not true.
document.addEventListener('keydown', (event) => {
if (event.shiftKey && event.keyCode === 56) {
console.log('*')
document.getElementById("output").innerHTML += "*";
} else if (event.keyCode === 56 || event.keyCode === 104) {
document.getElementById("output").innerHTML += 8
}
})
<div id="output"></div>
Also, here's my attempt at a calculator, complete with regular numbers, addition, subtraction, multiplication, division, exponent, Num Pad, designated symbols for multiplication and division, prevention for operands next to each other (things like 132+*837), backspace, clearing options, and evaluation for Enter key, equal to, or Evaluate button:
var outputEl = document.getElementById("output")
function CheckLastChar() {
if (["×", "+", "-", "÷", "^"].includes(outputEl.innerText.slice(-1))) {
outputEl.innerText = outputEl.innerText.slice(0, -1)
}
}
document.addEventListener('keydown', (event) => {
key = String.fromCharCode(event.keyCode);
if (event.shiftKey) {
if (key == "8") {
CheckLastChar();
outputEl.innerText += "×";
} else if (key == "6") {
CheckLastChar();
outputEl.innerText += "^";
} else if (event.keyCode == 187) {
CheckLastChar();
outputEl.innerText += "+";
}
} else {
if ([...Array(10).keys()].map(el => el.toString()).includes(key)) {
outputEl.innerText += key;
} else if (event.keyCode == 106) {
CheckLastChar();
outputEl.innerText += "×";
} else if (event.keyCode == 107) {
CheckLastChar();
outputEl.innerText += "+";
} else if (event.keyCode == 189 || event.keyCode == 109) {
CheckLastChar();
outputEl.innerText += "-";
} else if (event.keyCode == 191 || event.keyCode == 111) {
CheckLastChar();
outputEl.innerText += "÷";
} else if (event.keyCode == 8) {
outputEl.innerText = outputEl.innerText.slice(0, -1);
} else if (event.keyCode == 13) {
document.querySelectorAll("button")[0].click();
} else if (event.keyCode == 187) {
document.querySelectorAll("button")[0].click();
}
}
})
document.querySelectorAll("button")[0].addEventListener("click", () => {
stringToEvaluate = document.getElementById("output").innerText.replace("×", "*").replace("÷", "/").replace("^", "**");
console.clear();
try {
console.log(eval(stringToEvaluate));
} catch {
console.log("Unexpected error or invalid expression.");
}
})
document.querySelectorAll("button")[1].addEventListener("click", () => {
outputEl.innerText = "";
})
<div id="output"></div>
<button>Evaluate!</button>
<button>Clear!</button>
Related
I have a requirement where I have to prevent user from typing in shift+greater than in textbox.
I looked up in the ascii key code chart.I could see no ascii key for shift+greater than combination which renders ">" on the UI.
This is the code that i have tried so far.
$scope.isValidControlInputInteger = function (event) {
var keyCode = event.keyCode;
if (keyCode >= 48 && keyCode <= 57 && event.shiftKey) { // decimal numbers
return true;
} else if (keyCode >= 96 && keyCode <= 105) { // numerical pad
return true;
} else if (keyCode == 46 || keyCode == 8) { // delete and backspace
return true;
} else if (keyCode == 37 || keyCode == 39) { // arrow keys
return true;
}
else if (keyCode == 9) { // tab key
return true;
}
else {
return false;
}
};
A simple workaround that works better than checking for keyup is to just remove all instances of > upon changing the contents of the input field.
$("#field").on("keyup", function(e) {
$(this).val($(this).val().replace(/\>/g, ""))
});
Here's a fiddle.
i have used this code but it only detects if the capslock is on or off.
$(function () {
var isShiftPressed = false;
var isCapsOn = null;
$("#txtName").bind("keydown", function (e) {
var keyCode = e.keyCode ? e.keyCode : e.which;
if (keyCode == 16) {
isShiftPressed = true;
}
});
$("#txtName").bind("keyup", function (e) {
var keyCode = e.keyCode ? e.keyCode : e.which;
if (keyCode == 16) {
isShiftPressed = false;
}
if (keyCode == 20) {
if (isCapsOn == true) {
isCapsOn = false;
$("#error").hide();
} else if (isCapsOn == false) {
isCapsOn = true;
$("#error").show();
}
}
});
$("#txtName").bind("keypress", function (e) {
var keyCode = e.keyCode ? e.keyCode : e.which;
if (keyCode >= 65 && keyCode <= 90 && !isShiftPressed) {
isCapsOn = true;
$("#error").show();
} else {
$("#error").hide();
}
});
});
but this is not functioning if the textarea that hold the value is in readOnly state.
how can i fix it?
replace
$("#txtName")
with
$('body')
You could use onkeypress instead of onkeydown. The latter only detects which key was pressed; the former (even though counter-intuitively its name includes 'keypress') will give you the char. This link explains in detail: http://unixpapa.com/js/key.html Note that onkeypress is not supported by all browsers.
Also, your code for converting charcode to char is inefficient, and you're converting uppercase charcodes to lowercase chars. Here's some code that listens for key presses and on each one, alerts the user which char was pressed.
document.onkeypress = function(event){
event = event || window.event;
var key = event.keyCode;
alert(String.fromCharCode(key));
}
if (event.keyCode == "65"){
document.getElementById("txtInput").value+=val1;
btnA.style.backgroundColor="#00bfff";
}
if (event.keyCode == "66"){
document.getElementById("txtInput").value+="b";
btnB.style.backgroundColor="#00bfff";
}
if (event.keyCode == "67"){
document.getElementById("txtInput").value+="c";
btnC.style.backgroundColor="#00bfff";
}
if (event.keyCode == "68"){
document.getElementById("txtInput").value+="d";
btnD.style.backgroundColor="#00bfff";
}
if (event.keyCode == "69"){
document.getElementById("txtInput").value+="e";
btnE.style.backgroundColor="#00bfff";
}
if (event.keyCode == "70"){
document.getElementById("txtInput").value+="f";
btnF.style.backgroundColor="#00bfff";
}
if (event.keyCode == "71"){
document.getElementById("txtInput").value+="g";
btnG.style.backgroundColor="#00bfff";
}
if (event.keyCode == "72"){
document.getElementById("txtInput").value+="h";
btnH.style.backgroundColor="#00bfff";
}
if (event.keyCode == "73"){
document.getElementById("txtInput").value+="i";
btnI.style.backgroundColor="#00bfff";
}
if (event.keyCode == "74"){
document.getElementById("txtInput").value+="j";
btnJ.style.backgroundColor="#00bfff";
}
if (event.keyCode == "75"){
document.getElementById("txtInput").value+="k";
btnK.style.backgroundColor="#00bfff";
}
if (event.keyCode == "76"){
document.getElementById("txtInput").value+="l";
btnL.style.backgroundColor="#00bfff";
}
if (event.keyCode == "77"){
document.getElementById("txtInput").value+="m";
btnM.style.backgroundColor="#00bfff";
}
if (event.keyCode == "78"){
document.getElementById("txtInput").value+="n";
btnN.style.backgroundColor="#00bfff";
}
if (event.keyCode == "79"){
document.getElementById("txtInput").value+="o";
btnO.style.backgroundColor="#00bfff";
}
if (event.keyCode == "80"){
document.getElementById("txtInput").value+="p";
btnP.style.backgroundColor="#00bfff";
}
if (event.keyCode == "81"){
document.getElementById("txtInput").value+="q";
btnQ.style.backgroundColor="#00bfff";
}
if (event.keyCode == "82"){
document.getElementById("txtInput").value+="r";
btnR.style.backgroundColor="#00bfff";
}
if (event.keyCode == "83"){
document.getElementById("txtInput").value+="s";
btnS.style.backgroundColor="#00bfff";
}
if (event.keyCode == "84"){
document.getElementById("txtInput").value+="t";
btnT.style.backgroundColor="#00bfff";
}
if (event.keyCode == "85"){
document.getElementById("txtInput").value+="u";
btnU.style.backgroundColor="#00bfff";
}
if (event.keyCode == "86"){
document.getElementById("txtInput").value+="v";
btnV.style.backgroundColor="#00bfff";
}
if (event.keyCode == "87"){
document.getElementById("txtInput").value+="w";
btnW.style.backgroundColor="#00bfff";
}
if (event.keyCode == "88"){
document.getElementById("txtInput").value+="x";
btnX.style.backgroundColor="#00bfff";
}
if (event.keyCode == "89"){
document.getElementById("txtInput").value+="y";
btnY.style.backgroundColor="#00bfff";
}
if (event.keyCode == "90"){
document.getElementById("txtInput").value+="z";
btnZ.style.backgroundColor="#00bfff";
}
thats the code i used so when i press a-z in the keyboard it will have a-z in the textarea. But even if the capslock is ON its still on lowercase.
I have a problem. Basically, what happens in my case is that the numbers in my textbox are autoformatted as I type. I don't want this to happen. What I want is that the numbers should be autoformatted only when the user clicks outside the textbox.
In my input tag I have :
onkeyup="format(event, this);"
My javascript function is :
function format(e, obj) {
if (e.keyCode == 36) {
press1(obj);
}
if (e.keyCode == 13) {
return false;
}
if ((e.keyCode <= 34) || (e.keyCode >= 46 && e.keyCode < 58) || (e.keyCode >= 96 && e.keyCode <= 105)) { // //alert(e.keyCode);
obj.value = CommaFormatted(obj.value);
} else {
if (e && e.stopPropagation) {
e.stopPropagation();
e.preventDefault();
} else {
e.cancelBubble = true;
e.returnValue = false;
}
return false;
}
}
where the press1 function is:
function press1(textControlID) {
var text = textControlID;
if (text.getAttribute("maxlength") == text.value.length) {
var FieldRange = text.createTextRange();
FieldRange.moveStart('character', text.value.length);
FieldRange.collapse();
FieldRange.select();
return true;
}
if (text != null && text.value.length > 0) {
if (text.createTextRange) {
var FieldRange = text.createTextRange();
FieldRange.moveStart('character', text.value.length);
FieldRange.collapse();
FieldRange.select();
} else if (text.setSelectionRange) {
var textLength = text.value.length;
text.setSelectionRange(textLength, textLength);
}
}
}
I really hope this could be solved. Please!
You could change onkeyup to onblur, which is the event that gets fired when the control loses focus - clicking out of it.
The onkeyup event fires with every keypress.
While working with the multiple keypress events i found this code which worke fine
$(document).bind('keypress', function(event) {
if( event.which === 65 && event.shiftKey ) {
alert('you pressed SHIFT+A');
}
});
But to make it to work wth combinig with windows key... like
event.which === 65 && event.windowsKey
it failed...
Is there any option to make it work with windows key?
if it is a mac machine there is no key as windows..so what could be the alternate option for windows key in mac
Use keyup event.
On a Mac left Command is which = 91, right Command is which = 93. I can't tell what are those on Windows, but you can test it yourself. As #ian commented they should be 91 and 92 respectively.
To test
$(document).on('keyup', function(e) {
var modKey = "";
if (e.shiftKey) modKey += "shiftKey,";
if (e.ctrlKey) modKey += "ctrlKey,";
if (e.altKey) modKey += "altKey,";
if (e.metaKey) modKey += "metaKey,";
console.log ("which: " + e.which + " modkey: " + modKey );
});
UPDATE: Try use keydown event and event.metaKey
$(document).on('keydown', function(e) {
if(e.which === 65 && event.metaKey ) {
console.log ("You pressed Windows + A");
}
});
Remember the key you pressed before. Like if you press shift. get a boolean or something to shiftPressed = true on a onKeyRelease make it false again. That way you can check if shiftPressed == true && aPressed == true before doing something
I made something a while ago for a little WASD game. Perhaps it makes more sense if you see the code:
var up = false;
var down = false;
var left = false;
var right = false;
function keyUp(e) {
keyCode = (e.keyCode ? e.keyCode : e.which);
if (keyCode == 37 || keyCode == 65) {
left = false;
}
if (keyCode == 38 || keyCode == 87) {
up = false;
}
if (keyCode == 39 || keyCode == 68) {
right = false;
}
if (keyCode == 40 || keyCode == 83) {
down = false;
}
}
function forceStopMoving() {
left = false;
up = false;
right = false;
down = false;
}
function keyDown(e) {
keyCode = (e.keyCode ? e.keyCode : e.which);
if (keyCode == 37 || keyCode == 65) {
left = true;
}
if (keyCode == 38 || keyCode == 87) {
up = true;
}
if (keyCode == 39 || keyCode == 68) {
right = true;
}
if (keyCode == 40 || keyCode == 83) {
down = true;
}
}
I'm building a terminal emulation and running into an issue with capturing backspace in Firefox. I'm able to nab the first backspace and remove the last character on the input at the prompt, but it won't persist and remove more than one character.
Actual website: http://term.qt.io/
Replication here: http://jsfiddle.net/BgtsE/1/
JavaScript code
function handleKeys(e){
var evt = e || window.event;
var key = evt.charCode || evt.keyCode;
if(evt.type == "keydown")
{
curr_key = key;
if(key == 8)
{
evt.preventDefault();
if(0 < $('body').text().length)
$('body').text($('body').text().slice(0,-1));
}
}
else if(evt.type == "keypress")
{
if(97 <= key && key <= 122)
{
if(curr_key != key)
$('body').append(String.fromCharCode(key));
}
else
$('body').append(String.fromCharCode(key));
}
}
$(function(){
$('html').live({
keydown:function(e){
handleKeys(e);
},
keypress:function(e){
handleKeys(e);
}
})
})
Try this: http://jsfiddle.net/NBZG8/1/
You'll need to handle backspace in both keydown and keypress to support Chrome and Firefox
function handleKeys(e){
var evt = e || window.event;
var key = evt.charCode || evt.keyCode;
if (evt.type == "keydown") {
curr_key = key;
if(key == 8 && !$.browser.mozilla) {
backspaceHandler(evt);
}
} else if (evt.type == "keypress") {
if (key == 8) {
backspaceHandler(evt);
} else if (97 <= key && key <= 122) {
if(curr_key != key) {
$('body').append(String.fromCharCode(key));
}
} else {
$('body').append(String.fromCharCode(key));
}
}
}
function backspaceHandler(evt) {
evt.preventDefault();
if(0 < $('body').text().length) {
$('body').text($('body').text().slice(0,-1));
}
};
$(function(){
$('html').live({
keydown : handleKeys,
keypress : handleKeys
})
})
In firefox Windows 17.0.1 any value returned by $("selector").text() has an added new line character appended to the end. So the substring didn't work for me:
<html>
<head>
<title>test</title>
<script src="jquery.js"></script>
<script>
$("document").ready(function(){
console.log("body text seems to have a new line character");
console.log(($('body').text()[5]=="\n"));
});
function handleKeys(e){
var evt = e || window.event;
var key = evt.charCode || evt.keyCode;
if(evt.type == "keydown")
{
curr_key = key;
if(key == 8)
{
evt.preventDefault();
if(0 < $('body').text().length)
// next line works, you might trim the \n if it's there at the end
//$('body').text($('body').text().slice(0,-2));
// this one didn't work for me
$('body').text($('body').text().substring(0,$('body').text().length-1));
}
}
else if(evt.type == "keypress")
{
if(97 <= key && key <= 122)
{
if(curr_key != key)
$('body').append(String.fromCharCode(key));
}
else
$('body').append(String.fromCharCode(key));
}
}
$(function(){
$('html').live({
keydown:function(e){
handleKeys(e);
},
keypress:function(e){
handleKeys(e);
}
})
})
</script>
</head>
<body>12345</body>
</html>
I had the same issue with keypress on mozilla.
Thanks to this subject it solves my problem so I'll post my code if anyone try to do the same thing as me.
In my exemple I try to auto space when the user type two numbers, and it didn't work in Firefox so that's my code :
$(function() {
$('#field1, #field2').on('keypress',function(event) {
event = event || window.event;
var charCode = event.keyCode || event.which,
lgstring = $(this).val().length,
trimstring;
if(charCode === 8) {
event.returnValue = false;
if(event.preventDefault)
event.preventDefault();
if(0 < $(this).val().length) {
$(this).val($(this).val().slice(0,-1));
}
}
else if(((charCode > 31) && (charCode < 48 || charCode > 57)) || lgstring >= 14) {
event.returnValue = false;
if(event.preventDefault)
event.preventDefault();
}
else {
trimstring = $(this).val().replace(/ /g,"");
if((lgstring !== 0) && (trimstring.length % 2) === 0 ) {
$(this).val($(this).val() + ' ');
}
}
});
});
I noticed that Mozilla handle the backspace as a keypress where Chrome don't.
Sorry for my English I'm French
$('#id').keypress(function(e) {
if(e.charCode > 0 || e.keyCode === 8){
if(e.keyCode === 8){
return true;
}else if((e.charCode !== 0) && ((e.charCode > 57 && e.charCode < 65)){
return false;
}
}else if((e.keyCode !== 0) && ((e.keyCode > 57 && e.keyCode < 65)){
return false;
}
});