trouble getting variable to display using .innerHTML - javascript

HTML:
<input type="number" id="input" placeholder="Number.." onkeydown="javascript:
return event.keyCode === 69 ? false : true"/>
<div class="boxes">
<div class="decimalBox">
<p>Decimal:
<span id="decimalOutput"></span>
</p>
</div>
<div class="binaryBox">
<p>Binary:
<span id="binaryOutput"></span>
</p>
</div>
Javascript:
//global variables
var number = document.getElementById('input');
var decimalOutput = document.getElementById('decimalOutput');
var binaryOutput = document.getElementById('binaryOutput');
number.addEventListener("input", toBinary);
//Converting Decical to Binary by using independent division and taking the
modulus the number
function toBinary(x){
var result = [], i;
for(var i=number;i>0;i=parseInt(i/2)){
result.push(i%2);
}
var binary = result.reverse().join('');
//returns the result of the array and then reverses the order to create the
correct binary order.
decimalOutput.innerHTML = number.value;
binaryOutput.innerHTML = binary;
return binary;
}
My question is this. Everything is working except for me being able to display the binary variable declared in the toBinary() Function. It seems to throw errors and not allow me to actually use that value to display the current input in binary form, however I tested this using parameters and the code runs just fine. I just need help figuring out why this specific case won't work.
Correct way to fix this was #titus suggestion: instead of having "var i = number" in the for loop change it to the value or number. Thanks!

Related

I'm trying to use parseint but it does not work

I'm writing a script and I want a H1 tag to increase with an input's value. But it doesn't work. I'm probably dumb, but I'm here cause I want help.
This is my code:
var h1Value = 0;
function addFun() {
var changeH1By = document.getElementById('input').value;
parseInt('h1Value') + parseInt('changeH1By');
document.getElementById('h1').innerHTML = h1Value;
}
<h1 id="h1">0</h1>
<input type="number" id="input" value="1">
<button onclick="addFun()">Add</button>
As you probably see I'm using parseInt(), because else the h1 was "11". Like 1 + 1 = 11? Am I using the parseInt wrong or is something else wrong?
Thank you!
You were passing an string into parseInt, remove the quotes to pass the variable.
You didn't assign the result of parseInt('h1Value') + parseInt('changeH1By');to any variable
Instead off keeping track of var h1Value, lets use document.getElementById('h1').innerHTML to get the current value
Removed newValue so we can set the new value instant as innerHTML
function addFun() {
var currentvalue = document.getElementById('h1').innerHTML;
var changeH1By = document.getElementById('input').value;
document.getElementById('h1').innerHTML = parseInt(currentvalue) + parseInt(changeH1By);
}
<h1 id="h1">0</h1>
<input type="number" id="input" value="1">
<button onclick="addFun()">Add</button>
You're passing the strings "h1Value" and "changeH1By" to parseInt and it's trying to parse those literal strings to integers. If you try logging the result of e.g. parseInt("h1Value") it evaluates to NaN, i.e. "not a number", which would give you a hint of where you're going wrong.
A working version of your code would be
var h1Value = 0;
function addFun() {
var changeH1By = document.getElementById('input').value;
h1Value = h1Value + parseInt(changeH1By);
document.getElementById('h1').innerHTML = h1Value;
}
The type of h1Value is already a number, so it doesn't need to be coerced into one, and instead of calling parseInt with the literal string "changeH1By", you'll need to give the actual variable as an argument. Also the line
parseInt('h1Value') + parseInt('changeH1By');
doesn't do anything by itself, the javascript engine will just compute the value and throw it away, as you're not saving it into a variable etc.
A clean way for coding that...
<input..> elements of type="number" have a valueAsNumber property
use const to avoid repeating the results of these interpretations
const
h1_element = document.getElementById('h1')
, changeH1By = document.getElementById('input')
;
function addFun()
{
h1_element.textContent = changeH1By.valueAsNumber
+ parseInt(h1_element.textContent)
}
<h1 id="h1">0</h1>
<input type="number" id="input" value="1">
<button onclick="addFun()">Add</button>

Return or highlight only new values in textarea

