Setting elements with jQuery, what did I miss. - javascript

const form = document.getElementById("form");
let accountBalance = $("#accountBalance");
let stockPrice = $("#stockPrice");
accountBalance = parseInt(accountBalance);
stockPrice = parseFloat(stockPrice);
// const div = document.getElementById('div');
$("#display").hide();
let amountPerTrade = function amountPerTrade() {
return accountBalance / 4;
}
// Returns shares that are allowed per trade
let sharesPerTrade = function sharesPerTrade() {
const amountPerTrade = accountBalance / 4;
return Math.floor(amountPerTrade / stockPrice);
}
// Returns amount that should be calculated for limit and stop amounts
function getExitAmount(percentage) {
let amount = ((accountBalance * percentage) / sharesPerTrade()).toFixed(2);
return amount;
}
let limitPrice = function limitPrice() {
return getExitAmount(.03) + stockPrice;
}
let stopPrice = function stopPrice() {
return stockPrice - getExitAmount(.01);
}
let possibleProfit = function possibleProfit() {
return (getExitAmount(.03) * sharesPerTrade()).toFixed(2);
}
let possibleLoss = function possibleLoss() {
return (getExitAmount(.01) * sharesPerTrade()).toFixed(2);
}
$("form").submit(function () {
$("form").hide();
$("#amountPerTrade").html(amountPerTrade);
$("#sharesPerTrade").html(sharesPerTrade);
$("#limitPrice").html(limitPrice);
$("#stopPrice").html(stopPrice);
$("#possibleProfit").html(possibleProfit);
$("#possibleLoss").html(possibleLoss);
$("#display").show();
return false;
});
$("#reset").click(function (){
$("form").show();
$("#display").hide();
return false;
});
So this is my js code, all my id's in the HTML correspond. I've checked rechecked and checked again. I know I'm missing something stupid here. But every time I run it either nothing is put into the HTML element or I NaN.
The full code is at https://github.com/rustycomer/stock-strategy-calculator/tree/Update2.0

There are a number of problems in your code.
I have made some changes on it so the result can be shown now. You can have a check first.
const form = document.getElementById("form");
let accountBalance = $("#accountBalance")[0].value;
let stockPrice = $("#stockPrice")[0].value;
// const div = document.getElementById('div');
$("#display").hide();
let amountPerTrade = function amountPerTrade() {
return accountBalance / 4;
}
// Returns shares that are allowed per trade
let sharesPerTrade = function sharesPerTrade() {
let amountPerTrade = accountBalance / 4;
return Math.floor(amountPerTrade / stockPrice);
}
// Returns amount that should be calculated for limit and stop amounts
function getExitAmount(percentage) {
let amount = (((accountBalance) * percentage) / sharesPerTrade()).toFixed(2);
return amount;
}
let limitPrice = function() {
return getExitAmount(.03) + stockPrice;
}
let stopPrice = function() {
return stockPrice - getExitAmount(.01);
}
let possibleProfit = function() {
return (getExitAmount(.03) * sharesPerTrade()).toFixed(2);
}
let possibleLoss = function() {
return (getExitAmount(.01) * sharesPerTrade()).toFixed(2);
}
$("form").submit(function () {
$("form").hide();
accountBalance = parseInt(accountBalance[0].value);
stockPrice = parseInt(stockPrice[0].value);
$("#amountPerTrade").html(amountPerTrade());
$("#sharesPerTrade").html(sharesPerTrade());
$("#limitPrice").html(limitPrice());
$("#stopPrice").html(stopPrice());
$("#possibleProfit").html(possibleProfit());
$("#possibleLoss").html(possibleLoss());
$("#display").show();
return false;
});
$("#reset").click(function (){
$("form").show();
$("#display").hide();
return false;
});
The major problem of your code is that the variables or functions did not manipulate properly.
In your $("form").submit(function() { }), $(target).html() can receive the html code you want to insert but not the function you have declared. You need to execute those function to get the returned value for insertion.
Also, in line 2 to 3, you have to get the value from the input but not the $(target).
Finally, please be careful the differences between var, let and const. They can make you crazy if you use them incorrectly.
Good luck.

