I had a quick look and it looks like you haven’t decoupled the logic for mode selection and equal at all—notice that the code in my previous snippet is only meant to handle when =
is pressed and for the special cases; it’s there to help you to reason about part of your code and not there as a solution for you (that’s your job, not my job). In your current code equalHandler()
actually handles both when GEOM, PT... etc.
and when equal is pressed, which is not what I suggested in the previous post at all.
In addition, you are still calling $('#equal').on("click", callback);
every time the GEOM
button (or any other special mode buttons, I’ll just abbreviate it as GEOM
now) is pressed, so it’s only natural that you’re still getting duplicated outputs. This is the issue that I pointed out in the very first response—you should take some time to think about the sequence of execution and make sure that doesn’t happen.
The additional duplication comes from the fact that each time you press =
you are triggering both of these:
document.getElementById("equal").addEventListener("click", equalHandler)
- The
else { equalHandler(); }
block inside the solve()
function.
Since you are still creating event listeners inside equalHandler()
and it gets called twice, it’s only natural that you are doubling the problem from before.
Fixing any of this is meaningless if you don’t spend the time to reason about your code and understand the problem. Duct taping solutions is also a waste of everyone’s time because something else will just break.
I have already said everything that needs to be said about the problem, how to address it, and how to go about it in the future to avoid this from happening. If it’s a conceptual issue around what I said then I’m more than happy to expand on it, otherwise the following is the last thing I will say on this and hopefully it will bring you towards the right direction:
-
Rename equalHandler
on line 3 and line 332 assomeFunction
-
On line 331, create a new function called equalHandler
function equalHandler() {
}
-
Comment out line 17 to line 34
-
Copy line 18 to line 33 to inside the new equalHandler()
and uncomment them
function equalHandler() {
answer = 0;
var shape = $("#selectorGEOM :selected").text();
if (shape === "H.S.") {
shape = "hemisphere";
}
var find = $("#findGEOM :selected").text();
var part1 = $("#1GEOM").val();
var part2 = $("#2GEOM").val();
var answer = geo(shape, find, part1, part2);
$("#log").append(
"<div class='outputElement'><ul><li><div class='row'><div class='xOutput'>" +
answer[0] +
"</div><div class='yOutput'>" +
answer[1] +
"</div></div></li></ul></div>"
);
}
Test the GEOM mode and, the results will be correctly displayed but it’s still duplicating. Now the duplication is not because you are adding multiple event handlers anymore—you can verify this by switching modes and it’ll still only add one entry every time you press equal (instead of 1, 2, 3, 4… etc. like before). This is a bug that has always been there in your code—you are just appending elements to #log
and not cleaning anything up. So following from above:
- Add
$('.outputElement').remove();
to line 341
The duplication should now be gone and you should be getting the intended behaviour for the GEOM mode. Obviously the code above only fixes the GEOM mode and the problem is still present in the other modes, I was under the impression that you are using memoryExtra
to keep track of the current mode, but it seems that it either doesn’t do that anymore or it never has. Just so there is no ambiguity in how to go about the rest of it:
- Add
var currentMode = '';
to line 2
- Add
currentMode = 'GEOM';
to line 8
- Add
switch (currentMode) {
to line 334 and case 'GEOM':
to line 335
- Close the
switch
by adding }
to line 353
Test that everything is still working, and it should provided that I haven’t mistyped anything. This is the basic idea of how you would keep track of different modes and you can now do the migration for the other modes (from someFunction
to equalHandler
).
These changes are purely there to guide you to realise what the problem is and the outcome is by no means how I personally would approach it and/or considered good design.
In case I’ve made a mistake, the code is appended. I hope that helps!
$("document").ready(function() {
var currentMode = "";
var memoryExtra = 0;
function someFunction() {
// I just define the function, is not actually caled yet.
switch (memoryExtra) {
case "GEOM":
currentMode = "GEOM";
notEquations = 1;
$("#output").html("");
$("#output").append(
"<div class='row' id='marginGeom'><select class='selector' id='selectorGEOM'><option value='option1'>Cylinder</option><option value='option2'>Cone</option><option value='option3'>Sphere</option><option value='option4'>H.S.</option></select><select class='selector' id='findGEOM'><option value='option1'>Volume</option><option value='option2'>Height</option><option value='option3'>Radius</option></select><input id='1GEOM' style='text-align: center;' placeholder='Part 1'></input><input id='2GEOM' placeholder='Part 2' style='text-align: center;'></input></div>"
);
$("#log").html("");
$("#log").append(
"<h2 class='helpG' style='text-align: center;text-decoration: underline;'>Selected Shape </h2><h2 class='helpG' style='text-decoration: underline;'>Volume:</h2><h2 class='helpG'> Radius, Height </h2><h2 class='helpG' style='text-decoration: underline;'>Height:</h2><h2 class='helpG'> Volume, Radius </h2><h2 class='helpG' style='text-decoration: underline;'>Radius:</h2><h2 class='helpG'> Volume, Height </h2><hr/><h2 class='helpOutputElement'>Click on box & use arrow keys</h2>"
);
// $("#equal").on("click", function() {
// answer = 0;
// var shape = $("#selectorGEOM :selected").text();
// if (shape === "H.S.") {
// shape = "hemisphere";
// }
// var find = $("#findGEOM :selected").text();
// var part1 = $("#1GEOM").val();
// var part2 = $("#2GEOM").val();
// var answer = geo(shape, find, part1, part2);
// $("#log").append(
// "<div class='outputElement'><ul><li><div class='row'><div class='xOutput'>" +
// answer[0] +
// "</div><div class='yOutput'>" +
// answer[1] +
// "</div></div></li></ul></div>"
// );
// });
break;
case "PT":
notEquations = 1;
$("#output").html("");
$("#log").html("");
$("#output").append(
"<div class='row' id='marginPT'><select class='selector' id='selectorPT'><option value='option1'>Right</option><option value='option2'>Leg</option><option value='option3'>C</option></select><input id='1PT'style='text-align: center;' placeholder='Part 1'></input><input id='2PT'style='text-align: center;' placeholder='Part 2'></input><input id='3PT'style='text-align: center;' placeholder='Part 3'></input></div>"
);
$("#log").html(
"<h2 class='helpG' style='text-align: center;text-decoration: underline;'>Selected Finder</h2><h2 class='helpG' style='text-decoration: underline;'>Right:</h2><h2 class='helpG'> A, B, C </h2><h2 class='helpG' style='text-decoration: underline;'>Leg B:</h2><h2 class='helpG'> A, C </h2><h2 class='helpG' style='text-decoration: underline;'>Hypotenuse:</h2><h2 class='helpG'> A, B </h2><h2 class='helpWaver' style=''> This <b>only</b> works on right triangles or to find if they are right.</h2><hr/><h2 class='helpOutputElement'>Click on box & use arrow keys</h2>"
);
setInterval(function() {
// unimportant to the issue
$("#firstSelector :selected").text() === "Leg" ||
$("#firstSelector :selected").text() === "C"
? $("#3PT").attr("disabled", "disabled")
: $("#3PT").removeAttr("disabled", "disabled");
}, 100);
$("#equal").on("click", function() {
if (memoryExtra === "PT") {
answer = 0;
answerPT = 0;
answerPT =
$("#firstSelector :selected").text() === "Right"
? pt($("#1PT").val(), $("#2").val(), $("#3").val())
: pt(
$("#1PT").val(),
$("#2PT").val(),
$("#selectorPT :selected").text()
);
$("#log").append(
"<div class='outputElement'><ul><li><div class='row'><div class='xOutput'>" +
answerPT[0] +
"</div><div class='yOutput'>" +
answerPT[1] +
"</div></div></li></ul></div>"
);
}
});
break;
case "prime":
notEquations = 1;
$("#log").html("");
$("#output").html("");
$("#output").append(
"<div style='text-align: center;'><p>Input a number to extract its prime Numbers</p><input id='1PRIME' style='text-align: center;'class='prime' value='20000'/></div>"
);
$("#equal").on("click", function() {
if (memoryExtra === "prime") {
answer = [];
var prime = sumPrimes($("#1PRIME").val());
$("#log").append(
" <div style='padding-top: 16px;' class='primeOutputItem'> <h3 class='primeOutputH3'> Prime count: " +
prime[1] +
"</h3> <hr/><h3 class='primeOutputH3'>" +
prime[0] +
"</h3></div><hr/>"
);
}
});
break;
case "algebra":
notEquations = 1;
$("#output").html("");
$("#output").append(
"<div class='row'><h1 class='yAlge'>Y=</h1><input id='1Alge' class='algeInput'value='(x*3)**3'/><h1 class='xAlge'>X=</h1><input id='2Alge' class='algeX'value='1000'/></div>"
);
$("#log").html("");
$("#equal").on("click", function() {
if (memoryExtra === "algebra") {
graph($("#1Alge").val(), $("#2Alge").val());
}
}); // equal
break;
} // switch
} // function (equalHandler)
var notEquations = 0;
const pt = (input1, input2, input3) => {
var arr = [input1, input2, input3];
arr = arr.sort();
return input3 === "C"
? ["C", Math.sqrt(input1 ** 2 + input2 ** 2)]
: input3 === "Leg"
? ["B", Math.sqrt(input2 ** 2 - input1 ** 2)]
: input1 ** 2 + input2 ** 2 === input3
? ["R", input1 ** 2 + " + " + input2 ** 2 + " === " + input3]
: ["NR", input1 ** 2 + " + " + input2 ** 2 + " !== " + input3];
};
const sumPrimes = num => {
var prime = [];
var arr = [];
for (let i = 2; i <= num; i++) {
arr.push(i);
}
// create the list of numbers
for (let i = 0; i < arr.length; i++) {
var number = arr[i];
// we know this number is prime
prime.push(number + ",");
for (var j = i + 1; j < arr.length; j++) {
// so you dont count that same number again, second loop to go back through and take out any mutiples of selected number.
if (arr[j] % number === 0) {
// evenly devided?
var arrayTail = arr.slice(j + 1);
// last half of the array
arr = arr.splice(0, j).concat(arrayTail);
// first half, takes out that number and joins them together
}
}
// after the loop is over, and than repeats again. Each time when you pick a number (line 10) we know its prime.
}
return [prime.join(" "), prime.length];
// the prime numbers and how many there are.
};
const graph = (equation, range) => {
var x = 0;
while (x <= range) {
console.log("when X=" + x + ", Y=" + eval(equation));
x++;
}
};
const geo = (shape, find, input1, input2) => {
if (shape === "Cylinder") {
return find === "Volume"
? ["V", Math.PI * Math.pow(input1, 2) * input2]
: find === "Radius"
? ["R", Math.sqrt(input1 / (Math.PI * input2))]
: find === "Height"
? ["H", +input1 / (Math.PI * Math.pow(input2, 2))]
: null;
}
if (shape === "Cone") {
return find === "Volume"
? ["V", Math.PI * Math.pow(input1, 2) * input2 / 3]
: find === "Radius"
? ["R", Math.sqrt(input1 * 3 / (Math.PI * input2))]
: find === "Height"
? ["H", input1 * 3 / (Math.PI * Math.pow(input2, 2))]
: null;
}
if (shape === "Sphere") {
return find === "Volume"
? ["V", 4 / 3 * (Math.PI * Math.pow(input1, 2))]
: find === "Radius"
? ["R", Math.cbrt(input1 / Math.PI * (3 / 4))]
: find === "Height"
? ["H", Math.cbrt(input1 / Math.PI * (3 / 4))]
: null;
}
if (shape === "Hemisphere") {
return find === "Volume"
? ["V", 2 / 3 * (Math.PI * Math.pow(input1, 2))]
: find === "Radius"
? ["R", Math.cbrt(input1 / Math.PI * (3 / 4)) / 2]
: find === "Height"
? ["H", Math.cbrt(input1 / Math.PI * (3 / 4)) / 2]
: null;
}
};
var answerPT = 0;
var combination = 0;
var algebraCheck = 0;
var prime = 0;
var geom = 0;
var ptCheck = 0;
var ans = 0; // So you can use your previous equation answer
var answer = 0; // This is to check if you have awnsered, to give Ans a value
var equation = [];
var memory = [];
var symbol = false;
var showNumber = [];
var number = false;
const solve = id => {
console.log(id);
memoryExtra = id;
if (id === "ac") {
notEquations = 0;
}
if (
id !== "GEOM" &&
id !== "PT" &&
id !== "prime" &&
id !== "algebra" &&
notEquations !== 1
) {
$("#output").html("");
$("#output").append("<h1 id='current'></h1><h1 id='equation'></h1>");
//$("#log").html("")
$("#current").html(equation);
$("#equation").html(equation);
symbol = false;
number = false;
if (id === "*" || id === "+" || id == "-" || id === "/") {
showNumber = [];
number = false;
symbol = true;
}
if (
isNaN(id) !== true ||
id === "%" ||
id === "(" ||
id === ")" ||
id === "ans" ||
id === "√(" ||
id === "∛(" ||
id === "."
) {
number = true;
showNumber.push(id);
$("#log").html("");
}
if (number === true && answer === 1) {
// so it earases previous equation in case of it being a number when you go to type
equation = [];
equation.push(id);
showNumber = [];
$("#current").html(equation);
$("#equation").html(equation);
answer = 0;
return (symbol = false);
} else if (symbol === true && answer === 1) {
// keeps previous equation if symbol and adds o that new equation ans, symbol (ans+)
equation.push(ans);
equation.push(id);
$("#current").html(equation);
$("#equation").html(equation);
answer = 0;
return (symbol = false);
}
if (id === "equal") {
equation = equation.join("");
memory.push(
equation +
" = " +
eval(
equation
.replace("%", "/100")
.replace("π", "Math.PI")
.replace("√(", "Math.sqrt(")
.replace("∛(", "Math.cbrt(")
)
);
equation = eval(
equation
.replace("%", "/100")
.replace("π", "Math.PI")
.replace("√(", "Math.sqrt(")
.replace("∛(", "Math.cbrt(")
);
ans = equation;
$("#current").html(equation);
$("#log").html("");
equation = [];
answer = 1;
} else if (id === "ac") {
memoryExtra = 0;
notEquations = 0;
$("#current").html("");
$("#current").html("");
ans = 0;
equation = [];
$("#output").html("");
$("#output").append("<h1 id='current'></h1><h1 id='equation'></h1>");
$("#log").html("");
showNumber = [];
symbol = false;
number = false;
} else {
if (number === true) {
$("#current").html(showNumber.join(""));
// so you can see, for instance, 7863 at the same time
} else {
// or if teh previous thing was a symbol, erases that symbol and puts number and starts chain of numbers (line 169)
$("#current").html(id);
}
equation.push(id);
$("#equation").html(equation);
// adds that number to teh equation and displays that.
} // else for solve function
} else {
someFunction();
}
}; // solve (id)
function equalHandler() {
switch (currentMode) {
case "GEOM":
answer = 0;
var shape = $("#selectorGEOM :selected").text();
if (shape === "H.S.") {
shape = "hemisphere";
}
var find = $("#findGEOM :selected").text();
var part1 = $("#1GEOM").val();
var part2 = $("#2GEOM").val();
var answer = geo(shape, find, part1, part2);
$(".outputElement").remove();
$("#log").append(
"<div class='outputElement'><ul><li><div class='row'><div class='xOutput'>" +
answer[0] +
"</div><div class='yOutput'>" +
answer[1] +
"</div></div></li></ul></div>"
);
}
}
document.getElementById("equal").addEventListener("click", equalHandler);
document
.getElementById("buttonRows")
.addEventListener("click", e => solve(e.target.id));
});