I am stuck in one of the tricky problem. I have a textarea having some strings already in it. What I am trying is, when the user put new values in the textarea, they should be displayed highlighted (green), only the new ones, the old ones should remain colorless. And if the user removes the strings from the textarea, the removed values should be highlighted as red. I am using plain JS and HTML. What I have tried is below.
function f() {
var checkBox = document.getElementById('checkbox');
var scopeResult = document.getElementById('scopeResult');
var scopes = document.getElementById('scopes').value;
if (checkBox.checked === true) {
scopeResult.style.display = 'block';
addOrRemoveScope(scopes);
} else {
scopeResult.style.display = 'none';
}
}
function addOrRemoveScope(val) {
document.getElementById("scopeResult").innerHTML = val.replace(/(?:\\[rn]|[\r\n])/g, ",<br/>");
}
<textarea id="scopes" class="form-control" field="*{scope}" rows="10" maxlength="4096" onchange="addOrRemoveScope(this.value)">
</textarea>
<input id="checkbox" type="checkbox" required onclick="f()" />
<label for="checkbox"> Are you sure, you want to modify the scopes?*</label><br>
<p id="scopeResult" style="display: none; background-color: #5cb85c"></p>
Thanks!
replace(/(?:\\[rn]|[\r\n])/g, ",<br/>") is not going to help solve the problem.
Really you should look into a robust lib that does text diff, but to answer.
Based entirely on the position of the value compared to the original value.
When the user put new values in the textarea, they should be displayed
highlighted (green), only the new ones.
New values can replace old ones, so I would opt in to making them red, and new new values would be green, essentially any new value longer then the original string length is green everything else is treated as changed, which would be red
The old ones should remain colourless. And if the user removes the
strings from the textarea, the removed values should be highlighted as
red.
Easy enough if is all based on position. As said if you want something more robust look into using a lib. Or use something like the following:
Split the original string and new value into arrays, then loop over original string char by char and if is the same, then dont apply styling, if it's not the same then treat as changed (red), if it does not exist in new array then its deleted, so use the original char as the value.
Then use slice to pick only the new chars in the new value as they will be all new, then join both together.
let original = document.getElementById('input').value;
function process() {
let letters_original = [...original]
let letters_current = [...document.getElementById('input').value]
let b = letters_original.map(
(v, i) => letters_current[i] === v ? v : `<span style="color:red">${letters_current[i] || v}</span>`
)
let c = letters_current.slice(b.length).map(
v => `<span style="color:green">${v}</span>`
)
document.getElementById("output").innerHTML = [...b, ...c].join('')
}
<textarea id="input" rows="10" maxlength="4096" oninput="process()">123</textarea>
<p id="output"></p>

Values not being returned in JS