not sure ,but it run and i hv chg u code to my code style
const form = document.getElementById("form");
$("#display").hide();
$("form").submit(function ()
{
$("form").hide();
var accountBalance = $("#accountBalance").val();
var stockPrice = $("#stockPrice").val();
function amountPerTrade()
{
return accountBalance / 4;
}
// Returns shares that are allowed per trade
function sharesPerTrade()
{
//const amountPerTrade = accountBalance / 4;
//return Math.floor(amountPerTrade() / stockPrice);
return (amountPerTrade() / stockPrice);
}
// Returns amount that should be calculated for limit and stop amounts
function getExitAmount(percentage)
{
return ((accountBalance * percentage) / sharesPerTrade()).toFixed(2);
}
function limitPrice()
{
return getExitAmount(0.03) + stockPrice;
}
function stopPrice()
{
return stockPrice - getExitAmount(0.01);
}
function possibleProfit()
{
return (getExitAmount(0.03) * sharesPerTrade()).toFixed(2);
}
function possibleLoss()
{
return (getExitAmount(0.01) * sharesPerTrade()).toFixed(2);
}
accountBalance = parseInt(accountBalance);
stockPrice = parseFloat(stockPrice);
// const div = document.getElementById('div');
$("#amountPerTrade").html(amountPerTrade());
$("#sharesPerTrade").html(sharesPerTrade());
$("#limitPrice").html(limitPrice());
$("#stopPrice").html(stopPrice());
$("#possibleProfit").html(possibleProfit());
$("#possibleLoss").html(possibleLoss());
$("#display").show();
return false;
});
$("#reset").click(function (){
$("form").show();
$("#display").hide();
return false;
});

Related

How can I encapsulate my code, so I can pass arguments from one function to another?

