I have simple function which checks if entered pin code is valid. But i don't know how to force for-loop to wait until i enter code again to check again it's validity.
So how it should be - i type PIN code, then click OK button and it checks whether it's correct (if it is, i can see my account menu; if it's not i have to type it again and i have 2 chances left). My code fails, because PIN when code is wrong program should wait until i type new code and press OK button again.
I tried setTimeout(), callback(), but it doesn't work. This is what i have - a function with for-loop that just runs 3 times (as it is suppose to, but not instantly) without giving a chance to correct the PIN code.
That's whole, unfinished yet, code: http://jsfiddle.net/j1yz0zuj/
Only function with for-loop, which checks validity of PIN code:
var submitKey = function(callback)
{
console.log("digit status" + digitStatus);
if (digitStatus == 0)
{
correctPIN = 1234;
var onScreen = document.getElementById("screen");
for (i=0; i<3; i++)
{
if (onScreen.innerHTML.slice(15, onScreen.innerHTML.length) == correctPIN)
{
setTimeout(accountMenu, 1250);
//break;
}
else
{
onScreen.innerHTML += "<br> Błędny kod PIN! Wpisz PIN ponownie. <br> Pozostało prób: " + (2-i);
callback();
//cardInserted = function(function(){console.log("Ponowne wpisanie PINu");});
}
if (i=2) console.log("blokada");
}
}
else if (digitStatus == 1)
{
}
}
Your approach is wrong. You should not make the user wait!!! You need 2 more variables at the top of your programm pincount=0 and pininputallowed. Increase pincount in the submit key function by 1 and then check if pincount<3.
Here is a corrected version of your code.
http://jsfiddle.net/kvsx0kkx/16/
var pinCount=0,
pinAllowed=true;
var submitKey = function()
{
console.log("digit status" + digitStatus);
if (digitStatus == 0)
{
correctPIN = 1234;
var onScreen = document.getElementById("screen");
pinCount++;
if(pinCount >= 3) {
pinAllowed = false;
onScreen.innerHTML = "<br>blokada";
}
if(pinAllowed){
if (onScreen.innerHTML.slice(15, onScreen.innerHTML.length) == correctPIN)
{
setTimeout(accountMenu, 1250);
//break;
}
else
{
onScreen.innerHTML += "<br> Błędny kod PIN! Wpisz PIN ponownie. <br> Pozostało prób: " + (3-pinCount);
inputLength = 0;
document.getElementById("screen").innerHTML += "<br>Wpisz kod PIN: ";
//callback();
//cardInserted = function(function(){console.log("Ponowne wpisanie PINu");});
}
}
}
else if (digitStatus == 1)
{
}
}
You need to create much more variables to control your machine. Your add/delete digit function had conditions that were badly written and only worked if the text on the screen was short enough.
var inputLength = 0;
addDigit = function(digit){
//numKeyValue = numKeyValue instanceof MouseEvent ? this.value : numKeyValue;{
if (inputLength < pinLength) {
onScreen.innerHTML += this.value;
inputLength++;
}
//if (onScreen.innerHTML == 1234) console.log("PIN został wprowadzony");
},
delDigit = function(){
if (inputLength >= 0) {
onScreen.innerHTML = onScreen.innerHTML.slice(0, -1);
inputLength--;
}
};
If you want to empty the screen at any moment you can insert onScreen.innerHTML = ''; anywhere
ps: Thanks for the exercise and nice automat you made there.
Related
I'm making a Node Express multiple choice test, and each question has different amount of correct answers. I have my answers coming from a database auto-populate in PUG. However my Function doesn't work right, when I click over the limit of correct answers, the alert pops up but then the answer is checked anyways. What am I doing wrong?
I tried making a function that tracks how many answers checked, but can't get it to stop after it reaches the limit.
block content
header.header USA Government Test
main.q-card
p.q-promt #{question}
small (Please choose #{mcLimit} answers)
hr
each answer in answers
label.container
| #{answer.Answer_prompt}
input(type='checkbox' name='answer' onclick="ckLimit()")
span.checkmark
hr
script.
function ckLimit() {
var limit = #{mcLimit};
var total = 0;
var inputTag = document.getElementsByTagName('input');
var x = inputTag.length;
for (var i = 0; i < x; i++) {
if (inputTag[i].checked) {
total += 1;
}
if (total > limit) {
alert(`Please select only ${limit}`);
this.checked = false;
return;
}
}
}
everything works accept the: this.checked = false;
It continues to check answers. This what my code looks like now:
header.header USA Government Test
main.q-card
p.q-promt #{question}
small (Please choose #{mcLimit} answers)
hr
each answer in answers
label.container
| #{answer.Answer_prompt}
input(type='checkbox' name='answer' onclick="return ckLimit()")
span.checkmark
hr
script.
function ckLimit() {
var limit = #{mcLimit};
var total = 0;
var inputTag = document.getElementsByTagName('input');
var x = inputTag.length;
for (var i = 0; i < x; i++) {
if (inputTag[i].checked) {
total += 1;
}
if (total > limit) {
alert(`Please select only ${limit}`);
this.checked = false;
return;
}
}
}
Add return keyword to the below statement.
input(type='checkbox' name='answer' onclick="ckLimit()")
thus becoming
input(type='checkbox' name='answer' onclick="return ckLimit()")
Without return, onclick proceeds on allowing the default action of checking. Once onclick gets false value, it stops the action.
Edit:
In function ckLimit, return should return false.
if (total > limit) {
alert(`Please select only ${limit}`);
this.checked = false;
return false;
}
My code is supposed to add 1 to the counter when I hit space and then change the magnifying glass to tilt the other direction. It just doesn't do anything when I hit space.
I've fixed every problem I saw, nothing worked. Maybe somebody else knows, I'm really not that good at js.
var hits = 0;
var hitElement = document.querySelector( '.hits' );
document.body.onkeydown = function(e) {
if( e.keyCode == 32 ) {
addHit();
}
}
var mag = "🔎";
var hitElement2 = document.querySelector( '.mag' );
document.body.onkeydown = function(f) {
if( f.keyCode == 32 ) {
if( mag.text == "🔎") {
mag = "🔍";
renderMag();
else
mag = "🔎";
renderMag();
}
}
}
var addHit = function() {
hits++;
renderHits();
}
var renderMag = function() {
hitElement2.innerHTML = mag;
}
var renderHits = function() {
hitElement.innerHTML = hits;
}
var resetHits = function() {
hits = 0;
renderHits();
}
Console says absolutely nothing too.
I fixed a few things and changed a few things that didn't need fixing. The three key points:
As mentioned, if a bit harshly, by Randy, your second event listener was overwriting your first, so hits was not increasing
The brackets in the if statement of your second event listener had some issues
Though checking the mag icon might work, using icons in the code feels like asking for something to break, so I changed that to a modulo check, to see whether hits was odd or even.
You were on the right track. When you have issues like this in the future, try putting console log statements in various places in the code. Make predictions about what variables should have what values at what points, then check if they do, then, if they don't, try to figure out why not.
var hits = 0;
var hitElement = document.querySelector('.hits');
var mag = "🔎";
var hitElement2 = document.querySelector('.mag');
document.body.onkeydown = function(f) {
if (f.key == ' ') {
addHit();
if (hits % 2 === 0) {
mag = "🔍";
renderMag();
} else {
mag = "🔎";
renderMag();
}
}
}
function addHit() {
hits++;
renderHits();
}
function renderMag() {
hitElement2.innerHTML = mag;
}
function renderHits() {
hitElement.innerHTML = hits;
}
function resetHits() {
hits = 0;
renderHits();
}
<div class="hits"></div>
<div class="mag"></div>
var checkErrors = 0;
// Check for mistakes function
function yourResult() {
let checkErrors = 0;
let textEnterd = testArea.value;
let orginTextMatch = originText.substring(0, textEnterd.length);
if (textEnterd.length == originText.length || textEnterd == originText) {
if (textEnterd != orginTextMatch) {
++checkErrors;
}
theResult.innerHTML **strong text** = "You did " + checkErrors + " mistakes.";
}
}
testArea.addEventListener('keyup', function() {
yourResult();
}, false);
// "return"
This is a test typing project, i am stuck at the yourResult function, i cant get the desire errors.
The main mistake is that the error count is reset after each stroke.
So put that outside and you can match the characters as they're typed.
It's not far off, so you can try this instead:
// Put check errors variable outside of the function to keep count between the key strokes
// Reset to 0 when starting the test over
let checkErrors = 0;
function yourResult(){
let textEnterd = testArea.value;
let charPos = textEnterd.length;
// Match the characters at their positions. If they don't match, add them up
if (charPos > 0 && textEnterd.charAt(charPos) != originText.charAt(charPos)) {
++checkErrors;
}
theResult.innerHTML = "You did " + checkErrors + " mistakes.";
}
I suppose my question is a bit similar to this one, but I can't really work out how to do my specific need from it. I'm building a very basic text adventure, and I'd like the returned text - after the user has entered a command - to be returned in a typewriter style. Here's a snippet of my commands so far (there'll be a lot more, I don't mind that this will be built in a bit of a tedious way)
<script>
textIn = document.getElementById("input-textbox");
textOut = document.getElementById("output-textbox");
function process(input) {
if (input == "hi") { textOut.innerHTML += "Hello to you too!<br><br>"; }
else if (input == "exit") { textOut.innerHTML += "No."; }
}
function go() {
var input = textIn.value;
textIn.value = "";
var output = process(input);
textOut.value += output + "\n";
}
</script>
and the HTML
<div id="output-textbox">
Returned text goes here.
</div>
<form onSubmit="go();return false;">
<input id="input-textbox" name="command" value="" autofocus="autofocus"/>
</form>
Thank you so much for your help in advance! This solution doesn't need to be beautiful, code wise, nor very nifty. It just has to work, I have no standards at all with this!
Based on William B's answer, here is a more condensed version:
https://jsfiddle.net/sators/4wra3y1p/1/
HTML
<div id="output-typewriter"></div>
Javascript
function typewriterText(text) {
var outEl = document.querySelector('#output-typewriter');
var interval = 50; // ms between characters appearing
outEl.innerHTML = '';
text.split('').forEach(function(char, i){
setTimeout(function () {
outEl.innerHTML += char;
}, i * interval);
});
}
typewriterText('this is an example');
Create a timeout for each character inside a loop, with each timeout being a bit later than the last. See: https://jsfiddle.net/fswam77j/1/
var outputEl = document.querySelector('#output-textbox');
var charInterval = 50; // ms between characters appearing
function showOutput(text) {
outputEl.innerHTML = '';
for(var i = 0; i < text.length; i++) {
showChar(text, i);
}
}
function showChar(text, i) {
setTimeout(function () {
outputEl.innerHTML += text[i];
}, i * charInterval);
}
showOutput('this is an example');
process the input:
function process(input) {
if (input == "hi") {
showOutput("Hello to you too!");
}
else if (input == "exit") {
showOutput("No.");
}
}
Alright I need help combining the two JavaScript Functions... I have tried multiple times and am not coming up with any luck. There almost identical functions except the fact that I change one number so that it thinks there different textboxes. I tried putting a variable in its place but then it always only validates to the ending number of the loop. Please show me how I may be able to combine these two functions. (Its my only work around and I can not find any examples similar to mine)
First:
<script type="text/javascript">
var QnoText = ['abc_1']; // add IDs here for questions with optional text input
function doSubmit_1() {
var ids_1 = '';
flag_1 = true;
for (i=0; i<QnoText.length; i++) {
CkStatus = document.getElementById(QnoText[i]).checked;
ids_1 = QnoText[i]+'Certificate_1';
if (CkStatus && document.getElementById(ids_1).value == '') {
alert('Please enter certificate number 1.');
document.getElementById(ids_1).focus();
flag_1 = false;
alert('return flag_1');
}
}
return flag_1;
}
</script>
Second:
<script type="text/javascript">
var QnoText = ['abc_2']; // add IDs here for questions with optional text input
function doSubmit_2() {
var ids_2 = '';
flag_2 = true;
for (i=0; i<QnoText.length; i++) {
CkStatus = document.getElementById(QnoText[i]).checked;
ids_2 = QnoText[i]+'Certificate_2';
if (CkStatus && document.getElementById(ids_2).value == '') {
alert('Please enter certificate number 2.');
document.getElementById(ids_2).focus();
flag_2 = false;
alert('return flag_2');
}
}
return flag_2;
}
</script>
You can pass a parameter in your function with the number of the textbox, like this:
var QnoText = ['abc_2']; // add IDs here for questions with optional text input
function doSubmit(n) {
var ids = '';
flag = true;
for (i=0; i<QnoText.length; i++) {
CkStatus = document.getElementById(QnoText[i]).checked;
ids = QnoText[i]+'Certificate_' + n;
if (CkStatus && document.getElementById(ids).value == '') {
alert('Please enter certificate number ' + n + '.');
document.getElementById(ids).focus();
flag = false;
alert('return flag_' + n);
}
}
return flag;
}
doSubmit(1); // for your submit 1
doSubmit(2); // for your submit 2
Is this what you wanted? because is not very clear. If is not feel free to explain.