Why I can only get the default value from the input? - javascript

I'm super new to JS, and I was writing this little function that supposed to take whatever input from the user and wrap the text at the length of the longest word. All things went well, except I can only get the default value of the input, not the real text someone put there.
My code is:
var inputString = document.getElementById("input").value;
var inputArray = inputString.split(" ");
var outputEl = document.getElementById("output");
// find the number of letters in the longest word:
function longest(inputString) {
let longestWord = 0;
for (var i = 0; i < inputArray.length; i++) {
if (longestWord < inputArray[i].length) {
longestWord = inputArray[i].length
}
}
return longestWord
}
var numberOfLetters = longest(inputString);
// wrap the text
function wrap(input, numberOfLetters) {
let lineLength = 0;
for (var i = 0; i < inputArray.length; i++) {
if (lineLength + inputArray[i].length <= numberOfLetters) {
outputEl.innerHTML += inputArray[i] + " ";
lineLength += inputArray[i].length + 1 // because there's a space
} else {
outputEl.innerHTML += "<br>" + inputArray[i] + " ";
lineLength = inputArray[i].length + 1 // space
}
}
}
<h3>Text Wrapper</h3>
<p id="instructions">We will break your text at the length of your longest word!</p>
<p>Enter Text: <input type="text" id="input" value="put your text here" size='50'></p>
<button onclick="wrap(input.value,numberOfLetters)">Yeah, click me</button>
<p id="output"></p>
if I type input.value in the console, it returns the value I put into; but if I ask for inputString it returns the default value.
I just don't know what's went wrong here? Can somebody help me?
Sorry if it's a stupid mistake, I just couldn't figure it out. Thanks in advance!

welcome to stackoverflow!
as the comments suggest, you need to set your variable values based on the current value of the input. your current code sets the variables at load-time, and so they get set to the default value and stay that way. try:
var outputEl = document.getElementById("output");
// find the number of letters in the longest word:
function longest(inputArray) {
let longestWord = 0;
for (var i = 0; i < inputArray.length; i++) {
if (longestWord < inputArray[i].length) {
longestWord = inputArray[i].length
}
}
return longestWord
}
// wrap the text
function wrap(inputString) {
var inputArray = inputString.split(" ");
var numberOfLetters = longest(inputArray);
let lineLength = 0;
for (var i = 0; i < inputArray.length; i++) {
if (lineLength + inputArray[i].length <= numberOfLetters) {
outputEl.innerHTML += inputArray[i] + " ";
lineLength += inputArray[i].length + 1 // because there's a space
} else {
outputEl.innerHTML += "<br>" + inputArray[i] + " ";
lineLength = inputArray[i].length + 1 // space
}
}
}
<h3>Text Wrapper</h3>
<p id="instructions">We will break your text at the length of your longest word!</p>
<p>Enter Text: <input type="text" id="input" value="put your text here" size='50'></p>
<button onclick="wrap(document.getElementById('input').value)">Yeah, click me</button>
<p id="output"></p>
notice that i moved all the variable instantiation to inside the wrap function. i changed the 'longest' function to accept inputArray as its argument, since that's what it's actually using (not inputString) -- this way it doesn't need a global variable. also i made sure wrap call in the button onclick was identifying the input by its id and pass value, then the 'wrap' function needs only this inputString in order to do its process.

The script block only executes once and that's why you always get the same value when clicking the button. Moving it to the callback function(which executes every time you click) fixes this problem. Here's the working example of what you need:
<body>
<h3>Text Wrapper</h3>
<p id="instructions">We will break your text at the length of your longest word!</p>
<p>Enter Text: <input type="text" id="input" value="put your text here" size='50'></p>
<button onclick="wrap(input.value)">Yeah, click me</button>
<p id="output"></p>
<script>
// find the number of letters in the longest word:
function longest(inputString){
var inputArray = inputString.split(" ");
let longestWord = 0;
for (var i = 0; i < inputArray.length; i++ ) {
if (longestWord < inputArray[i].length) {
longestWord = inputArray[i].length
}
}
return longestWord
}
// wrap the text
function wrap(inputString) {
var numberOfLetters = longest(inputString);
var inputArray = inputString.split(" ");
var inputString = document.getElementById("input").value;
var outputEl = document.getElementById("output");
let lineLength = 0;
for (var i = 0; i < inputArray.length; i++) {
if (lineLength + inputArray[i].length <= numberOfLetters){
outputEl.innerHTML += inputArray[i] + " ";
lineLength += inputArray[i].length + 1 // because there's a space
} else {
outputEl.innerHTML += "<br>" + inputArray[i] + " ";
lineLength = inputArray[i].length + 1 // space
}
}
}
</script>
</body>