I wrote this simple carousel but without encapsulation. So previously I placed items from buttonControl() in global scope and added eventListeners on global scope, which are now emraced in prev() and next() functions. However, my encapsulation breaks the code. Because arguments from buttonControl() aren't global but prev() and next() needs them to work. I thought that maybe I can pass all arguments from buttonsControl() inside addEventListener('click', prev) but I cannot, because when I write thisaddEventListener('click', prev(slides,totalItems,allItems....)) it is launching this event without a click.And I even don't know if its correct way.
I thought of puting arguments from buttonsControl() inside prev() and next() but it won't work.
function buttonsControl(){
const slides = document.querySelector('.slides');
const totalItems = document.querySelectorAll('.slides>*').length - 1;
const allItems = document.querySelectorAll('.slides>*').length;
console.log(totalItems)
let activeItem = 0;
let controlCarouselFooter = document.querySelector('.carousel_footer');
controlCarouselFooter.innerHTML = `1 / ${allItems}`
console.log(controlCarouselFooter)
const prevButton = document.querySelector('.prev_button').addEventListener('click', prev)
const nextButton = document.querySelector('.next_button').addEventListener('click', next)
// no idea how to pass those arguments
}
// Buttons controls
function prev(){
// const prevButton = document.querySelector('.prev_button').addEventListener('click', () => {
if (activeItem === 0) {
activeItem = totalItems;
slides.style.transform = `translateX(-${totalItems * 100}%)`;
console.log(`if ${activeItem}`)
controlCarouselFooter.innerHTML = `${activeItem+1} / ${allItems}`
}else {
activeItem--;
slides.style.transform = `translateX(-${activeItem * 100}%)`;
console.log(`else ${activeItem}`)
controlCarouselFooter.innerHTML = `${activeItem+1} / ${allItems} `
}
}
// );
// }
function next(){
// const nextButton = document.querySelector('.next_button').addEventListener('click', () => {
if(activeItem < totalItems) {
activeItem++;
slides.style.transform = `translateX(-${activeItem * 100}%)`;
console.log(`if ${activeItem}`)
controlCarouselFooter.innerHTML = `${activeItem+1} / ${allItems}`
} else {
activeItem = 0;
slides.style.transform = 'none';
console.log(`else ${activeItem+1}`)
console.log(`totalItems ${totalItems}`)
controlCarouselFooter.innerHTML = `${activeItem+1} / ${allItems}`
}
}
// );
// };
// });
buttonsControl();
The easiest solution would be to define the functions prev and next inside the buttonsControl function, so that all its local variables are in scope through closure:
function buttonsControl() {
const slides = document.querySelector('.slides');
const totalItems = document.querySelectorAll('.slides>*').length - 1;
const allItems = document.querySelectorAll('.slides>*').length;
let activeItem = 0;
let controlCarouselFooter = document.querySelector('.carousel_footer');
controlCarouselFooter.innerHTML = `1 / ${allItems}`;
const prevButton = document.querySelector('.prev_button').addEventListener('click', prev);
const nextButton = document.querySelector('.next_button').addEventListener('click', next);
// Buttons controls
function prev() {
if (activeItem === 0) {
activeItem = totalItems;
} else {
activeItem--;
}
slides.style.transform = `translateX(-${totalItems * 100}%)`;
controlCarouselFooter.innerHTML = `${activeItem+1} / ${allItems}`
}
function next() {
if (activeItem < totalItems) {
activeItem++;
slides.style.transform = `translateX(-${activeItem * 100}%)`;
} else {
activeItem = 0;
slides.style.transform = 'none';
}
controlCarouselFooter.innerHTML = `${activeItem+1} / ${allItems}`
}
}
buttonsControl();
If I'm understanding your question correctly, You could bind the variables to the listeners.
EDIT: Someone pointed out that you're mutating activeItems. Which is true. So You will want to define all your variables on an object first so that mutation is persistent between function calls.
function buttonsControl(){
let obj = {};
obj.slides = document.querySelector('.slides');
obj.totalItems = document.querySelectorAll('.slides>*').length - 1;
obj.allItems = document.querySelectorAll('.slides>*').length;
console.log(obj.totalItems)
obj.activeItem = 0;
obj.controlCarouselFooter = document.querySelector('.carousel_footer');
controlCarouselFooter.innerHTML = `1 / ${allItems}`
console.log(controlCarouselFooter)
//bind the variables you want to use to your input
const prevButton = document.querySelector('.prev_button').addEventListener('click', prev.bind(null, obj))
const nextButton = document.querySelector('.next_button').addEventListener('click', next.bind(null, obj))
// no idea how to pass those arguments
}
// Buttons controls
function prev(obj){
//define the arguments in your fn params.
// const prevButton = document.querySelector('.prev_button').addEventListener('click', () => {
if (obj.activeItem === 0) {
obj.activeItem = totalItems;
obj.slides.style.transform = `translateX(-${totalItems * 100}%)`;
console.log(`if ${activeItem}`)
obj.controlCarouselFooter.innerHTML = `${obj.activeItem+1} / ${obj.allItems}`
}else {
obj.activeItem--;
obj.slides.style.transform = `translateX(-${activeItem * 100}%)`;
console.log(`else ${obj.activeItem}`)
obj.controlCarouselFooter.innerHTML = `${obj.activeItem+1} / ${obj.allItems} `
}
}
// );
// }
function next(obj){
...similar implimentation to prev()
}
// );
// };
// });
buttonsControl();

Looping array on click in javascript