I have a value separated by commas. The code is as follows:
function addComma(values) {
const v = values.value && new Number(values.value.replace(/,/g, ''));
values.value = v.toLocaleString();
}
if (document.getElementById("values"))
var pay = document.getElementById("values").value;
payment = pay.replace(/\,/g, '');
<label>Rent</label> <input style="font-size:10px;width:80px;text-align:right" id="values" type="text" onkeyup="addComma(this);">
Issue:
if (selectedPayType === "A") {
PV = getNPV(rate, array, payment) + payment;
console.log("PV);
}
For some reason, PV returns the value but it doesn't add the +payment. But, instead of +payment, if i use the numeric value itself ex: 10000, then it adds the value up.
I tried debugging and it is taking the payment value inside the getNPV however, not adding it up which is really weird. Not sure what i am doing wrong here. Any help is appreciated. Thank you.
The main problem is that you are adding a string to a number . For eg: 1 + '2' = '12'. So you need to convert your payment which is a string, into a number.
Do not use Number constructor as it might cause unwanted results, but use parseFloat or parseInt to convert numeral strings into numbers.
p.s. for parseInt you should/need to specify a radix .
Useful links
parseInt()
parseFloat()
why avoid creating object versions of primitives
Changed a bit the structure ( added the if inside the addComma function that is called onkeyup )
See below
function addComma(values) {
const v = values.value && parseFloat(values.value.replace(/,/g, ''));
values.value = v.toLocaleString();
if (document.getElementById("values")) {
var pay = document.getElementById("values").value;
payment = pay.replace(/\,/g, '');
PV = 10 + parseFloat(payment);
console.log(PV);
}
}
<label>Rent</label> <input style="font-size:10px;width:80px;text-align:right" id="values" type="text" onkeyup="addComma(this);">

my function() is not working or the value is not converting to a number

Been stuck here ALL day long trying to figure out what is wrong with my syntax.
Here’s my code… I’d like to verify if Number1 is > than Number 2. However, whenever I tried to run the code I always getting false.
Please help me..
PS. I am new to coding :(
var num1 = document.getElementById('num1');
var num2 = document.getElementById('num2');
var x = Number(num1);
var y = Number(num2);
function higherThan(x, y){
x > y? alert(true) : alert(false);
}
Numb1: <input type="number" id="num1"><br>
Numb2: <input type="" id="num2"><br>
<button onclick="higherThan();">Is Higher Than?</button>
Get the values of the inputs inside the function.In your case you are trying to get the value even before user have provided any input.
Also to get the value you need to do
document.getElementById('elemId').value
function higherThan(x, y) {
var num1 = document.getElementById('num1').value;
var num2 = document.getElementById('num2').value;
var x = Number(num1);
var y = Number(num2);
x > y ? alert(true) : alert(false);
}
Numb1:
<input type="number" id="num1">
<br> Numb2:
<input type="" id="num2">
<br>
<button onclick="higherThan();"> Is Higher Than ?</button>
a few things:
you are not passing anything to your higherThan() function when you call it, but you have defined higherThan() as requiring two arguments.
I'm not convinced you that num1 and num2 are actually numbers. I would use some console logs to verify that you are a.) getting something back here and b.) that what you are getting back is a number not a string. You may need to use parseInt as obviously you can't math with strings.
What is happening here? var x = Number(num1); the way this is written it looks like you are calling a function? where is this function defined?
I would test your code in jsfiddle or browser console first and verify it works before trying to embed it in a webpage.
You have to take the value from the control. You can pass the id's of the control's to refer that inside the function for getting the values. Try the following way:
function higherThan(n1, n2){
var x = Number(document.getElementById(n1).value);
var y = Number(document.getElementById(n2).value);
var res = x > y? true : false;
alert(res);
}
Numb1: <input type="number" id="num1"><br>
Numb2: <input type="" id="num2"><br>
<button onclick="higherThan('num1','num2');">Is Higher Than?</button>

How to get JavaScript running properly on mobile phones?

(http://www.learnwithjesse.com/white-hmong-to-green-hmong-converter/).
I have JavaScript that utilizes two HTML <textarea> elements, one for input values and one for output values. Input values are converted a different word and is outputted to the output box. For example, if I type in the word 'daj' in the input box and click on the convert button, it should output the converted word 'dlaaj' to the output box. It works fine in Chrome, Firefox, and Internet Explorer, but not on my Galaxy S5 Active; it outputs the same word I put in the input box. 'daj' still outputs 'daj'.
What I've tried so far: I've tried running on different phones, iPhone5, it doesn't output correctly. I've tried running the script on http://mobiletest.me which makes my computer act like mobile phone using Galaxy S5 and it runs properly.
How can I get it to output properly on mobile phones?
<p class="welcome" id="greeting">White Hmong to Green Hmong Converter</p>
<p class="content">
</p>
<form>
<input type="button" value="Convert White Hmong to Green Hmong" onClick="clicked(0)" /><input type="button" value="Converter Green Hmong to White Hmong" onClick="clicked(1)" />
<br>
<br>
<textarea rows="7" cols="68" id="whiteHmongInput" >
Input</textarea>
<br>
<br>
<textarea rows="7" cols="68" id="greenHmongInput" >
Output</textarea>
</form>
<script>
function clicked(number) {
var n = -1;
var list = [];
var list2 = [];
var NUMBERWORDS = 90;
list[0] ="cab";
list[1] ="cia";
list[2] ="dab";
list[3] ="daj";
list[4] ="dej";
list[5] ="dev";
list[6] ="dib";
list[7] ="duab";
list[8] ="fiav";
list[9] ="hais";
list[10] ="hla";
list[11] ="hlab";
list[12] ="hlad";
list[13] ="hmaim";
list[14] ="hmaiv";
list[15] ="hmaj";
list[16] ="hmaiv";
list[17] ="hmob";
list[18] ="hmog";
list[19] ="hmoo";
list[20] ="hmoob";
list[21] ="hmood";
list[22] ="hmoog";
list[23] ="hmoov";
list[24] ="hmos";
list[25] ="hmov";
list[26] ="hnas";
list[27] ="hnais";
list[28] ="hneev";
list[29] ="hnyab";
list[30] ="hnov";
list[31] ="iav";
list[32] ="kos";
list[33] ="liab";
list[34] ="liaj";
list[35] ="liam";
list[36] ="loos";
list[37] ="los";
list[38] ="mloos";
list[39] ="mus";
list[40] ="npib";
list[41] ="nqhaiv";
list[42] ="nyaiv";
list[43] ="pa";
list[44] ="pab";
list[45] ="pad";
list[46] ="pag";
list[47] ="pam";
list[48] ="piam";
list[49] ="piav";
list[50] ="qaib";
list[51] ="rhiam";
list[52] ="siab";
list[53] ="siav";
list[54] ="thab";
list[55] ="tiab";
list[56] ="tias";
list[57] ="tiav";
list[58] ="tsam";
list[59] ="tshaj";
list[60] ="txiav";
list[61] ="txiab";
list[62] ="vaj";
list[63] ="xa";
list[64] ="xaj";
list[65] ="xya";
list[66] ="yiag";
list[67] ="zaj";
list[68] = "txoj";
list[69] = "nco";
list[70] = "dua";
list[71] = "tus";
list[72] = "txog";
list[73] = "cas";
list[74] = "tos";
list[75] = "qab";
list[76] = "yaj";
list[77] = "pov";
list[78] = "niaj";
list[79] = "hmo";
list[80] = "hnub";
list[81] = "iab";
list[82] = "pom";
list[83] = "niaj";
list[84] = "Ziag";
list[85] = "ya";
list[86]= "tas";
list[87]= "nws";
list[88] = "rau";
list[89] = "li";
list2[0] ="caab";
list2[1] ="ca";
list2[2] ="dlaab";
list2[3] ="dlaaj";
list2[4] ="dlej";
list2[5] ="dlev";
list2[6] ="dlib";
list2[7] ="dluab";
list2[8] ="fav";
list2[9] ="has";
list2[10] ="hlaa";
list2[11] ="hlaab";
list2[12] ="hlaad";
list2[13] ="maim";
list2[14] ="maiv";
list2[15] ="maaj";
list2[16] ="maiv";
list2[17] ="mob";
list2[18] ="mog";
list2[19] ="moo";
list2[20] ="moob";
list2[21] ="mood";
list2[22] ="moog";
list2[23] ="moov";
list2[24] ="mog";
list2[25] ="mov";
list2[26] ="naag";
list2[27] ="nais";
list2[28] ="neev";
list2[29] ="nyab";
list2[30] ="nov";
list2[31] ="av";
list2[32] ="kaus";
list2[33] ="lab";
list2[34] ="laj";
list2[35] ="lam";
list2[36] ="loog";
list2[37] ="lug";
list2[38] ="noog";
list2[39] ="moog";
list2[40] ="pib";
list2[41] ="qhav";
list2[42] ="yav";
list2[43] ="paa";
list2[44] ="paab";
list2[45] ="paad";
list2[46] ="paag";
list2[47] ="choj";
list2[48] ="puag";
list2[49] ="pav";
list2[50] ="qab";
list2[51] ="rag";
list2[52] ="sab";
list2[53] ="sav";
list2[54] ="hab";
list2[55] ="tab";
list2[56] ="tag";
list2[57] ="tav";
list2[58] ="tsaam";
list2[59] ="tshaaj";
list2[60] ="txav";
list2[61] ="txab";
list2[62] ="vaaj";
list2[63] ="xaa";
list2[64] ="xaaj";
list2[65] ="xyaa";
list2[66] ="yag";
list2[67] ="zaaj";
list2[68] = "txuj";
list2[69] = "ncu";
list2[70] = "dlua";
list2[71] = "tug";
list2[72] = "txug";
list2[73] = "caag";
list2[74] = "tog";
list2[75] = "qaab";
list2[76] = "yaaj";
list2[77] = "puv";
list2[78] = "naj";
list2[79] = "mo";
list2[80] = "nub";
list2[81] = "ab";
list2[82] = "pum";
list2[83] = "naj";
list2[84] = "Zag";
list2[85] = "yaa";
list2[86]= "tag";
list2[87]= "nwg";
list2[88] = "rua";
list2[89] = "le";
var s = document.getElementById("whiteHmongInput").value;
var choppedIntoLines = s.split(/\r\n|\r|\n/g);
var choppedIntoWords;
//Splits Lines Into Words
document.getElementById("greenHmongInput").value ="";
for(var i = 0; i < choppedIntoLines.length; i++) {
choppedIntoWords = choppedIntoLines[i].split(" ");
//Splits each Line to words, then match words to see if white hmong if so convert to green word
for(var o = 0; o < choppedIntoWords.length; o++) {
choppedIntoWords[o].toLowerCase();
if (number == 0){
n = list.indexOf(choppedIntoWords[o].valueOf()); //tries to find the index of a word if i exist, returns -1 if it doesn't
if ( n != -1){
choppedIntoWords[o] = list2[n];
}
n = -1; //Basically if n = -1 it means the white hmong word coulnd't be found.
}
if (number == 1 ){
n = list2.indexOf(choppedIntoWords[o].valueOf()); //tries to find the index of a word if i exist, returns -1 if it doesn't
if ( n != -1){
choppedIntoWords[o] = list[n];
}
n = -1; //Basically if n = -1 it means the white hmong word couldn't be found.
}
}
//Recombines words to line of Words.
choppedIntoLines[i] = "";
for (var p = 0; p < choppedIntoWords.length; p++) {
choppedIntoLines[i] += choppedIntoWords[p] + " ";
}
//Recombines lines and Output to Green Hmong Section
document.getElementById("greenHmongInput").value += choppedIntoLines[i]+"\n";
}
}
</script>
I suspect the reason your code is not working on mobile is not because of the mobile browser, but the keyboard on your mobile device. Most mobile keyboards will automatically capitalize the first letter you type, so when you type daj in it automatically comes out Daj.
There is a bug in the code that prevents it form working with words that have any capital letters.
Fixing the current code
The line choppedIntoWords[o].toLowerCase(); does nothing. In JavaScript strings are immutable, toLowerCase does not alter the string, it returns a new string. Since you never assigned the result of toLowerCase to a variable, the result was immediately discarded.
The quick fix would be to just assign the result of toLowerCase to the array element you are calling it on: choppedIntoWords[o] = choppedIntoWords[o].toLowerCase();.
Better yet, move the toLowerCase call into the comparison, leaving the original value untouched, this will preserve the capitalization of any words that are not being replaced.
list.indexOf(choppedIntoWords[o].toLowerCase()) // .valueOf() is not needed here
(Another subtle bug, word 84 in the arrays (Ziag/Zag), both words are capitalized which will screw up the comparisons even after the toLowerCase bug is fixed.)
That said, I would rewrite it to work a little differently to make it more maintainable.
A better way of doing it
Instead of trying to keep two lists of words in sync, it would be much easier to store the word pairs as two-element arrays inside of another array. This way when adding/removing/editing any of the words you can do it all in one place.
At run-time, you could then generate two objects to act as look-up tables for the white-to-green and green-to-white conversions. Using these objects to look up the conversions should also be much faster than doing .indexOf on an array. In this particular situation, efficiency probably does not matter that much but it is a bonus that the conversion will happen (ever so slightly) faster.
<p class="welcome" id="greeting">White Hmong to Green Hmong Converter</p>
<p class="content">
</p>
<form>
<button type="button" id="white-to-green">Convert White Hmong to Green Hmong</button>
<button type="button" id="green-to-white">Convert Green Hmong to White Hmong</button>
<br>
<br>
<textarea rows="7" cols="68" id="input" placeholder="Type in Hmong words here"></textarea>
<br>
<br>
<textarea rows="7" cols="68" id="output" placeholder="Converted words will appear here"></textarea>
</form>
<script>
// Storing the white and green words in a single array that made up of
// two-element arrays containing each word pair will be much more
// maintainable than trying to keep two different lists in sync.
var hmongWords = [
// white first, green second
["cab", "caab"],
["cia", "ca"],
["dab", "dlaab"],
["daj", "dlaaj"],
// ...
["tas", "tag"],
["nws", "nwg"],
["rau", "rua"],
["le", "li"]
],
// these objects will act as look-up tables for the conversions
whiteToGreen = {},
greenToWhite = {},
elInput = document.getElementById("input"),
elOuput = document.getElementById("output"),
elWhiteToGreen = document.getElementById("white-to-green"),
elGreenToWhite = document.getElementById("green-to-white"),
convert = function (text, lookupTable) {
var lines = text.split(/\r\n|\r|\n/),
processWord = function (word) {
// Look for the word in the look up object.
// If the object has a property that is the word we are looking for,
// that value will be returned. If the word is not in the look-up
// object, undefined is returned. Since undefined is falsey the
// second half of the or statement will return the original word
return lookupTable[word.toLowerCase()] || word;
},
processLine = function (line) {
// Split the line up based on whitespace and process them,
// join the resulting array with spaces and return the converted line
return line.split(/\s/).map(processWord).join(' ');
};
// Map will return a new array of lines that have been processed by
// processLine. Join the new lines with a newline and return the string
return lines.map(processLine).join('\n');
},
convertWhiteToGreen = function (text) {
// just calls convert with the whiteToGreen look-up object
return convert(text, whiteToGreen);
},
convertGreenToWhite = function (text) {
// just calls convert with the greenToWhite look-up object
return convert(text, greenToWhite);
},
makeListener = function (converter) {
// this returns a function that will be used as an event listener
return function () {
// grab text from the input box, runs it through the
// converter function that was provided when makeListener was called
// and puts the output into the output box
elOuput.value = converter(elInput.value);
};
};
// build the look-up tables
hmongWords.forEach(function (wordPair) {
whiteToGreen[wordPair[0]] = wordPair[1];
greenToWhite[wordPair[1]] = wordPair[0];
});
// Attach the event listeners to the buttons.
// makeListener returns a function that uses the function you pass to it
// to convert the text.
elWhiteToGreen.addEventListener('click', makeListener(convertWhiteToGreen), false);
elGreenToWhite.addEventListener('click', makeListener(convertGreenToWhite), false);
</script>
You can see my version in action here
My code uses the forEach and map methods to loop over the arrays that split creates instead of for loops. This avoids the need for a counter variable and instead allows us to provide each item in the array a meaningful name (word, line, etc) instead of referring to an item in the array by its index.
Something else you might notice is that the convert function uses the logical or (||) operator. The logical or statement short-circuits if the first operand is truthy. So if a value is found in the look-up object, it is returned. If the value is not found in the object the second operand, the original word is returned. You have to be careful when using this technique in some situations, for instance when a valid option might be falsy such as 0 or an empty string. But in this situation lookupTable[word.toLowerCase()] will either return a non-empty string, which is always truthy or undefined which is always falsy.
You might have noticed that I used the words "truthy" and "falsy" instead of true and false this has to do with how implicit type conversion is handled in JavaScript. If something is "truthy" it will be converted to true when in a context that a Boolean value is needed. Likewise "falsy" values are values that will be converted to false in a context where a Boolean value is needed.
In the HTML instead of putting the placeholder text as a value in the textareas, I used the placeholder attribute.
Here are a few articles that might help understanding some of the techniques I've used if they are new to you:
Truthy and Falsy: When All is Not Equal in JavaScript
JavaScript quirk 1: implicit conversion of values
Functions are first class objects in javascript
Tidying Up a JavaScript Application with Higher-Order Functions
Exploring JavaScript’s Logical OR Operator
Another thing I used in my code but didn't discus is closures. They are a kind of big and important topic in JavaScript here is some stuff to help with them:
Closing The Book On Javascript Closures
(videos) Stuart Langridge: Secrets of JavaScript Closures part 1, part 2
Advanced JavaScript: Namespaces, Closures, Self-Invoking Functions, and much, much more…

Categories