Implementing voting logic based on previous score - javascript

Wondering how to handle this. I've done it previously, but it involves a lot of if/else statements and I can't seem to figure it out without resorting to that. I posted it on codereview and got someone to help me re-facor it, but now I'm trying to get this functionality working properly.
How this works now is, if you click "up", it'll increase the score 1 point. If you click "up" again, it'll decrease the score. That's fine. If you click "down" it'll have the same behavior. It will not however go below 0 ever, since I don't want to display a negative score.
Right now I'm just checking to see if the previous or next buttons have .upColor and .downColor css classes on them, which check if they've already voted. I'm having trouble trying to update the proper score based off of this especially if the original score is 0, or if the score is 10.
Logic I'm trying to implement:
E.g. Original score is 0:
User votes up. Score goes to 1. User votes down. Score goes to 0 (not -1)
User votes down. Score stays at 0. User votes up. Score goes to 1.
E.g. Original score is 10:
User votes up. Score goes to 11. User votes down. Score goes to 9.
User votes down. Score goes to 9. User votes up. Score goes to 11.
Code:
$(function() {
var handleClick = function($btn) {
var $voteContainer = $btn.parent();
var scoreNode = $('.count');
var originalScore = Number($voteContainer.data('original-score'));
if ($btn.hasClass('down')) {
if ($btn.prevAll('.up').hasClass('upColor')) {
$btn.prevAll('.up').toggleClass('upColor');
alert('voted up now voting down, decrease 2 points, but don\'t go below 0.');
}
}
if ($btn.hasClass('up')) {
if ($btn.nextAll('.down').hasClass('downColor')) {
$btn.nextAll('.down').toggleClass('downColor');
alert('voted down now voting up, increase by 2 points');
}
}
var increment = $btn.hasClass('up') ? 1 : $btn.hasClass('down') && originalScore > 0 ? -1 : 0; // default
// Only do something if there is an increment
if (increment) {
var currentScore = Number(scoreNode.text()) || 0;
var newScore = currentScore + increment;
var diff = Math.abs(originalScore - newScore);
// Can't go more than + or - 1
if (diff > 1) {
newScore = originalScore;
}
// Set new displayed value
scoreNode.text(newScore);
}
$btn.hasClass('up') ? $btn.toggleClass('upColor') : $btn.toggleClass('downColor');
};
var upBtn = $('.up');
var downBtn = $('.down');
upBtn.add(downBtn).click(function() {
var $btn = $(this);
handleClick($btn);
});
});
Demo: http://jsfiddle.net/3kCPw/

I won't rewrite your code because it will take me too long, but I will give you some code that I would have used from the start.
Start with the original number:
var original_vote = 2;
var current_vote = original_vote;
Keep this as a constant to refer to for the future. Then when you click the up vote, you can add 1 to that simply with:
current_vote = original_vote + 1;
Then un-checking the up vote would make it:
current_vote = original_vote;
Then just do the opposite for down voting.
Keeping the original number ensures that you will not accidentally make the votes go out of the scope that it should.
Hope this helps!

Related

How to display updated localStorage data after page is refreshed?

2 things I would like to accomplish here:
I'm trying to display the new high score after the page is refreshed.
The high score resets to 0 after refreshing due to localStorage.setItem('high_score', 0); so I'm not sure how to properly set this without resetting it to 0 every time the page is refreshed.
let score = 0;
var high_score = 0;
localStorage.setItem('high_score', 0);
document.getElementById('high_score').innerHTML="HIGH<br>SCORE:<br>" +
localStorage['high_score'];
if (score > parseInt(localStorage.getItem('high_score'), 10)) {
localStorage.setItem('high_score', score);
}
You could only set the storage item except when you need to update it:
// assuming the scores will not be negative
const newHighScore = Math.max(localStorage.high_score, score);
localStorage.high_score = newHighScore;
And then when using the storage value, alternate with 0:
document.getElementById('high_score').innerHTML="HIGH<br>SCORE:<br>" +
(localStorage.high_score || 0)

How can I adjust in my Jquery Code see description of problem

