I decided to build a high/low game in javascript and am running into an issue where the numbers displayed are ahead of what the variables have stored or the exact opposite. I can't seem to get them to match.
EDIT: I figured it out, the code ran before ajax was done causing an offset.
It helps me more when I find answers with the old code to compare with the new so I'll leave the broken code. Updated with working code at the end.
Page that helped me figure out a fix:
Wait for AJAX before continuing through separate function
Original JavaScript:
var y = "0";
var z = "0";
var output_div = document.getElementById("outcome");
var last_ = document.getElementById("val");
var cardVal;
function higher(x) {
var new_ = last_.innerHTML; //getting new value
y = last_.getAttribute("data-old"); //getting old value
console.log("data_old " + y);
z = ajx(); //calling function return the value from which need to compare
console.log("data_new " + z);
if (x === 1) {
if (z > y) {
output_div.innerHTML = "Winner!";
} else {
output_div.innerHTML = "Loser!";
}
} else {
if (z < y) {
output_div.innerHTML = "Winner!";
} else {
output_div.innerHTML = "Loser!";
}
}
last_.setAttribute("data-old", new_); //setting old value with current value of div
}
function ajx() {
$.ajax({
url: "./getfacecard.php",
success: function(response) {
var result = $.parseJSON(response);
var img = result[0];
cardVal = result[1];
document.getElementById(\'card\').src = img;
document.getElementById(\'val\').innerHTML = cardVal;
}
});
return cardVal; // return current card value in calling function
}
Updated Working JavaScript:
var lastVal = document.getElementById("lastVal"); //Last played cars value
var wl = document.getElementById("outcome"); //Shows win or lose
var newVal = document.getElementById("currentVal"); //Current face up card
var iSrc = document.getElementById("card"); //Card img
var lVal; //Last cards value from post
var iLink; //Image link from post
var nVal; //Gets new html to be sent to post.
function start(x){
// console.log("Start:");
ajx(function(){ //Runs ajax before continuing
iSrc.src = iLink; //Set new card image src
newVal.innerHTML = nVal; //Sets Current card value in div
lastVal.innerHTML = lVal; //Sets Last card value in div
// console.log("-slgn"); //Consoles to track code launch order.
// console.log("-Last Value: "+lVal);
// console.log("-Current Value: "+nVal);
// console.log("-Link: "+iLink);
// console.log(x);
if(x===1){ //If clicked higher
if(nVal>lVal){ //If new card is higher than old card
wl.innerHTML = "Winner!";
}else{
wl.innerHTML = "Loser!"
}
}
if(x===2){
if(nVal<lVal){ //If new card is lower than old card
wl.innerHTML = "Winner!";
}else{
wl.innerHTML = "Loser!"
}
}
});
}
function ajx(callback) {
$.ajax({
type: "POST",
data: {data:newVal.innerHTML}, //Post new card value to be returned as last card.
url: "./getfacecard.php",
success: function(response) {
var result = $.parseJSON(response);
iLink = result[0]; //img
lVal = result[2]; //Last card
nVal = result[1]; //New Card
// console.log("ajax");
callback(); //Go back and the code
}
});
}
You can use custom attribute in your div to save your current value as old value and vice versa so only one div required here i.e: Your div look like below :
<div data-old="0" id="val">0</div>
And js code will look like below:
var y = "0";
var z = "0";
var output_div = document.getElementById("outcome");
var last_ = document.getElementById("val");
function higher(x) {
var new_ = last_.innerHTML; //getting new value
y = last_.getAttribute("data-old"); //getting old value
console.log("data_old " + y);
z = ajx(); //calling function return the value from which need to compare
console.log("data_new " + z);
if (x === 1) {
if (z > y) {
output_div.innerHTML = "Winner!";
} else {
output_div.innerHTML = "Loser!";
}
} else {
if (z < y) {
output_div.innerHTML = "Winner!";
} else {
output_div.innerHTML = "Loser!";
}
}
last_.setAttribute("data-old", new_); //setting old value with current value of div
}
function ajx() {
$.ajax({
url: "./getfacecard.php",
success: function(response) {
var result = $.parseJSON(response);
var img = result[0];
var cardVal = result[1];
document.getElementById('card').src = img;
document.getElementById('val').innerHTML = cardVal;
}
});
return cardVal; // return current card value in calling function
}
In above js code what i done is after ajax call finishes execution it will return cardVal which will get pass in variable z and then we will compare it with y i.e : old value and print required output.Also, i have return value from ajax called because when you do document.getElementById(\'val\').innerHTML = cardVal; still this value is not available with us in our function higher so to overcome this i have return that value to your calling function.
(This code is already tested and working as excepted )
Related
I'm using fabricjs and want to render the text every time a value is updated.
But when I do this, the new text overlaps the old. I tried to clear the object but didn't find any way to do so.
Below is the code snippet to describe what I doing:
//console.log('topp'+ rect.getTop());
rect.on('moving', function() {
var rectTop = rect.getTop();
var upCounter = 0;
var downCounter = 0;
var text40;
var canvas_objects = canvasForRect._objects;
// console.log('topp'+ rect.getTop());
// READ STRING FROM LOCAL STORAGE
var retrievedObject = localStorage.getItem('heatMapClickData');
// CONVERT STRING TO REGULAR JS OBJECT
var text40;
var last = canvas_objects[canvas_objects.length - 1];
var parsedObject = JSON.parse(retrievedObject);
$.each(parsedObject, function(index, item) {
if (rectTop >= item['pos_y']) {
upCounter += 1;
} else {
downCounter += 1;
}
text40 = new fabric.Text("Total clicks above line" + upCounter, {
fontSize: 40
});
});
// var obj = canvasForRect.getActiveObject();
// console.log(obj);
text40.set({
text: "Total clicks above line" + upCounter
});
canvasForRect.add(text40);
// canvas.renderAll();
});
How do I re-render the text every time upCounter is updated?
I have the below code which is called onclick, and want to be able to show a second image after a few seconds, depending on which one is chosen from the array - so for example if 1.png is shown, then I want to show 1s.png, 2.png then show 2s.png etc
function displayImage () {
var img_name = new Array("images/1.png", "images/2.png", "images/3.png");
var l = img_name.length;
var rnd_no = Math.floor(l*Math.random());
document.getElementById("imgHolder").src = img_name[rnd_no];
}
How do I determine which image has been chosen from the array to then use in another function please ?
You're gonna need a global var for knowing that function is running for the first time or not.
var alreadyRandom = false;
function displayImage()
{
var img_name = new Array("images/1.png", "images/2.png", "images/3.png");
if(alreadyRandom)
{
// If the random for first time is done
var rnd_no = img_name.indexOf(document.getElementById("imgHolder").getAttribute('src'));
if(rnd_no === img_name.length-1)
{
// If the current image is the last one in array,
// go back to the first one
rnd_no = 0;
}
else
{
// Choose the next image in array
rnd_no++;
}
document.getElementById("imgHolder").src = img_name[rnd_no];
}
else
{
var l = img_name.length;
var rnd_no = Math.floor(l*Math.random());
document.getElementById("imgHolder").src = img_name[rnd_no];
alreadyRandom = true; // Tell the function not to random again
}
return img_name[rnd_no];
}
Demo: http://jsbin.com/kanejugahi/edit?html,js,console,output
Moreover, making the array global would make your function more efficient.
Hope this helps,
I think it's important you understand how Functions work in JavaScript and how scope works.
What you need to do is you need to expose that information so that both functions have access. You have the array of images defined and you have already determined the random number so just make them available by declaring them outside of the function so now these variables are available. Defining variables in the global scope is generally bad practice but this is simply for teaching.
var selectedImage; // defined outside so it is available for other functions
function displayImage() {
var img_name = new Array("images/1.png", "images/2.png", "images/3.png");
var rnd_no = Math.floor(img_name.length * Math.random());
selectedImage = img_name[rnd_no];
document.getElementById("imgHolder").src = selectedImage;
}
function anotherFunction() {
console.log(selectedImage);
}
As far as I understand the question, you can use a return and make the image array global.
var img_name = new Array("images/1.png", "images/2.png", "images/3.png");
var img_class = '';
//this function will return the index of the image in array
function displayImage () {
var l = img_name.length;
var rnd_no = Math.floor(l*Math.random());
document.getElementById("imgHolder").src = img_name[rnd_no];
return rnd_no;
}
var nextimage;
function showImages(){
//your logic to show the next image here
nextimage = (displayImage ()+1)%img_name.length;
var myVar = setInterval(function(){
if(img_class==''){
document.getElementById("imgHolder").src = img_name[nextimage];
img_class = 's';
}else{
var img_arr = img_name[nextimage].split(".");
if(img_arr.length===2){
document.getElementById("imgHolder").src = img_arr[0]+"s."+img_arr[1];
}
img_class = '';
nextimage = (nextimage+1)%img_name.length;
}
}, 1000);
}
var img_name = new Array("images/1.png", "images/2.png", "images/3.png");
var img_class = '';
//this function will return the index of the image in array
function displayImage () {
var l = img_name.length;
var rnd_no = Math.floor(l*Math.random());
document.getElementById("imgHolder").src = img_name[rnd_no];
return rnd_no;
}
var nextimage;
function showImages(){
//your logic to show the next image here
nextimage = (displayImage ()+1)%img_name.length;
var myVar = setInterval(function(){
if(img_class==''){
document.getElementById("imgHolder").innerHTML = img_name[nextimage];
img_class = 's';
}else{
var img_arr = img_name[nextimage].split(".");
if(img_arr.length===2){
document.getElementById("imgHolder").innerHTML = img_arr[0]+"s."+img_arr[1];
}
img_class = '';
nextimage = (nextimage+1)%img_name.length;
}
}, 1000);
}
showImages();
<div id="imgHolder"></div>
Mayve something like this?
var images = ["images/1.png", "images/2.png", "images/3.png"];
function displayImage () {
var dom = document.getElementById("imgHolder");
if ( images.indexOf(dom.src) >=0 ) {
dom.src = dom.src.replace(".png", "s.png"); // Seems like a stupid way to do this
return;
}
var l = images.length;
dom.src = images[Math.floor(l*Math.random())];
}
I need some help on an assignment that I need to do. Basically the question is a number guessing game. We're assigned a number in the interval [0,1023] based on our student number and we have 11 guesses to get the right number. I know I have to use a binary search to get the number, my only problem is connecting to the server and getting a result.
We're given this:
A sample request looks as follows:
http://142.132.145.50/A3Server/NumberGuess?snum=1234567&callback=processResult&guess=800
And also given that the request returns the following parameters:
1: A code to determine if your guess is equal, less than or greater than the number
2: Message string
3: Number of guesses made by my application
This is what I've tried so far, just as a test to get the server request working. All I get in return is "object HTMLHeadingElement"
window.onload = function() {
newGuess();
}
function newGuess() {
var url = "http://142.132.145.50/A3Server/NumberGuess?snum=3057267&callback=processResult&guess=600";
var newScriptElement = document.createElement("script");
newScriptElement.setAttribute("src", url);
newScriptElement.setAttribute("id", "jsonp");
var oldScriptElement = document.getElementById("jsonp");
var head=document.getElementsByTagName("head")[0];
if (oldScriptElement == null) {
head.appendChild(newScriptElement);
} else {
head.replaceChild(newScriptElement, oldScriptElement);
}
}
function processResult(code,message,guesses) {
var code = document.getElementById("code");
var message = document.getElementById("message");
var guesses = document.getElementById("guesses");
code.innerHTML = code;
message.innerHTML = message;
guesses.innerHTML = guesses;
}
EDIT: Current state of my code.
window.onload = function() {
min = 0;
max = 1023;
mid = 0;
setInterval(newGuess,1000);
};
function newGuess() {
mid = Math.floor((max-min)/2);
var url = "http://142.132.145.50/A3Server/NumberGuess?snum=3057267&callback=processResult&guess="+mid;
var newScriptElement = document.createElement("script");
newScriptElement.setAttribute("src", url);
newScriptElement.setAttribute("id", "jsonp");
var oldScriptElement = document.getElementById("jsonp");
var head=document.getElementsByTagName("head")[0];
if (oldScriptElement == null) {
head.appendChild(newScriptElement);
} else {
head.replaceChild(newScriptElement, oldScriptElement);
}
}
function processResult(codeJ,messageJ,guessesJ) {
code = document.getElementById("code");
message = document.getElementById("message");
guesses = document.getElementById("guesses");
code.innerHTML = codeJ;
message.innerHTML = messageJ;
guesses.innerHTML = guessesJ;
if(codeJ == 0){
return;
}else if(codeJ == -1){
min = mid + 1;
}else if(codeJ == 1){
max = mid -1;
}
console.log(mid);
}
Check your variable-names. You are overwriting the function-patameters.
Something like
code.innerHTML = code;
message.innerHTML = message;
guesses.innerHTML = guesses;
just CAN'T work, you should see the problem yourself...
I want to create a array containing objects, and I'm using Parse to query all the data.
However, the for loop which loops over the results doesn't does that in the correct order but randomly loops over the data. If I log i each iteration, the logs show different results every time.
Here is my code:
for (var i = 0; i < results.length; i++)
{
Parse.Cloud.useMasterKey();
// retrieve params
var objectid = results[i];
var self = request.params.userid;
// start query
var Payment = Parse.Object.extend("Payments");
var query = new Parse.Query(Payment);
query.get(objectid, {
success: function (payment) {
// get all the correct variables
var from_user_id = payment.get("from_user_id");
var to_user_id = payment.get("to_user_id");
var amount = payment.get("amount");
var createdAt = payment.updatedAt;
var note = payment.get("note");
var img = payment.get("photo");
var location = payment.get("location");
var status = payment.get("status");
var fromquery = new Parse.Query(Parse.User);
fromquery.get(from_user_id, {
success: function(userObject) {
var fromusername = userObject.get("name");
var currency = userObject.get("currency");
var toquery = new Parse.Query(Parse.User);
toquery.get(to_user_id, {
success: function(touser)
{
var tousername = touser.get("name");
if(tousername !== null || tousername !== "")
{
sendArray(tousername);
}
},
error: function(touser, error)
{
var tousername = to_user_id;
if(tousername !== null || tousername !== "")
{
sendArray(tousername);
}
}
});
function sendArray(tousername) {
var array = new Array();
// create the time and date
var day = createdAt.getDate();
var year = createdAt.getFullYear();
var month = createdAt.getMonth();
var hour = createdAt.getHours();
var minutes = createdAt.getMinutes();
// create the timestamp
var time = "" + hour + ":" + minutes;
var date = "" + day + " " + month + " " + year;
var associativeArray = {};
if(self == from_user_id)
{
fromusername = "self";
}
if(self == to_user_id)
{
tousername = "self";
}
associativeArray["from"] = fromusername;
associativeArray["to"] = tousername;
associativeArray["amount"] = amount;
associativeArray["currency"] = currency;
associativeArray["date"] = date;
associativeArray["time"] = time;
associativeArray["status"] = status;
if(note == "" || note == null)
{
associativeArray["note"] = null;
}
else
{
associativeArray["note"] = note;
}
if(img == "" || img == null)
{
associativeArray["img"] = null;
}
else
{
associativeArray["img"] = img;
}
if(location == "" || location == null)
{
associativeArray["location"] = null;
}
else
{
associativeArray["location"] = location;
}
array[i] = associativeArray;
if((i + 1) == results.length)
{
response.success(array);
}
},
error: function(userObject, error)
{
response.error(106);
}
});
},
error: function(payment, error) {
response.error(125);
}
});
}
But the i var is always set to seven, so the associative arrays are appended at array[7] instead of the correct i (like 1,2,3,4,5)
The reason that this is so important is because I want to order the payment chronologically (which I have done in the query providing the results).
What can I do to solve this issue?
Success is a callback that happens at a later point in time. So what happens is, the for loop runs 7 times and calls parse 7 times. Then after it has run each of parse success calls will be executed, they look at i which is now at 7.
A simple way to fix this is to wrap the whole thing in an immediate function and create a new closure for i. Something like this
for(var i = 0; i < results.length; i++){
function(iClosure) {
//rest of code goes here, replace i's with iClosure
}(i);
}
Now what will happen is that each success function will have access to it's own iClosure variable and they will be set to the value of i at the point they were created in the loop.
I am trying to call two functions when only the "add" button is clicked. the problem I am having is that the final four textboxes in the calculate_balances function are not outputting their variables.
var $ = function (id) {
return document.getElementById(id);
}
// Declare Arrays to store information from Inputs //
var transactions = [];
transactions[0] = []; // holds date
transactions[1] = []; // holds transaction type
transactions[2] = []; // holds amount
// Function to print results to text area //
var update_results = function () {
var list = ""; // string variable to build output //
// check to see if arrays are empty //
if (transactions[0].length == 0) {
$("results").value = "";
} else {
list = "";
// for loop to cycle through arrays and build string for textarea output //
for (var i = 0; i < transactions[0].length; i++) {
list += transactions[0][i] + " " + transactions[1][i] + " " + transactions[2][i] + "\n";
}
// display results //
$("results").value = list;
}
}
// function to gather inputs //
var add_transaction = function () {
$("add").blur();
transactions[0][transactions[0].length] = $("date").value;
transactions[1][transactions[1].length] = $("transType").value;
transactions[2][transactions[2].length] = parseFloat( $("amount").value);
update_results();
calculate_balances();
}
// function for Calculations //
var calculate_balances = function () {
var startBal = 2000.00;
var ttlDeposits = 0;
var ttlWithdrawals = 0;
var endBal = startBal;
if (transactions[1][transactions[1].length] == "deposit")
{
ttlDeposits += transactions[2][transactions[2].length];
endBal += ttlDeposits;
}
if (transactions[1][i] == "withdrawal")
{
ttlWithdrawals += transactions[2][transactions[i]];
endBal -= ttlWithdrawals;
}
$("balStart").value = parseFloat(startBal);
$("ttlDeposits").value = parseFloat(ttlDeposits);
$("ttlWithdrawals").value = parseFloat(ttlWithdrawals);
$("balEnd").value = parseFloat(endBal);
}
window.onload = function () {
$("add").onclick = add_transaction, calculate_balances;
update_results();
}
tHank you
Edit: Did not realize the OP was NOT using jQuery. Your onclick should look like this:
$("add").onclick = function(){
add_transaction();
calculate_balances();
};
The rest here is for jQuery which is not what the OP wanted.
For setting the value of a text box with jQuery use the val() method:
$("balStart").val(parseFloat(startBal));
To call the two methods when the button is clicked:
$("add").click(function(){
add_transaction();
calculate_balances();
});