I'm looking for a method where I can make a variable containing the document.getElementById and include the correct value for the ID as a variable value. What I have now is this:
let lenght = parseInt(document.getElementById("lenght").value);
let start = parseInt(document.getElementById("start").value);
let end = parseInt(document.getElementById("end").value);
But what I would like to have is something like this:
let documentById = parseInt(document.getElementById($elementName).value)
let lenght = documentById("lenght");
let start = documentById("start");
let end = documentById("end");
Am I thinking in the correct way or is this a method that does not make sense? Any tips/suggestions are welcome as I try to learn.
You could accomplish this with a simple function that takes in the ID of the element as a parameter and returns the value as intended
function documentById(id) {
const el = document.getElementById(id);
if (!el) return undefined; // element doesn't exist
const value = parseInt(el.value, 10); // parsing string to a number (default radix is 10)
return isNaN(value) ? { number: false, value: value } : { number: true, value: value };
}
const { number, value } = documentById('end'); // if value isnt a number return false (to prevent errors);
if (number) console.log(value); // if value is a number log its value
else console.log('not a valid number')
Sure, you can make a function that returns just that.
const getValueById = (id) => parseInt(document.getElementById(id).value, 10);
const length = getValueById("length");
const start = getValueById("start");
const end = getValueById("end");
console.log({ length, start, end });
<input id="length" value="5" />
<input id="start" value="2" />
<input id="end" value="6" />
Related
I have three inputs and three variables, my goal is to change variables values with the values inside the inputs
const inputs = [
document.querySelector(".bill-input"),
document.querySelector(".custom"),
document.querySelector(".people-number"),
];
var bill = 0;
var tip = 0;
var people = 0;
i accomplished to do it this way
inputs[0].addEventListener("keyup", (e) => {
bill = Number(e.target.value);
});
inputs[1].addEventListener("keyup", (e) => {
tip = Number(e.target.value);
});
inputs[2].addEventListener("keyup", (e) => {
people = Number(e.target.value);
});
I'm pretty sure this is not the optimal way to do it, so i wanted to ask if there's a way to do it with forEach or any other method that does not require for me to write every single one each time.
Add a data attribute to each input.
Use an object to maintain the state of those inputs instead of n variables.
Have one handler that can update the object properties based on their id.
// Initialise the values object
const values = { bill: 0, tip: 0, people: 0 };
// Cache the inputs, and add listeners to them
const inputs = document.querySelectorAll('input');
inputs.forEach(input => input.addEventListener('keyup', handleChange));
// Grab the id from the input's dataset, and
// set the values object property to match
// the input value
function handleChange() {
const { id } = this.dataset;
values[id] = this.value;
console.log(JSON.stringify(values));
}
input { display: block; }
Bill<input data-id="bill">
Tip <input data-id="tip">
People <input data-id="people">
Additional documentation
Destructuring assignment
Yes, you can use forEach. I used a switch to get the index of the input element (in inputs const) to know what variable update.
Please see snippet below :
var bill = 0;
var tip = 0;
var people = 0;
const inputs = [
document.querySelector(".bill-input"),
document.querySelector(".custom"),
document.querySelector(".people-number"),
];
inputs.forEach(function(item,index){
item.addEventListener("keyup", (e) => {
const val = Number(e.target.value);
switch(index){
case 0 : bill = val; break;
case 1 : tip = val; break;
case 2 : people = val; break;
}
console.log(bill,tip,people)
});
});
<input value="3" type="number" class="bill-input">
<input value="10" type="number" class="custom">
<input value="100" type="number" class="people-number">
I'm finding DOM manipulation tricky. I have written a function that uses the filter method on an array with numbers that are divisible by two.
The function evenNums works. I want to use the push() method to push numbers from the input text field to the array and display the result from the function evenNums on the page.
HTML
<!DOCTYPE html>
<html>
<head> </head>
<body>
<label for="text">Enter Text</label>
<input id="myText" type="text" />
<input type="radio" />
<label for="function">Function 1</label>
<input type="radio" />
<label for="function">Function 2</label>
<button id="btn">Click Me</button>
<div id="result"></div>
<script src="array.js"></script>
</body>
</html>
ignore the radio buttons. This is my Javascript
const inputBtn = document.getElementById("btn")
const myText = document.getElementById("myText")
const result = document.getElementById("result")
//function 1 filter method on array.
const nums = [1,2,3];
const answer = nums.filter(evenNums);
function evenNums(nums) {
if (nums%2 == 0) {
return nums
}
}
result.innerHTML = answer;
console.log(nums) // original array
console.log(answer) // array using filter method
//How do I push a value from the user to the array?
inputBtn.addEventListener ("click", function() {
nums.push(myText.value);
myText.value ='';
evenNums(nums);
});
This is how far I've got. How do I push a value from the user to the array and display it on the page? Am I close?
Thanks for all your help!
What you are doing is almost correct, just make sure you call the filter and set the textcontent when clicking the button. Also the value is a string, you will have to parseInt() it to do the even / odd calculation. It is also safer to use textcontent instead of innerHTML.
const inputBtn = document.getElementById("btn")
const myText = document.getElementById("myText")
const result = document.getElementById("result")
const nums = [1, 2, 3];
inputBtn.addEventListener("click", function() {
nums.push(parseInt(myText.value));
myText.value = '';
const answer = nums.filter(evenNums);
function evenNums(nums) {
if (nums % 2 == 0) {
return nums
}
}
result.textContent = answer;
});
<label for="text">Enter Text</label>
<input id="myText" type="text" />
<button id="btn">Click Me</button>
<div id="result"></div>
Just a sidenote: filter() expects a boolean as return value, the reason your filter works is because you return nums which is seen as truthy.
This should be better.
const nums = [1, 2, 3];
const answer = nums.filter(evenNums);
function evenNums(nums) {
if (nums % 2 == 0) {
return true;
}
}
console.log(answer);
You could simplify your filter to.
const nums = [1,2,3];
const answer = nums.filter(n => n % 2 === 0);
console.log(answer);
Because (x === y) returns a boolean.
The short answer would be.
const inputBtn = document.getElementById("btn")
const myText = document.getElementById("myText")
const result = document.getElementById("result")
const nums = [1, 2, 3];
inputBtn.addEventListener("click", function() {
nums.push(parseInt(myText.value));
myText.value = '';
result.textContent = nums.filter(n => n % 2 === 0);
});
<label for="text">Enter Text</label>
<input id="myText" type="text" />
<button id="btn">Click Me</button>
<div id="result"></div>
Seems like you are on the right track. After you push the user's input to the array, you can display the result of filtered array on the page by setting the innerHTML attribute.
Just calling the function on its own is not going to do anything for you.
document.getElementById("result").innerHTML = nums.filter(evenNums);
I have a controlled <input /> in my React application where the user would type.
I want to keep track on it and replace the occurrences of $.text and $.lang to random hashes/number.
from
let string = 'I may have multiple $.text and $.lang like $.textand$.lang';
I want all occurrences of $.text and $.lang to have a random number(or anything unique):
to
updatedString = 'I may have multiple 123 and 245 like 744and111';
What I have done so far
let temp = value.split('').reverse().join(''); // reverse it to find the latest occurrence
let reText = /txet.\$/i;
let reLang = /gnal.\$/i;
let updated;
if (value.includes('$.text')) {
updated = temp.replace(reText, `${hash}#`); // replace the latest occurrence
} else {
updated = temp.replace(reLang, `${hash}#`); // replace the latest occurrence
}
updatedValue = updated.split('').reverse().join(''); // re reverse it
The issue is it replaces the but onChange RESETS the input state and it only changes the last occurrence of it.
So im doing it on click. So lets say user type something and then clicking on Replace Template button will replace the $.text and $.lang by some random number. You can insert your specific hash or number if needed.
const replaceTemplateByRandom = (val, temp) => {
while(val.indexOf(temp) != -1){
const numb = Math.floor(Math.random()*1000);
val = val.replace(temp, numb);
}
return val;
}
inside this arrow function I'm running the while loop till we find the template to replace, and replace occurrence by random number.
const replaceTemplateByRandom = (val, temp) => {
while(val.indexOf(temp) != -1){
const numb = Math.floor(Math.random()*1000);
val = val.replace(temp, numb);
}
return val;
}
function App(props){
const [val, setVal] = React.useState('default text is $.text, and language is $.lang.');
const updateVal = (e) => {
const newVal = e.target.value;
setVal(newVal);
}
const replaceTemplate = ()=>{
let currentVal = val;
currentVal = replaceTemplateByRandom(currentVal, '$.text');
currentVal = replaceTemplateByRandom(currentVal, '$.lang');
setVal(currentVal);
}
return <div>
<input type="text" value={val} onChange={updateVal} style={{"width":"100%"}}/>
<button onClick={replaceTemplate}>Replace Template</button>
</div>;
}
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
You can make use of .replace()'s acceptance of a function for custom and dynamic substitution:
function myHashFunction(match)
{
// Uncomment this line to see the various matches coming through
//console.log(match);
// I'm just returning a random number, you need to change this to your hash algorithm
return Math.floor(Math.random() * Math.floor(999999999999));
}
let str = `I may have multiple $.text and $.lang like $.textand$.lang`;
console.log(str.replace(/\$\.(?:text|lang)/g, myHashFunction));
function myFunction() {
var theString = "How are $.you doing $.you today?";
var splitString = theString.split("$.you");
var joinedString = "";
for(index = 0; index < splitString.length-1; index++){
joinedString += splitString[index] + Math.random();
}
document.getElementById("demo").innerHTML = joinedString;
}
Something simple like this could probably do the job.
So spliting the string into an array of strings and then joining it back with a specific string.
Not React specifically, but the idea is there.
I want to get the value of an input type number and put it into a global variable. But in the console I get undefined. I need to use the value in other functions. How can I do that?
const bet = document.querySelector('#bet');
let Inputvalue;
bet.addEventListener('change', checkBet)
function checkBet(e) {
Inputvalue = e.target.value;
}
console.log(Inputvalue)
<input type="number" id="bet" value="" name="bet">
The checkBet() function will only be called after you change the value in the input. However, console.log() gets called right away, just as the JS parser reads the file. Since you've not assigned any value to the variable, you will get undefined.
You should either initialize the variable with a value (like 0), or move the console.log() inside the checkBet() function.
Option 1:
const bet = document.querySelector('#bet');
let Inputvalue;
bet.addEventListener('change', checkBet)
function checkBet(e) {
Inputvalue = e.target.value;
console.log(Inputvalue)
}
Option 2:
const bet = document.querySelector('#bet');
let Inputvalue = 0;
bet.addEventListener('change', checkBet)
function checkBet(e) {
Inputvalue = e.target.value;
}
console.log(Inputvalue)
Try this.
const bet = document.querySelector('#bet');
let Inputvalue;
bet.addEventListener('change', checkBet);
function checkBet(e) {
Inputvalue = e.target.value;
console.log(Inputvalue)
}
<input type="number" id="bet" name="bet"/>
Hope this helps
How would one go about stacking values to each other? So if you were to click on a button, it would add the numbers to each other and keep stacking on. I'm trying to add the values to a P tag's innerHTML that calculates the total but I just figured out how to display its true value without the addition of additional values.
const input = document.querySelector('input')
const button = document.querySelector('button')
const p = document.querySelector('p')
function addCal() {
const inputVal = input.value
p.innerHTML = inputVal
}
button.addEventListener('click', addCal)
<input type="text"/>
<button>Add Calories</button>
<p>0</p>
You just need to keep track of the last value somewhere and add that to the newest number.
Keep in mind that all values gotten from HTML are strings, so they must be converted (implicitly or explicitly) to numbers before math can be done. Also, .innerHTML is for when you are getting/ setting strings that contain HTML. When you aren't doing that, use .textContent.
Also note that you should always verify user input is what you think it is before you operate on it. What if the user doesn't enter anything, but clicks the button anyway? What if they enter non-numeric data?
const input = document.querySelector('input');
const button = document.querySelector('button');
const p = document.querySelector('p');
var total = null; // The running total will be kept here
function addCal() {
const inputVal = input.value;
// .parseInt() and .parseFloat() are two ways of
// explicitly converting strings that contain number
// characters to numbers. With .parseInt() the secon
// argument is the radix, which specifies what numeral
// system to use (base 10 here).
total = total + parseInt(inputVal, 10);
p.textContent = total;
}
button.addEventListener('click', addCal)
<input type="text"/>
<button>Add Calories</button>
<p>0</p>
One of the easiest ways is to use reduce to sum all the input values.
1) Pick up all the inputs with querySelectorAll.
2) Then iterate over the input elements with reduce adding each input's value to the total sum. We use +input.value to coerce the string type of the value to a number.
const inputs = document.querySelectorAll('input');
const button = document.querySelector('button');
const para = document.querySelector('p');
function addCal() {
para.textContent = [...inputs].reduce((sum, input) => {
return sum += +input.value;
}, 0);
}
button.addEventListener('click', addCal, false);
<input type="text" />
<input type="text" />
<input type="text" />
<input type="text" />
<button>Add Calories</button>
<p>0</p>
Just do convert p tag value to int and then added up. like
function addCal() {
const inputVal = input.value
p.innerHTML = ( parseInt(p.innerHTML) + parseInt(inputVal) )
}