Currently right now it adds up a visit counter. Example: I have a text field and I type 1 then next text field I type of 20 so 1 of 20 visits. Next document I use it uses the same counter so it would automatically calculate up the visits for me to say 2 of 20 visits. What I want to figure out is if I need to change the counter to say 3 of 20 instead of 2 out of 20 how can I adjust the code to save my changes.
Currently the counter reverts back after I save my document with the counter in it- reverts back to 2 of 20 not reflecting me changing it to 3 of 20.
window.onload = function(e){
setCurrentCount('previousvisit','currentvisit','totalvisits');
}
function setCurrentCount(prevId, currentId, totalId ) {
var prevEle = document.getElementById(prevId);
var currentEle = document.getElementById(currentId);
var totalEle = document.getElementById(totalId );
if( prevEle && currentEle && totalEle ) {
var totalVal = parseInt(totalEle.value);
if( totalVal > 0) {
var prevVal = 0;
// check the prev value
// if it is empty, set it to the total value
if(! prevEle.value ) {
//currentEle.value = totalVal;
prevEle.value = totalVal;
} else {
currentEle.value = parseInt(prevEle.value) + 1;
}
}
}
}
If I change the counter to reflect a different number outside the initial calculation I want it to save it- right now it reverts back to the number it actually should be in the calculation.

JavaScript and Array's