Related

Is there a way to use for loops to display quotients and products of array numbers?

Need help with assignment. I need to create a button that uses a for loop to multiply each number in the array by the number after it into a second array and display the result. Lastly create another button that uses a while loop that divides each number in the array by the number after it into a third array and once more display the result. I have created a way to input numbers into an array "numbers" and display the array but do not know how to use for loops to display the quotient nor the product please help :(
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<input type="number" id="num" min="0" max="100">
<button onclick="myFunction()">Try it</button>
<button onclick="SortFunction()">Sort it</button>
<button onclick="AddFunction()">Add it</button>
<p id="demo"></p>
<script>
var myarray =[] ;
var text ;
function myFunction()
{
var fLen ;
var x = document.getElementById("num").value;
var i ;
myarray.push(Number(x));
fLen = myarray.length ;
text = "<ul>";
for (i = 0; i < fLen; i++)
{
text += "<li>" + myarray[i] + "</li>";
}
text += "</ul>";
document.getElementById("demo").innerHTML = text;
}
function SortFunction()
{
myarray.sort(function(a, b){return a - b});
document.getElementById("demo").innerHTML = myarray;
}
function AddFunction()
{
var sum = 0 ;
var fLen ;
var i ;
fLen = myarray.length ;
for (i = 0; i < fLen; i++)
{
sum = sum + Number(myarray[i]);
}
document.getElementById("demo").innerHTML = sum;
}
</script>
Well, simply you could add these buttons and try to create some special logic for each button inside relevant function, for example MultiplyNumbers() and DivideNumbers():
<button onclick="MultiplyNumbers()">Multiply pairs</button>
<button onclick="DivideNumbers()">Divide pairs</button>
In both functions firstly you should check if the main array has paired values via dividing length with 2 -> length % 2 == 0, then check if they're valid numbers with isNaN() function, if some value in pair is not valid you can define the result of this math equal 0 or what you want. Dividing function request also checking the second value in each pair with 0, cause you can't divide a number with zero(or you can).
So, the first function works via for loop, the second one via while loop.
The snippet below shows you this two functions, they're work correctly with this simple rules. If I've missed something you can tell me.
var myarray =[] ;
var text ;
function myFunction()
{
var fLen ;
var x = document.getElementById("num").value;
var i ;
myarray.push(Number(x));
fLen = myarray.length ;
text = "<ul>";
for (i = 0; i < fLen; i++)
{
text += "<li>" + myarray[i] + "</li>";
}
text += "</ul>";
document.getElementById("demo").innerHTML = text;
}
function SortFunction()
{
myarray.sort(function(a, b){return a - b});
document.getElementById("demo").innerHTML = myarray;
}
function AddFunction()
{
var sum = 0 ;
var fLen ;
var i ;
fLen = myarray.length ;
for (i = 0; i < fLen; i++)
{
sum = sum + Number(myarray[i]);
}
document.getElementById("demo").innerHTML = sum;
}
function MultiplyNumbers() {
let multNumbers = [];
if (myarray.length % 2 == 0){
let actions = myarray.length / 2;
for(let i = 0; i < actions; i++){
var tmult = (isNaN(myarray[i*2]) || isNaN(myarray[i*2+1])) ?
0 :
Number(myarray[i*2]) * Number(myarray[i*2+1]);
multNumbers.push(tmult);
}
document.getElementById("demo").innerHTML = multNumbers;
}
}
function DivideNumbers() {
let divNumbers = [];
if (myarray.length % 2 == 0){
let actions = myarray.length / 2;
let i = 0;
while(i<actions){
var tdiv = (isNaN(myarray[i*2]) || isNaN(myarray[i*2+1]) || Number(myarray[i*2+1]) == 0) ?
0 :
Number(myarray[i*2]) / Number(myarray[i*2+1]);
divNumbers.push(tdiv);
i++;
}
document.getElementById("demo").innerHTML = divNumbers;
}
}
<input type="number" id="num" min="0" max="100">
<button onclick="myFunction()">Try it</button>
<button onclick="SortFunction()">Sort it</button>
<button onclick="AddFunction()">Add it</button>
<button onclick="MultiplyNumbers()">Multiply pairs</button>
<button onclick="DivideNumbers()">Divide pairs</button>
<p id="demo"></p>
var myarray =[] ;
var text ;
function myFunction()
{
var fLen ;
var x = document.getElementById("num").value;
var i ;
myarray.push(Number(x));
fLen = myarray.length ;
text = "<ul>";
for (i = 0; i < fLen; i++)
{
text += "<li>" + myarray[i] + "</li>";
}
text += "</ul>";
document.getElementById("demo").innerHTML = text;
}
function SortFunction()
{
myarray.sort(function(a, b){return a - b});
document.getElementById("demo").innerHTML = myarray;
}
function AddFunction()
{
var sum = 0 ;
var fLen ;
var i ;
fLen = myarray.length ;
for (i = 0; i < fLen; i++)
{
sum = sum + Number(myarray[i]);
}
document.getElementById("demo").innerHTML = sum;
}
// updated code
var secondArray=[];
function multiplyFunction(){
var temp = document.getElementById("num").value;
for(i=0;i<myarray.length;i++){
secondArray.push(Number(temp) * myarray[i]);
}
// show new array ..
text = "<ul>";
for (i = 0; i < myarray.length; i++){
text += "<li>" + secondArray[i] + "</li>";
}
text += "</ul>";
document.getElementById("demo").innerHTML = text;
//
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<input type="number" id="num" min="0" max="100">
<button onclick="myFunction()">Try it</button>
<button onclick="SortFunction()">Sort it</button>
<button onclick="AddFunction()">Add it</button>
<button onclick="multiplyFunction()">Multiply</button>
<button onclick="divideFunction()">Divide</button>
<p id="demo"></p>
</body>
</html>

javascript count present i value with previous loop output value

function myFunction() {
var text = "";
var i;
for (i = 0; i <= 10; i++) {
text += + i + "<br>";
}
document.getElementById("demo").innerHTML = text;
}
<button onclick="myFunction()">Count</button>
<p id="demo"></p>
I want to add present i value into previous loop output value. This maybe a simple question. I have searched in google and stackoverflow. But, didn't get the desired result.
In above screenshot,
0 is the previous loop value + 1 is present i returns => 1
1 is the previous loop value + 2 is present i returns => 3
3 is the previous loop value + 3 is present i returns => 6
6 is the previous loop value + 4 is present i returns => 10
You need another persistent variable that keeps track of the last total that was concatenated with text:
function myFunction() {
var text = "";
var i;
var lastTotal = 0;
for (i = 0; i <= 10; i++) {
var newTotal = lastTotal + i;
text += + newTotal + "<br>";
lastTotal = newTotal;
}
document.getElementById("demo").innerHTML = text;
}
<button onclick="myFunction()">Count</button>
<p id="demo"></p>
(technically, you don't need the newTotal variable, but it makes the code's intent more clear)
You could also do this a bit more elegantly with reduce:
function myFunction() {
let text = '';
Array.from({ length: 11 }, (_, i) => i)
.reduce((lastTotal, i) => {
const newTotal = lastTotal + i;
text += newTotal + '<br>';
return newTotal;
}, 0);
document.getElementById("demo").innerHTML = text;
}
<button onclick="myFunction()">Count</button>
<p id="demo"></p>
You just need a second variable to hold the last value:
function myFunction() {
var text = "";
var sum = 0;
for (var i = 0; i <= 10; i++) {
sum += i;
text += sum + "<br>";
}
document.getElementById("demo").innerHTML = text;
}
<button onclick="myFunction()">Count</button>
<p id="demo"></p>
Keep a count of the last number:
function myFunction() {
var text = "";
var i;
var count = 0;
for (i = 0; i <= 10; i++) {
count += i;
text += count + "<br>";
}
document.getElementById("demo").innerHTML = text;
}
<button onclick="myFunction()">Count</button>
<p id="demo"></p>
You can use the function reduce to fill the operations and then use the function forEach to build the desired output.
function myFunction() {
var html = "";
Array.from({length: 10}, (_, i) => i + 1).reduce((a, c, i) => {
a[i] = (a[i - 1] || 0) + c;
return a;
}, []).forEach((n, i, arr) =>
(html += (arr[i - 1] || 0) + " + " + (i + 1) + " = " + n + "<br>"));
document.getElementById("demo").innerHTML = html;
}
<button onclick="myFunction()">Count</button>
<p id="demo"></p>
I think I'd just use an array so that you both have the previous sum, and can also use it with .join() for setting the HTML.
function myFunction() {
for (var i = 0, a = []; i <= 10; i++) {
a[i] = i + (a[i-1] || 0);
}
document.getElementById("demo").innerHTML = a.join("<br>");
}
<button onclick="myFunction()">Count</button>
<p id="demo"></p>

Loop that changes letter colors

The purpose is to change color of all characters in #text one by one, I made a loop:
function myFunction() {
var letters = document.getElementById('text');
for (var i = 0; i < letters.innerHTML.length; i++) {
//only change the one you want to
letters.innerHTML = letters.innerHTML.replace(letters[i], '<span style="color: yellow;">'+letters[i]+'</span>');
}
}
It doesnt work but also doesnt show any errors.
https://jsfiddle.net/zkbctk2h/
I suggest to store the text of the element with id = "text" and build a new string out of the old text, because replace would replace the first found character which may not the wanted character, because the replaced character cold contain a character which should not be replaced.
function myFunction() {
var letters = document.getElementById('text'),
text = letters.innerHTML
letters.innerHTML = '';
for (var i = 0; i < text.length; i++) {
letters.innerHTML += '<span style="background-color: yellow;">' + text[i] + '</span>';
}
}
myFunction();
<div id="text">abracadabra</div>
Some typewriter functionality with setInterval and clearInterval
function myFunction() {
var letters = document.getElementById('text'),
text = letters.innerHTML,
i = 0;
return function () {
var j;
if (i < text.length) {
letters.innerHTML = '';
for (j = 0; j <= i; j++) {
letters.innerHTML += '<span style="background-color: yellow;">' + text[j] + '</span>';
}
letters.innerHTML += text.slice(j);
i++;
} else {
clearInterval(interval);
}
}
}
var interval = setInterval(myFunction(), 500);
<div id="text">abracadabra</div>
This is because you are updating the letters, and reading the next letter afterwards. You should use innerText instead of innerHTML because then you only get the text.
Example fiddle: https://jsfiddle.net/zkbctk2h/25/
function myFunction() {
var letters = document.getElementById('text'),
str = letters.innerText,
newString = "";
for (var i = 0; i < str.length; i++) {
//only change the one you want to
newString += '<span style="color: yellow;">'+str[i]+'</span>';
}
letters.innerHTML = newString;
}
I suggest to read once and write once to the dom. If you read and write a force redraw is triggered in the browser. Therefor it can get slow if you have large text.
Just suggesting a more functional approach:
const myFunction = id =>
document.getElementById(id).innerHTML
.split('')
.map(c =>
`<span style="color: green;">${c}</span>`
)
.join('')
document.getElementById('text').innerHTML = myFunction('text')
<div id="text">Hello World</div>

Count amount of times a value is represented

i have some code that takes input numbers and put them into a new array. How can i make it so my alert tells the user how many times the number is represented in the input? Exampel 0,4,4,2,3,4,1 would show "0 appears 1 time, 4 appears 3 times" and so on...I think im close but cant get the final part right...
<!DOCTYPE html>
<html>
<head>
<title>Oppgave 5</title>
<script type="text/javascript">
window.onload = btn;
function btn() {
document.getElementById("btn").onclick = showTxt;
}
function showTxt() {
var text = "";
var input = document.getElementById("input").value;
var split = input.split(",");
var newArray = split;
var count = 0;
for (var i = 0; i < newArray.length; i++) {
if (newArray[i] === parseInt(input)) {
count++;
}
alert("Number " + newArray[i] + " appears " + count + " times");
}
text += newArray;
document.getElementById("print").innerHTML = text;
}
</script>
</head>
<body>
<input id="input" type="text">
<button id="btn" type="button">Show</button>
<p id="print"></p>
</body>
</html>
I have changed your showTxt function
function showTxt() {
var text = "";
var input = document.getElementById("input").value;
var split = input.split(",");
var newArray = split;
var count;
for (var i = 0; i < newArray.length; i++) {
count = 0;
for (var j = 0; j < newArray.length; j++) {
if (newArray[i] === newArray[j]) {
count++;
}
}
alert("Number " + newArray[i] + " appears " + count + " times");
}
text += newArray;
document.getElementById("print").innerHTML = text;
}
You could use the method from this gist like so:
window.onload = btn;
function btn() {
document.getElementById("btn").onclick = showTxt;
}
function showTxt() {
var text = "";
var input = document.getElementById("input").value;
var split = input.replace(/ /g, '').split(",").sort();
compressArray(split);
}
function compressArray(original) {
var compressed = [];
// make a copy of the input array
var copy = original.slice(0);
// first loop goes over every element
for (var i = 0; i < original.length; i++) {
var myCount = 0;
// loop over every element in the copy and see if it's the same
for (var w = 0; w < copy.length; w++) {
if (original[i] == copy[w]) {
// increase amount of times duplicate is found
myCount++;
// sets item to undefined
delete copy[w];
}
}
if (myCount > 0) {
var a = new Object();
a.value = original[i];
a.count = myCount;
compressed.push(a);
}
}
for (var i = 0; i < compressed.length; i++) {
var message = compressed[i].value + ' appears ' + compressed[i].count + ' times.';
alert(message);
document.getElementById("print").innerHTML += message + '</br>';
}
};
<input id="input" type="text">
<button id="btn" type="button">Show</button>
<p id="print"></p>
Check this out, may be it'll helpful .
<!DOCTYPE html>
<html>
<head>
<title>Oppgave 5</title>
<script type="text/javascript">
window.onload = btn;
function btn() {
document.getElementById("btn").onclick = showTxt;
}
function showTxt() {
var text = "";
var input = document.getElementById("input").value;
var split = input.split(",");
var newArray = split;
let countedValues = newArray.reduce(function(obj,val){
if(obj[val])
obj[val] += 1;
else
obj[val] = 1;
return obj
}, {})
for (let value in countedValues ) {
alert("Number " + value + " appears " + countedValues[value] + " times");
}
text = newArray;
document.getElementById("print").innerHTML = text;
}
</script>
</head>
<body>
<input id="input" type="text">
<button id="btn" type="button">Show</button>
<p id="print"></p>
</body>
</html>

Logics for store letter in correct place

** I need new logics to store guessed letters in correct place. A game called hangman. As it is now the previous correct letter is overwritten if a new correct guess applys....**
function guessLetter() {
var letter;
var i;
var letterFound;
var correctLettersCount;
correctLettersCount=0;
letterBoxes = "";
letter = this.value;
for (i = 0; i < selectedWord.length; i++) {
if (selectedWord.charAt(i) == letter) { //if
letterBoxes += "<span>" + letter + "</span >";
}
else{
letterBoxes += "<span>*</span>";
}
document.getElementById("letterBoxes").innerHTML = letterBoxes;
}
}
You can use an array that will store the * and letters found
In the following snippet, this array is called display
const wordToFind = "testing";
const wordDisplay = document.getElementById("word");
let display = Array.from('*'.repeat(wordToFind.length));
wordDisplay.innerHTML = display.join("");
function checkLetter(el){
const letter = el.value.toLowerCase();
for(let i=0,l=wordToFind.length;i<l;i++){
if(wordToFind[i]===letter)
display[i] = letter;
}
el.value = "";
wordDisplay.innerHTML = display.join("");
}
<input oninput="checkLetter(this)" />
<p id="word"></p>

Categories

Resources