I want to change the index of newAr on each click and console log the values of next object in newAr showed in looper function
Note: I only want the index second object values on second click and third object values in newAr on third click
HTML only has a button nothing else
const button = document.querySelector("button");
let firstVar = () => {
const firstVarVariable = Math.round(Math.random() * 10);
if (firstVarVariable < 5) {
return true;
} else {
return false;
}
};
let secondVar = () => {
const firstVarVariable = Math.round(Math.random() * 10);
if (firstVarVariable < 5) {
return true;
} else {
return false;
}
};
let thirdVar = () => {
const firstVarVariable = Math.round(Math.random() * 10);
if (firstVarVariable < 5) {
return true;
} else {
return false;
}
};
const newAr = [];
const pusher = () => {
newAr.push({
one: firstVar(),
two: secondVar(),
three: thirdVar(),
});
console.log(newAr);
looper();
};
const looper = () => {
for (const value of newAr) {
console.log(value.one);
console.log(value.two);
console.log(value.three);
}
// I want to change the index of newAr array on click
// Like i want to console log first object in array on first click
// and second object on other click and third object
// alsp please tell me if i can change some approch
};
button.addEventListener("click", () => {
pusher();
});
let randomBool = () => Math.random() < 0.5;
// all three functions did the same thing...
const newAr = [];
const pusher = () => {
newAr.push({
one: randomBool(),
two: randomBool(),
three: randomBool(),
});
console.log(newAr);
looper();
};
let index = 0; // counter / array index
const looper = () => {
let value = newAr[index++]; // always getting the next element (starting from 0).
console.log(value.one);
console.log(value.two);
console.log(value.three);
};
/***/
const button = document.querySelector("button");
button.addEventListener("click", () => {
pusher();
});
<button>Test</button>

how to add a localstorage for my Calculator?

I have to work on a calculator. I got everything i need. The only thing is, I have to add a LocalStorage under my Result. So the Calculator adds everytime the result, untill i delete the session.
For example:
"1+1=2," 2*2=4, 8/8=1
Localstorage: 2,4,1
function clear()
{
number1.value = "";
number2.value = "";
}
function clearresult()
{
result.innerText = '';
}
function calc()
{
var number1 = parseFloat(document.getElementById('number1').value);
var number2 = parseFloat(document.getElementById('number2').value);
var oper = document.getElementById('operators').value;
if ( !isNaN(number1) && !isNaN(number2) )
{
if ( oper === '+' )
{
result.innerText = document.getElementById('result').value = parseFloat(number1) + parseFloat(number2);
}
if ( oper === '-' )
{
result.innerText = document.getElementById('result').value = parseFloat(number1) - parseFloat(number2);
}
if ( oper === '/' && number1 )
{
result.innerText = document.getElementById('result').value = parseFloat(number1) / parseFloat(number2);
}
if ( oper === '*' )
{
result.innerText = document.getElementById('result').value = parseFloat(number1) * parseFloat(number2);
}
clear();
for (var i = 0; i < localStorage.length; i++)
{
localStorage.setItem('resultstorage', result.innerText);
output.innerText = localStorage.getItem('resultstorage');
}
}
else
{
alert("Es wurden keine Zahlen eingegeben!");
clear();
clearresult();
}
}
*store your result in array and store that array in localstorage as mentioned below
let itemsArray = []
localStorage.setItem('items', JSON.stringify(itemsArray))
const data = JSON.parse(localStorage.getItem('items'))
putting new result in array
itemsArray.push(input.value)
localStorage.setItem('items', JSON.stringify(itemsArray))
remove array from local storage
localStorage.clear()
I think the solution below will go a long way into helping you out
- The use of default variables may make code verbose, remove at wish.
// saves the result and update DOM with it accordingly
const saveResult = function (result, storageName = 'resultstorage') {
let store = []
store.push(result)
localStorage.setItem(storageName, JSON.stringify(store))
// update DOM with value
getResult()
}
// using try-catch statement ensures we did not get an error
// if - say no value is in the localStorage
// And it can enable us to retrieve the last result in memory on page-load
// if peradventure we exited the browser without removing the item from localStorage
// i.e we can call getResult() without error
const getResult = function (storageName = 'resultstorage') {
let result;
try {
result = JSON.parse(localStorage.getItem(storageName))
document.querySelector('#output').innerHTML = result
} catch (err) {}
}
// we use **remove** not **clear** and the storage name
// to avoid removing other values unintended
const removeResult = (storageName = 'resultstorage') => localStorage.removeItem(storageName)
// usage
let value = 23
saveResult(value)