EDIT I originally posted this with my version of the J.S but it's so far off no one can even help so i'm starting over. Here is the pseudocode i have done that needs to be translated into a Javascript program. Any help is appreciated!
I am a beginning programmer i understand this code will have multiple errors, that's why i am here. Array's and loops have given me much trouble while trying to learn them and especially with formatting them in JavaScript. The things i know are incorrect or still need i commented out i still need them, i also know i'm not passing anything i just can't seem to wrap my head around how to get them there. I'm also not sure if while gather input i'm using alter and prompt correctly. In the display function the spacing is necessary for when it will be displayed. Corrections and explanations are greatly appreciated.
Module main()
//Declare local variables
Declare endProgram = “no”
While endProgram == “no”
Declare Real notGreenCost[12]
Declare Real goneGreenCost[12]
Declare Real savings[12]
Declare String months[12] = “January”, “February”, “March”, “April”, “May”, “June”, “July”, “August”, “September”, “October”, “November”, “December”
//function calls
getNotGreen(notGreenCost, months)
getGoneGreen(goneGreenCost, months)
energySaved(notGreenCost, goneGreenCosts, savings)
displayInfo(notGreenCost, goneGreenCosts, savings, months)
Display “Do you want to end the program? Yes or no”
Input endProgram
End While
End Module
Module getNotGreen(Real notGreenCost[], String months[])
Set counter = 0
While counter < 12
Display “Enter NOT GREEN energy costs for”, months[counter]
Input notGreenCosts[counter]
Set counter = counter + 1
End While
End Module
Module getGoneGreen(Real goneGreenCost[], String months[])
Set counter = 0
While counter < 12
Display “Enter GONE GREEN energy costs for”, months[counter]
Input goneGreenCosts[counter]
Set counter = counter + 1
End While
End Module
Module energySaved(Real notGreenCost[], Real goneGreenCost[], Real savings[])
Set counter = 0
While counter < 12
Set savings[counter] = notGreenCost[counter] – goneGreenCost[counter]
Set counter = counter + 1
End While
End Module
Module displayInfo(Real notGreenCost[], Real goneGreenCost[], Real savings[], String months[])
Set counter = 0
While counter < 12
Display “Information for”, months[counter]
Display “Savings $”, savings[counter]
Display “Not Green Costs $”, notGreenCost[counter]
Display “Gone Green Costs $”, goneGreenCost[counter]
End While
End Module
A few notes:
Currently the program creates a few variables and functions that
don't seem to interact
Most of the edits below are not optimal - there are parts that
could be done by much simpler means (i.e. counter++) - But thats
for you to learn =P
I made quite a few assumptions of what you wanted the program to
do, they might be wrong, they might be right
var notGreenCost = []; //Array lengths don't need to be specified
var goneGreenCost = [];
var savings = [];
var months = ["January", "Feburary", "March", "April", "May", "June"];
//A boolean value (true | false) would suit this better as opposed to "yes"/ "no"
var endProgram = false;
var option = 0;
/* You dont need main functions in javascript
* migrated everything to be global :/
* Delete:
function main(){
// Move this (made it global): var endProgram = "no";
}
*/
// I don't think this is meant to be initMonths..
// Maybe something like getOptions?
function /*initMonths*/getOptions(){
while (endProgram == false){ //lowercase while
//Because prompt would block everything else until it gets input
//we probably want to move the prompt to be after the alerts
alert("options:"); //Clarity
alert("1 to enter data");
alert("2 to display data");
alert("3 to write data to a file");
alert("4 to read data from a file");
//Alter global "option" to take the value of the prompt
option = prompt("What would you like to do? Type:");
//} //I assume you want the rest of the code in this while loop - otherwise it will loop forever
// Delete this bracket (its unmatched): {
// Delete return statement as it will stop the function return option;
// Delete this bracket (its unmatched): }
//Create a variable to take the value of prompt (this should be outside the while loop) but it seem clearer for explanation purposes to be here
var toEnd;
toEnd = prompt("Do you want to end the program (enter yes or no)");
// Javascript uses != for "not equal to" and && for "AND"
while (toEnd != "no" && toEnd != "yes") {
toEnd = prompt("Please enter a value of yes or no");
}
//I think you want to assign the value of toEnd to endProgram
// Note the the below is not the only/best way to do it
if(toEnd == "no") {
endProgram = false;
} else if(toEnd == "yes") {
endProgram = true;
}
// While use brackets not End s
// End While
// End While
}//End while loop here
}
Javascript in a browser cannot alter files - writeToFile, readFromFile have all been removed
I believe you want months to be global, if it is then initMonths is unnecessary
getNotGreen:
function getNotGreen(){
//You don't need to specify types in Javascript
/*Integer*/ var counter = 0
while (counter < 6){ //lowercase while
//I'm assuming you want to combine the values of "Enter NOT GREEN energy costs for" and months[counter] - This is done by using the + sign
//Im also assuming you want to read the value into notGreenCost
//.push adds a value to a array
notGreenCost.push(prompt("Enter NOT GREEN energy costs for" + months[counter]))
//Returning here makes the rest of the function redundant
//}
//return notGreenCost[counter];
//}
//Javascript does not use Set
// Note that below is not the only/best way to do it
/*Set*/ counter = counter + 1
} //End the while loop here
}
getGoneGreen:
function getGoneGreen(){
//Counter should probably be local (not global) - use var
var counter = 0;
while (counter < 6){//lowercase while
//I'm assuming you want to combine the values of "Enter NOT GREEN energy costs for" and months[counter] - This is done by using the + sign
//Im also assuming you want to read the value into notGreenCost
//.push adds a value to a array
goneGreenCost.push(prompt("Enter GONE GREEN energy costs for" + months[counter]));
//See above (getNotGreen)
//}
//return goneGreenCost[counter];
/*Set*/ counter = counter + 1;
}//End while loop here
}
energySaved:
function energySaved(){
//Counter should probably be local (not global) - use var
var counter = 0;
while (counter < 6){//lowercase while
savings[counter] = notGreenCost[counter] - goneGreenCost[counter]
counter = counter + 1;
}
} //I assume you want to end energySaved here?
displayInfo:
function displayInfo(){
//Alert produced individual boxes, i assume you want the following in a single window?
// "\n" is a line break
alert("SAVINGS NOT GREEN GONE GREEN MONTH\n"+
"_________________________________________________\n");
//Counter should probably be local (not global) - use var
var counter = 0;
while (counter < 6){//lowercase while
alert( "$" + savings[counter] + "$" + notGreenCost[counter] + "$" + goneGreenCost[counter] + "" + months[counter]);
counter = counter + 1;
}
} //I assume you want to end displayInfo here?

Javascript timer used in points system

I am trying to make a game. There are blocks falling and a main block which the user commands that is trying to avoid them. There is a point system that is supposed to add 10points each time the red cube touches one of the extremities. The problem is that it adds 10 points per each 10 milliseconds that the cube stays in the extremity. How can I solve this??
You just need a flag that you set and then clear whenever you touch the side.
Since the box starts touching the side, i initialized already_touched to true.
var already_touched = true;
Then your logic below becomes:
if (mySprite.x == 450 || mySprite.x == 0) {
if (!already_touched) {
already_touched = true;
count += 10;
}
var alert1 = document.getElementById("score");
alert1.innerHTML = "Score: " + count;
} else {
already_touched = false;
}
Working demo here: http://jsfiddle.net/KrZq9/

