I'm trying to work through an assignment to further my understanding of js but I'm running into some issues that are keeping me from final code. The code executes a short quiz- inputs from radio buttons are taken in and matched to an object containing answers, then outputting a final score.
code at http://jsfiddle.net/8ax9A/3/
issues I'm aware of now :
my $response variable doesn't seem to work.
var $response = $('[name=rad]:checked').val();
counter is listening for clicks through questions. After the last question, I want to report final score. I can't get counter to reach the end of questions + 1, and I cant get an accurate final score listener reported (var finalScore).
if ($response == parseInt(questions[counter].answer, 10)) {
finalScore++;
}
Those are just snippets so check out the fiddle for full code. I'd love some suggestions on how to understand where I'm going wrong.
Here is one way you could do it:
//Initialization
var counter=0;
var score=0;
loadQuestion();
$('#next').on('click',answer);
//functions
function answer(){
// if the user did not answer
if ($('input:radio:checked').length == 0){
alert('You have to answer!');
return;
}
var currentQ=questions[counter];
// if answer is correct
if($('[name=rad]:checked').val()==currentQ.answer){score++;}
counter++;
// if there are no questions left
if(counter >= questions.length) {displayResults(); return;}
loadQuestion();
}
function loadQuestion(){
// clear the radio buttons
$("input:checked").removeAttr("checked");
var currentQ=questions[counter];
// display the question
$('h1').text(currentQ.question);
$('#a1').text(currentQ.choices[0]);
$('#a2').text(currentQ.choices[1]);
$('#a3').text(currentQ.choices[2]);
}
function displayResults(){
$("h1").text("You've finished with a score of " + score + "!");
$('[name=rad], #a1, #a2, #a3, #next').remove();
}
JS Fiddle
Related
I will like to achieve something in a quiz system.
Right about now I have a quiz system that works perfectly well. It closes the quiz after 10:00 min is elapsed.
But what I want now is, for each of the question there should be a timer.
So Question 1 would have 10 secs, Question 2 would also have 10 secs down to Question 20.
So when you fail to answer any question within ten seconds, it automatically takes you to the next question.
Right about now, what happens is that you must click on the next question button before it takes you to the next question, which is what I want to change.
Below is the code that does the timer and submit after 10 min
<script>
//function that keeps the counter going
function timer(secs){
var ele = document.getElementById("countdown");
ele.innerHTML = "Your Time Starts Now";
var mins_rem = parseInt(secs/60);
var secs_rem = secs%60;
if(mins_rem<10 && secs_rem>=10)
ele.innerHTML = " "+"0"+mins_rem+":"+secs_rem;
else if(secs_rem<10 && mins_rem>=10)
ele.innerHTML = " "+mins_rem+":0"+secs_rem;
else if(secs_rem<10 && mins_rem<10)
ele.innerHTML = " "+"0"+mins_rem+":0"+secs_rem;
else
ele.innerHTML = " "+mins_rem+":"+secs_rem;
if(mins_rem=="00" && secs_rem < 1){
quiz_submit();
}
secs--;
//to animate the timer otherwise it'd just stay at the number entered
//calling timer() again after 1 sec
var time_again = setTimeout('timer('+secs+')',1000);
}
</script>
<script>
setTimeout(function() {
$("form").submit();
}, 600000);
</script>
Here is the code that does the onclick to next question
<script type="text/javascript">
$('.cont').addClass('hide');
count=$('.questions').length;
$('#question'+1).removeClass('hide');
$(document).on('click','.next',function(){
last= parseInt($(this).attr('id'));
nex = last+1;
$('#question'+last).addClass('hide');
$('#question'+nex).removeClass('hide');
});
$(document).on('click','.previous',function(){
last = parseInt($(this).attr('id'));
pre = last-1;
$('#question'+last).addClass('hide');
$('#question'+pre).removeClass('hide');
});
setTimeout(function() {
$("form").submit();
}, 120000);
</script>
Please note that I fetch my questions with Php Mysqli
Initialize a timeout into a variable at start. The callback should simulate a click on the next button. Use .click() to simulate. It will execute all click event listeners associated to the button.
You also have to reset the timer when button is clicked (manually or not).
EDIT: After discussing by comments, I guess that you have <button.next> tags for each question in your HTML, with a numeric ID. So I propose you to stock in a variable your current progression.
// Initializes
let currentQuestion = 1;
let question_timer = setTimeout(question_timeout_callback, 10000);
// Function which simulates the click.
function question_timeout_callback() {
// Simulates
$(document).find(`#${currentQuestion}`).click();
}
// your code...
// And in your click event listener:
$(document).on('click','.next', function () {
// Resets timer
clearTimeout(question_timer);
question_timer = setTimeout(question_timeout_callback, 10000);
// Update question tracking
currentQuestion++;
// your code...
});
// Do NOT forget to update .previous buttons with "currentQuestion--"
Now, do not forget to ask yourself how you will handle the possibility to come back to the previous question.
i would suggest different approach.
first, take the time-counting to the backend of your application (so user can't tamper with it).
when user begins quiz, save start time and user identifier into db.
implement timeout (2s interval?) to ask backend, how much time is left.
create simple script which loads remaining time from db (calculates how much time remains for current question) and returns it to the frontend.
php:
<?php
$user = (int) $_GET['user'];
$questionNumber = (int) $_GET['question'];
//connect to the db
//select eg. with PDO
$st = $db->prepare('SELECT start_time FROM quiz_completion WHERE user_id = :user');
$st->bindParam(':user', $user, PDO::PARAM_INT);
$startTimeRow = $sth->execute();
//calculate remaining time
$elapsed = time() - $startTimeRow['start_time'];
$borderTime = 10 * $questionNumber;
echo $borderTime - $elapsed;
exit(0);
with mocked GET & db: https://3v4l.org/MId0K
then in js just call this script with user identifier and question number. when less than zero is returned, move user to the next question.
js:
$.ajax('http://localhost/your_php_script.php?user='+user+'&question='+questionNumber).done(
function(response){
if (response < 0) {
//move to the next q.
} else {
//show remaining time?
}
});
with asking backend to get time, there is risk of waiting too long for an answer from php (when many users are completing the poll)
I am trying to get a current score to add up every time an answer is correct, what is happening is that I have the questions in a pagination set up and when this answer is correct it give me the score but then when it goes to the next page it refresh the score and if I got that one right it just give me the score for that one again but it doesn't add up.
JS code:
$(function() {
$('#author').on('change', function(event) {
var opt = this.options[ this.selectedIndex ];
var correct = $(opt).text().match (arr2);
var score = 0;
if (correct){
alert('Good job ' + arr2,);
score += 2;
alert (score);
currentScore = score++;
alert(currentScore);
display(currentScore);
}
else {
alert ('nice try ' + arr2);
}
});
});
Here is another option - local storage.
Here is a reference W3School Web storage
It's not the most ideal solution, but it can meet your criteria.
let score = localStorage.getItem('score')
score++;
localStorage.setItem('score', score);
Your pages will be able to access the localStorage so you can get the value of score and re-set it.
Hopefully the reference can answer further questions, else leave a comment!
Con: It may not be supported by all browsers.
EDIT:
Here is an example with your code.
$(function() {
let currentScore = localStorage.getItem('score'); // get score
if (currentScore === null){ // if score doesnt exist yet
localStorage.setItem('score', 0); // set score
currentScore = 0; // make currentScore 0
}
$('#author').on('change', function(event) {
var opt = this.options[ this.selectedIndex ];
var correct = $(opt).text().match (arr2);
if (correct){
alert('Good job ' + arr2);
currentScore += 2; //increment current score by 2
alert (currentScore);
localStorage.setItem('score', currentScore); // set the item again with new value
alert(currentScore);
display(currentScore);
}
else {
alert ('nice try ' + arr2);
}
});
});
Edit 2:
let currentScore = localStorage.getItem('score'); // get score
currentScore = parseInt(currentScore);
it give me the score but then when it goes to the next page it refresh the score and if I got that one right it just give me the score for that one again but it doesn't add up.
I think your problem is there.
If I understand correctly, when the answer is good, the page refresh and passes to the next question. Your problem is that the score doesn't add up to the previous one.
The score variable is only stored in the current page, like a temporary one. Without saving the score on the server, via ajax or another method, and getting it on the next page, it will not add up. Indeed, score will have a value of 0 due to the refresh.
A simple schema :
score = 0 -> correct answer -> +50 point -> score = 50 -> next page -> score = 0
As you can see, because the javascript you wrote is not assuring the persistance of your information, the previously stored score is lost.
You need to send the score on the server and then get it back when the new page is loaded or to avoid changing page and make your quizz on one and only page, without refreshing.
Keep in mind that everytime you are refresing a page, the javascript is starting again and therefore everything done before is lost.
I hope this was helpful.
Ps: You should place your code in the $( document ).ready(); block just like this :
$( document ).ready(function() {
console.log( "ready!" );
});
It will make your code start when the html DOM (the structure of the html file) is loaded and ready to be manipulated. It can avoid a lot of errors.
Edit2 : What it will look like in your code :
$( document ).ready(function() {
$('#author').on('change', function(event) {
var opt = this.options[ this.selectedIndex ];
var correct = $(opt).text().match (arr2);
var score = 0;
if (correct){
alert('Good job ' + arr2,);
score += 2;
alert (score);
currentScore = score++;
alert(currentScore);
display(currentScore);
}
else {
alert ('nice try ' + arr2);
}
});
});
Or, to make this more readable and to avoird having a lot of things in the document.ready block (when you will have a lot of lines/functions) :
$( document ).ready( myNiceFunction() );
var myNiceFunction = function(){
$('#author').on('change', function(event) {
var opt = this.options[ this.selectedIndex ];
var correct = $(opt).text().match (arr2);
var score = 0;
if (correct){
alert('Good job ' + arr2,);
score += 2;
alert (score);
currentScore = score++;
alert(currentScore);
display(currentScore);
}
else {
alert ('nice try ' + arr2);
}
}
Ps2 : I know this is not the best website to explain it but I think it is simple enough to make you understand the principle of ajax without losing you into a bunch of technical stuff : here and here
Edit : Grammar and second post-scriptum.
Not sure how you're doing pagination but it should be ajaxed, instead of a full postback, so you don't lose the values on your page.
How to get winner detection?
My code isn't working right now i only need the winner detection if someone can help me then do this .
$(document).ready(function() {
var xoro = 1;
$('#reset').on("click", function() {
$('img').attr("src", "blank.png");
});
$('img').on("click", function() {
var tmp = $(this).attr("src");
if (tmp == "blank.png" && xoro == 1) {
$(this).attr("src", "x.png");
xoro = 0;
} else if (tmp == "blank.png" && xoro == 0) {
$(this).attr("src", "o.png");
xoro = 1;
}
});
});
With your code you cant really determine a winner.
Options you have are :
Give your images ids . like
Let say we have this 3x3 field and we say its a 2dimensional array. Then the top left field is [0][0] and your bottom right is [3][3]
Your HTML code should be somethig like this
<img src="x.png" id="0-0"></img><img src="blank.png" id="0-1"></img>...
And so on.
After youve eine that you have to Start writing a huge if statement with all the winning Casey where you check if the SRC are all "x.PNG" or so.
EG: if ID 0-0,0-1 and 0-2 all have the SRC x.PNG x wins .
Best is to put these into a function named checkForWinner() and then just call this Funktion after every click or so
I hope i could help you out.
This question has already been answered here (in Java language though but the idea is the same). For that I suggest you store every move in a matrix which you can the use to determine the winner.
In addition, you have to make the images identifiable (as zeropublix suggested) so that you can actually capture the user's input and fill the matrix.
I am a beginner with all coding. Here is my general goal. I am running something relatively simple where I have 8 superheroes on the screen. I would like the user to eliminate the 4 DC superheroes from the screen and after all 4 of them are eliminated from the screen I want the system to alert the user that they have won the game. They don't have to do it in any order so I ran the superHero function each time a DC character was clicked to check if all four DC superheroes had been eliminated yet. Somebody please help me. I feel like it is something very simple I am messing up on. Thanks a ton in advance.
/*This is my jquery that shows all 8 of my superheroes*/
$('#heroes').show();
var flashHidden = !$('#greenlantern').is(':visible');
var greenHidden = !$('#greenlantern').is(':visible');
var batmanHidden = !$('#batman').is(':visible');
var supermanHidden = !$('#superman').is(':visible');
function superHero() {
if(flashHidden && batmanHidden && supermanHidden && greenHidden) {
alert ("Congratulations!!! You have won the game!! Please proceed forward and fill out a quick survey for the developers");
}
}
$('#flash').click(function(){
$('#flash').hide('slow',function(){
superHero();
});
});
$('#greenlantern').click(function(){
$('#greenlantern').hide('slow',function(){
superHero();
});
});
$('#batman').click(function(){
$('#batman').hide('slow',function(){
superHero();
});
});
$('#superman').click(function(){
$('#superman').hide('slow',function(){
superHero();
});
});
});
Right now the current thing that is happening is I will eliminate all of the correct superheroes and it will not alert me that the user has won. I've tried a lot of different things and the only other result I've gotten is to have the system alert the user every time they click on a superhero that they've won which is also incorrect.
EDIT
This has been solved by changing the scope of the variables to inside the function.
You should declare your variables i.e. flashHidden in your function. Currently you are setting then at the start.
function superHero() {
var flashHidden = !$('#flash').is(':visible');
var greenHidden = !$('#greenlantern').is(':visible');
var batmanHidden = !$('#batman').is(':visible');
var supermanHidden = !$('#superman').is(':visible');
if(flashHidden && batmanHidden && supermanHidden && greenHidden) {
alert ("Congratulations!!! You have won the game!! Please proceed forward and fill out a quick survey for the developers");
}
}
Additionally your click handler can be condensed into
$('#flash, #greenlantern, #batman, #superman').click(function(){
$(this).hide('slow',function(){
superHero();
});
});
You're setting...
var flashHidden = !$('#greenlantern').is(':visible');
...to start with. But you're not updating that variable later on when it gets hidden. So according to your check of:
if(flashHidden && batmanHidden && supermanHidden && greenHidden) {
...Flash is still visible. Even though, yes, on the page he's gone.
Try adding this:
$('#flash').click(function(){
$('#flash').hide('slow',function(){
flashHidden=true;
superHero();
});
});
guys. I am trying to create a web-based calculator with basic operations using jQuery. I already have implemented the addition operation. Now, I am hooked in subtraction.
Here is a code snippet when you click on the minus button:
$("#btnSub").click(function () {
holdValue = $("#result").val();
currentValue = $("#result").val("0");
flagSub = "1";
flagNotEmpty = "0";
flagDecimal = "0";
});
Here is a code snippet when you click the equals button:
$("#btnEquals").click(function () {
if (flagNotEmpty == "0") {
alert("Missing Value.");
} else {
if (flagAdd == "1") {
currentValue = $("#result").val();
var output = parseFloat(holdValue) + parseFloat(currentValue);
$("#result").val(parseFloat(output));
} else if (flagSub == "1") {
currentValue = $("#result").val();
var output2 = parseFloat(holdValue) - parseFloat(currentValue);
$("#result").val(parseFloat(output2));
}
}
flagSub = "0";
flagAdd = "0";
flagNotEmpty = "0";
flagDecimal = "0";
});
Variables functions:
flagSub: used to determine that the operation choosen is subtraction
flagNotEmpty: used to determine if a number is pressed after selecting an operator. Displays error message if equal sign is clicked on right after the operator button.
flagDecimal: used to tell the program that a decimal has already been entered. Display error message for decimal point duplication.
Problem with this program is that it cannot perform subtraction when it is the first operation you do. That is, when the browser loads the UI and you do subtraction, nothing happens. BUT, when you do, for example, click 1 + 2 = then the program displays 3 in the textbox. Without refreshing the page, click - 10 =. Difference is displayed.
To start from the beginning, please refresh the page; will just add the CLEAR button after I am done with all the operations.
Just want to know what is wrong with my algorithm. For the complete code with html and css, here is its fiddle.
By the way, I have just started learning jQuery so please forgive me for the kind of messy and might be inefficient way of coding. Help is really much appreciated. Thanks in advance.
flagAdd needs to be initialized, you can alter the btnSub handler to do that
$("#btnSub").click(function () {
holdValue = $("#result").val();
currentValue = $("#result").val("0");
flagAdd = "0";
flagSub = "1";
flagNotEmpty = "0";
flagDecimal = "0";
});
alternatively you could initialize it in the document ready handler Fiddle