Protractor - X is not a function

In Protractor I'm trying to run a function from another page inside my spec file.
My spec file:
let TablePage = require("./../pages/TablePage");
let table_page = new TablePage();
let protractor = require("protractor");
let browser = protractor.browser;
describe('Login', function() {
beforeEach(function() {
browser.ignoreSynchronization = true;
browser.waitForAngular();
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
browser.get("/budget");
});
it('should get values from list', function(){
table_page.getPriceValuesFromList();
});
The other file form which i get the function (TablePage.js):
let protractor = require("protractor");
let browser = protractor.browser;
let number = 0;
let prices = [];
let TablePage = (function () {
function TablePage() {
}
TablePage.prototype.getPriceValuesFromList = function () {
for (number = 1; number < 100; number++) {
let locator = '//*[#id="root"]/main/section/table/tbody/tr[' + number + ']/td[3]/div[2]';
browser.findElement(By.xpath(locator)).then(function (err) {
prices[number] = element(By.xpath(locator)).getText();
console.log(prices[number])
}, function (err) {
if (err) {
break;
}
})
}
};
return TablePage;
});
module.exports = TablePage;
I get an error: table_page.getPriceValuesFromList is not a function
Do you know what's wrong? I was doing it this way in the other project and it was working.
The real typeof() this function is undefined
You can also check if the function will work - it should get values from one row of the table, save it in array and go to the next row until the value inside row is not found - Save values form the column
There are a couple of lines which shouldn't be there. TablePage should be defined as follows:
function TablePage() { }
// Removed lines which were here.
TablePage.prototype.getPriceValuesFromList = function () {
for (number = 1; number < 100; number++) {
let locator = '//*[#id="root"]/main/section/table/tbody/tr[' + number + ']/td[3]/div[2]';
browser.findElement(By.xpath(locator)).then(function (err) {
prices[number] = element(By.xpath(locator)).getText();
console.log(prices[number])
}, function (err) {
if (err) {
break;
}
})
}
};
// And removed the return TablePage();
As an object orientalist I prefer implementation using classes:
class TablePage {
getPriceValuesFromList() {
for (number = 1; number < 100; number++) {
let locator = '//*[#id="root"]/main/section/table/tbody/tr[' + number + ']/td[3]/div[2]';
browser.findElement(By.xpath(locator)).then(function (err) {
prices[number] = element(By.xpath(locator)).getText();
console.log(prices[number])
}, function (err) {
if (err) {
break;
}
})
}
};
};

Access array in if statement

I have JavaScript calculator wherein I have defined two arrays as follows:
var degInc, degArr = [];
var radInc, radArr = [];
var PI = Math.PI;
var radStart = (-91*PI/2), radEnd = (91*PI/2);
for (degInc = -8190; degInc <= 8190; degInc+=180) {
degArr.push(degInc);
}
for (radInc = radStart; radInc <= radEnd; radInc+=PI) {
var radIncFixed = radInc.toFixed(8);
radArr.push(radIncFixed);
}
to be used in conjunction with the tangent function (below) so as to display a value of Undefined in an input (HTML below) should the user attempt to take the tangent of these values (I have included other relavent function as well):
Input -
<INPUT NAME="display" ID="disp" VALUE="0" SIZE="28" MAXLENGTH="25"/>
Functions -
function tan(form) {
form.display.value = trigPrecision(Math.tan(form.display.value));
}
function tanDeg(form) {
form.display.value = trigPrecision(Math.tan(radians(form)));
}
function radians(form) {
return form.display.value * Math.PI / 180;
}
with jQuery -
$("#button-tan").click(function(){
if (checkNum(this.form.display.value)) {
if($("#button-mode").val() === 'DEG'){
tan(this.form); // INSERT OTHER 'if' STATEMENT HERE FOR RAD ARRAY
}
else{
tanDeg(this.form); // INSERT OTHER 'if' STATEMENT HERE FOR DEG ARRAY
}
}
});
I would like to incorporate an array check within the .click function such that if the user input is contained in the array (degArr or radArr depending on the mode), the calculator returns Undefined. Now, I know how to display Undefined in the input display ($('#disp').val('Undefined')), but I cannot figure out how to configure an if statement that checks the relevant array. Is there a way to do so within the #button-tan function where I have commented?
Loop through the arrays on click and set a variable if you find a matched value.
You can do something like this:
$("#button-tan").click(function(e) {
e.preventDefault();
var userInput = $('#disp').val();
var buttonMode = $('#button-mode').val();
var displayVal = '';
if (buttonMode === 'DEG') {
var radFound = false;
radArr.forEach(function(item) { // changed from degArr
if (item === userInput) {
radFound = true;
}
if (radFound) {
displayVal = 'undefined';
} else {
tan(this.form);
}
});
} else {
var degFound = false;
degArr.forEach(function(item) {
if (item === userInput) {
degFound = true;
}
if (degFound) {
displayVal = 'undefined';
} else {
tanDeg(this.form);
}
});
}
});
You could create a simple object of a Calculator class, which keeps a reference to these arrays, and use like this. I changed some methods to receive the input as parameter rather than form.
$(function () {
function Calculator()
{
var degInc;
this.degArr = [];
var radInc;
this.radArr = [];
var PI = Math.PI;
var radStart = (-91*PI/2);
var radEnd = (91*PI/2);
for (degInc = -8190; degInc <= 8190; degInc+=180) {
this.degArr.push(degInc);
}
for (radInc = radStart; radInc <= radEnd; radInc+=PI) {
var radIncFixed = radInc.toFixed(8);
this.radArr.push(radIncFixed);
}
}
var calc = new Calculator();
function tan(input) {
alert("tan called");
var value = Math.tan(input.value);
alert("tan called. value: " + value);
input.value = value;
}
function tanDeg(input) {
alert("tanDeg called");
var value = Math.tan(radians(input));
alert("tanDeg called. value: " + value);
input.value = value;
}
function radians(input) {
alert("radians called");
var value = input.value * Math.PI / 180;
alert("radians called. value: " + value);
return value;
}
$("#button-tan").click(function(){
alert (calc.degArr);
alert (calc.radArr);
var displayInput = $("#disp");
alert("user input: " + displayInput.val());
if (!isNaN(displayInput.val()))
{
if($("#button-mode").val() === 'DEG')
{
if (calc.radArr.indexOf(displayInput.val()) > -1)
{
alert("user input is in radArr");
}
else
{
alert("user input IS NOT in radArr");
tan(displayInput);
}
}
else
{
if (calc.degArr.indexOf(displayInput.val()) > -1)
{
alert("user input is in degArr");
}
else {
alert("user input IS NOT in degArr");
tan(displayInput);
}
}
}
else
alert("Not a number in input");
});
});
If you wanna do some tests, I created a JSFiddle demo here. Type -8190 in the first input, then click the button. It's gonna be inside the array. Then try typing "DEG" in the second input and clicking again, you'll notice code will check against another array (due to IFs). I couldn't make your auxiliar functions to calculate a value, but I think this helps you with your initial problem.
indexOf should work...
$("#button-tan").click(function(){
if (checkNum(this.form.display.value)) {
if($("#button-mode").val() === 'DEG'){
if (radArr.indexOf(Number(this.form)) > -1) {
$('#disp').val('Undefined');
} else {
tan(this.form);
}
}
else{
if (degArr.indexOf(Number(this.form)) > -1) {
$('#disp').val('Undefined');
} else {
tanDeg(this.form);
}
}
}
});

Categories