Javascript alert box shows up before executing previous statement

I am having a strange issue, but it is not surprising as I am a bit of a JavaScript newbie. Basically I am creating a simple high-low card game. (Draw two cards, highest card wins). Anyways, the code is below.
The basic flow of the program is pretty simple. I choose 2 random numbers (1-52). These numbers are mapped to a corresponding card. (i.e. number 1 is the ace of spades, number 37 is the jack of clubs, etc.). Anyways, after drawing the cards, the program is to display the corresponding card and determine the winner. At the end of all of this, i have an alert that comes up and and tells the winner of the draw and asks if the user wants to play again.
The problem I am having is this: Even though the program should have already displayed the image of the card and output the results to a text area, the alert box shows up before any of that actually occurs and never displays the cards or the results. Any ideas? I am posting all of the code so far and any help would be appreciated. Thanks in advance.
function drawCards() {
var oppCard = randNumber();
var customerCard = randNumber();
while (oppCard == customerCard) {
customerCard = randNumber();
}
var oppCardName = displayCard(oppCard, "oppImage");
var customerCardName = displayCard(customerCard, "custImage");
var result2 = "Your card was: " + customerCardName;
var result1 = "The opponent's card was: " + oppCardName;
var result3 = determineWinner(oppCard, customerCard);
var result4 = result3 + '\n' + result1 + '\n' + result2;
$("#textareaRes").text(result4);
playAgain(result3);
}
function determineWinner(oppsCard, customersCard) {
var oppValue = oppsCard % 13;
var customerValue = oppsCard % 13;
var winnerString = "";
if (oppValue == 0) {
oppValue = 13;
}
if (customerValue == 0) {
customerValue = 13;
}
if (oppValue == customerValue) {
winnerString = "You Tied.";
}
else if (oppValue > customerValue) {
winnerString = "You Lose.";
}
else if (oppValue < customerValue) {
winnerString = "You Win!!";
}
return winnerString;
}
function randNumber() {
var min = 1;
var max = 52;
var random = Math.floor(Math.random() * (max - min + 1)) + min;
return random;
}
function playAgain(resultString) {
if (resultString == "You Lose." || resultString == "You Win!!") {
alert(resultString);
var conf = confirm("Play Again?");
if (conf == true) {
$("#textareaRes").text("");
document.getElementById("custImage").src="./cardImages/default.png";
document.getElementById("oppImage").src="./cardImages/default.png";
}
else {
window.location = "#mainMenuPage";
}
}
else {
alert(resultString);
alert("Try Again.");
$("#textareaRes").text("");
document.getElementById("custImage").src="./cardImages/default.png";
document.getElementById("oppImage").src="./cardImages/default.png";
}
}
So I did not place the code in here for the display card function, just because for testing it is exceptionally long. It is just a giant switch case for all 52 random numbers. The finished product will actually be pulling from an XML file, but I used this just for testing purposes. (If, for some reason, you need to see the display cards function, let me know and I can post it.) Anyway, to recap, the last call made in the drawCards() function is the playAgain function. Upon running this code the results nor the card images are displayed. It just jumps straight to the alert that is called for by the playAgain function. This is probably a pretty noobish question, but I am a little perplexed by it. So any help you guys can offer would be GREATLY appreciated. Thanks.
EDIT: It actually performs correctly in a computer's browser. However, the problem happens on a mobile device like a phone or tablet. So this is probably something that I am doing incorrectly here. Any help is greatly appreciated.
Changes in the browser doesn't show up as long as your Javascript code is running.
The browser is event driven, so changing an element in the DOM doesn't show the change immediately, instead an event is triggered to redraw the element. When your function has finished running, the browser will handle any pending events and show the changes.
So, when building an application, you have to use the same approach so that the browser has a chance to show the changes.
For anyone who finds this looking for the solution to the problem, the solution can be found in this answer: https://stackoverflow.com/a/13338585/870729
Here is a working fiddle of a simple example:
jQuery(function($) {
$.when($('#empty-me').html('')).done(function() {
alert('I did it!');
});
});
"./cardImages/default.png"
im not sure ... but try "../cardImages/default.png" ... i always use 2 dots for come to a higher level

Categories

Resources