How to reset JavaScript code when input value is changed? - javascript

I would like for the code to change its answer when I change the value of the input.
So let's say instead of 10, I would like it to tell me how much HP (health points) I will have at level 15. Is there any way I can do this? I'm not that experienced in Javascript.
So right now I coded it to default to 10 on all stats. My website tells me that at level 10, I have 895.4 hp. The only problem is that it won't stay at 15 when I try to press enter. It will just revert back to 10. Pretty much useless. Is there any way to keep that number 15 when I press enter?
var finalhp = 500;
let hpmultiplier = 1.06;
var hpvaluestring = document.querySelector('.hp').value;
var hpvalue = parseInt(hpvaluestring);
for (let i = 0; i < hpvalue; i++) {
var finalhp = finalhp * hpmultiplier
}
console.log(finalhp)
<form>
<div>
<input class="hp" id="amount" type="number" value="10" min="0" max="50" oninput="rangeInput.value=amount.value">
<input class="slider" id="rangeInput" type="range" value="10" min="0" max="50" oninput="amount.value=rangeInput.value">
</div>
</form>

Add a form submit event listener to the form element and prevent form submission there.
<form onsubmit="submitForm(event)">
<div>
<input class="hp" id="amount" type="number" value="10" min="0" max="50" oninput="rangeInput.value=amount.value">
<input class="slider" id="rangeInput" type="range" value="10" min="0" max="50" oninput="amount.value=rangeInput.value">
</div>
</form>
Add a submitForm function inside a script tag
function submitForm(event){
event.preventDefault();
var finalhp = 500;
let hpmultiplier = 1.06;
var hpvaluestring = document.querySelector('.hp').value;
var hpvalue = parseInt(hpvaluestring);
for (let i = 0; i < hpvalue; i++) {
var finalhp = finalhp * hpmultiplier
}
console.log(finalhp)
}

So mainly I'm just adding eventListeners to trigger the function calculateHP on input/slider value change. The function calculateHP contains the same logic that you shared. I did this so that the eventListeners can callback the function.
Try the following:
const input = document.querySelector('.hp')
const slider = document.querySelector('.slider')
slider.addEventListener('change', calculateHP)
input.addEventListener('change', calculateHP)
function calculateHP(){
let multiplier = 1.06
let level = Number(input.value)
let HP = 500
for(let i = 0; i<level; i++){
HP = HP * multiplier
}
return console.log(HP)
}
<div>
<label>Level: </label>
<input class="hp" id="amount" type="number" value="10" min="0" max="50" oninput="rangeInput.value=amount.value">
<input class="slider" id="rangeInput" type="range" value="10" min="0" max="50" oninput="amount.value=rangeInput.value">
</div>

Related

Prevent user from entering smaller value than previous input

I am student testing and learning new things. Right now I'm trying to make a GUI fan speed controller. While I have made the basic code, I want that the user cant enter smaller value than previous input.
Javscript code
// 30
var range3 = document.getElementById("range3");
var num3 = document.getElementById('num3');
range3.addEventListener('input', function (e) {
num3.value = e.target.value;
});
num3.addEventListener('input', function (e) {
range3.value = e.target.value;
});
// 40
var range4 = document.getElementById("range4");
var num4 = document.getElementById('num4');
range4.addEventListener('input', function (e) {
num4.value = e.target.value;
});
num4.addEventListener('input', function (e) {
range4.value = e.target.value;
});
// 50
var range5 = document.getElementById("range5");
var num5 = document.getElementById('num5');
range5.addEventListener('input', function (e) {
num5.value = e.target.value;
});
num5.addEventListener('input', function (e) {
range5.value = e.target.value;
});
function execute(){
document.getElementById("result").innerHTML = num3.value + " " + num4.value + " " + num5.value ;
}
HTML code
<input id="range3" type="range" min="0" max="100" value="0" />
<input id="num3" min="0" max="100" type="number" value="0" />
<input id="range4" type="range" min="0" max="100" value="0" />
<input id="num4" min="0" max="100" type="number" value="0" />
<input id="range5" type="range" min="0" max="100" value="0" />
<input id="num5" min="0" max="100" type="number" value="0" />
<button onclick="execute()">Click</button>
<p id="result"></p>

input type range with specific numbers

I have an input type range which is Min of 0 and Max of 100
<div class="slidecontainer">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange" >
<input type="text" id="rangeValue">
</div>
And my JS
var slider = document.getElementById("myRange");
var output = document.getElementById("rangeValue");
$(output).val(slider.value);
slider.oninput = function() {
$(output).val(slider.value);
}
And it working:
But, what I want to happen is not all range 1-100. But when you try to scroll it, it will only show specific numbers, not all numbers between 1-100. For example. 10, 25 ,50 , 65 , 82, 88, 90, 98 , 100 only
Having trouble with this. Thank you
Well, you have two possibilities:
You can use the step attribute on your input to define a specific granularity
If you want a specific step between your values, you can define a datalist linked to your slider (eg. https://developer.mozilla.org/fr/docs/Web/HTML/Element/datalist)
<input type="range" list="tickmarks">
<datalist id="tickmarks">
<option value="10">
<option value="25">
<option value="50">
<option value="65">
<option value="82">
<option value="88">
<option value="90">
<option value="98">
<option value="100">
</datalist>
You could map your slider values to an array although it breaks the intuitive nature of the UI a little...
<div class="slidecontainer">
<input type="range" min="0" max="8" value="4" class="slider" id="myRange" >
<input type="text" id="rangeValue">
</div>
<script>
var slider = document.getElementById("myRange");
var output = document.getElementById("rangeValue");
var vals =[10, 25 ,50 , 65 , 82, 88, 90, 98 , 100];
$(output).val(vals[slider.value]);
slider.oninput = function() {
$(output).val(vals[slider.value]);
}
</script>
All you need for this is the step attribute on your input element:
var slider = document.getElementById("myRange");
var output = document.getElementById("rangeValue");
$(output).val(slider.value);
slider.oninput = function() {
$(output).val(slider.value);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="slidecontainer">
<input type="range" min="0" max="100" step="5" value="50" class="slider" id="myRange" >
<input type="text" id="rangeValue">
</div>
(See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number)
Actually yes you can use the step or list attributes, but this is not enough to validate the entered value.
You need to use a certain validation control along with the datalist and the list attribute, and when the value is out of range just reset it.
let values = Array.from($("#values option")).map(v => +v.value);
slider.oninput = function(e) {
//Check wether the inputted value is in the range of values
if (values.some(val => val == slider.value)) {
$(output).val(slider.value);
} else {
slider.value = 0;
}
}
Demo:
var slider = document.getElementById("myRange");
var output = document.getElementById("rangeValue");
$(output).val(slider.value);
let values = Array.from($("#values option")).map(v => +v.value);
slider.oninput = function(e) {
if (values.some(val => val == slider.value)) {
$(output).val(slider.value);
} else {
slider.value = 0;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<div class="slidecontainer">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange" list="values">
<input type="text" id="rangeValue">
<datalist id="values" style="display:none;">
<option value="10">
<option value="20">
<option value="30">
<option value="50">
<option value="65">
<option value="80">
<option value="100">
</datalist>
</div>
You have to make a custom function for that
var slider = document.getElementById("myRange");
var output = document.getElementById("rangeValue");
var arr = [10, 25, 50, 65, 82, 88, 90, 98, 100];
var ele = document.querySelector('.slider')
ele.setAttribute('step', arr[0]);
var i = 0;
function a() {
ele.removeAttribute('step')
var value = ele.value
for (i = 0; i < arr.length; i++) {
if (arr[i] > value) {
ele.value = arr[i]
break;
}
}
document.querySelector('span').innerHTML = ele.value
}
<div class="slidecontainer">
<input type="range" min="0" max="100" step="5" value="50" class="slider" id="myRange" onchange="a()">
</div>
<span>0</span>

How to get the value of a range slider?

Can you please help me how to get values of a range slider in javascript?
<script>
$(function()
{
$('.slider').on('input change', function(){
$(this).next($('.slider_label')).html(this.value);
});
$('.slider_label').each(function(){
var value = $(this).prev().attr('value');
$(this).html(value);
});
})
</script>
<p><label for="range_size">Size: </label> <input type="range" name="size" class="slider" min="1" max="75" value="45">
<span class="slider_label"></span></p>
<p><label for="range_width">Width: </label> <input type="range" name="width" class="slider" min="1" max="6" value="1">
<span class="slider_label"></span></p>
I am trying to get like this :
<script type="text/javascript">
function calculate () {
var size = document.getElementById ("size").value;
alert(size);
</script>
But it doesn't show any alert. Can you please help me?
Using value does work :
let p = document.getElementById("val")
let range = document.getElementById("slide")
let changeVal = () => {
p.textContent = range.value
}
changeVal()
range.onchange = changeVal
<input id="slide" type="range" min="0" max="100"/><p id="val"></p>
as B001ᛦ said in comment the problem is you forgot to add an id on your <input>
If you prefer you can also use names but you need to take care as name can be reused while Ids are unique
let p = document.getElementsByName("val")[0]
let range = document.getElementsByName("slide")[0]
let changeVal = () => {
p.textContent = range.value
}
changeVal()
range.onchange = changeVal
<input name="slide" type="range" min="0" max="100"/><p name="val"></p>
getElementsByName return a NodeList so you'll need to get the node you need from this list (the first one if you have only one)
as a side note value does exists on every input type

Set max value of three input numbers together

I have three input numbers:
<input min="0" name="cat1" step="1" type="number" max="50" value="0" />
<input min="0" name="cat2" step="1" type="number" max="50" value="0" />
<input min="0" name="cat3" step="1" type="number" max="50" value="0" />
Currently the max value is 50. I would like the max for all three together to be 50 aswell.
How can I solve this with javascript or jquery?
This method sums the other inputs, and if the sum + the current value is greater than max, it changes the current input's value to fit max.
For example, try entering 30, 5, 20 to the input boxes.
var max = 50;
var $inputs = $('input');
function sumInputs($inputs) {
var sum = 0;
$inputs.each(function() {
sum += parseInt($(this).val(), 0);
});
return sum;
}
$inputs.on('input', function(e) {
var $this = $(this);
var sum = sumInputs($inputs.not(function(i, el) {
return el === e.target;
}));
var value = parseInt($this.val(), 10) || 0;
if(sum + value > max) $this.val(max - sum);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input min="0" name="cat1" step="1" type="number" max="50" value="0" />
<input min="0" name="cat2" step="1" type="number" max="50" value="0" />
<input min="0" name="cat3" step="1" type="number" max="50" value="0" />
Hope you expected this way.
Try Using this code.
it will check the aggregate of three fields and check it whether it is greater than 50.
$(":input").bind('keyup mouseup', function () {
var cat1=$("#cat1").val();
var cat2=$("#cat2").val();
var cat3=$("#cat3").val();
var total=parseInt(cat1) + parseInt(cat2) + parseInt(cat3);
if(total>50) {
alert("it exceeds 50");
return false;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input min="0" id="cat1" name="cat1" step="1" type="number" max="50" value="0" />
<input min="0" id="cat2" name="cat2" step="1" type="number" max="50" value="0" />
<input min="0" id="cat3" name="cat3" step="1" type="number" max="50" value="0" />
This will ensure the sum doesn't exceed 50. In case the new value makes the total exceed the limit, the other two will be lowered equally to enforce the total=50 rule.
Note the
let share2 = Math.min(Math.floor(excessValue / 2), elmt2Value) which ensures
To ensure we won't remove more from one of the input than its value.
<input min="0" name="cat1" id="cat1" step="1" type="number" max="50" value="0" onchange="valueChanged('cat1')" />
<input min="0" name="cat2" id="cat2" step="1" type="number" max="50" value="0" onchange="valueChanged('cat2')" />
<input min="0" name="cat3" id="cat3" step="1" type="number" max="50" value="0" onchange="valueChanged('cat3')" />
<script>
function valueChanged(changedElmtId) {
// Retrieve all input, the one changed and the other 2
let elmt2Id = "cat2", elmt3Id = "cat3"
if ( changedElmtId === elmt2Id ) {
elmt2Id = "cat1"
}
else if ( changedElmtId === elmt3Id ) {
elmt3Id = "cat1"
}
let changedElmt = document.querySelector("#" + changedElmtId)
let elmt2 = document.querySelector("#" + elmt2Id)
let elmt3 = document.querySelector("#" + elmt3Id)
let elmt2Value = parseInt(elmt2.value)
let elmt3Value = parseInt(elmt3.value)
// Check if any action is needed
let totalValue = parseInt(changedElmt.value) + elmt2Value + elmt3Value
if ( isNaN(totalValue) || totalValue <= 50 )
return
// Measure excess then split in 2
let excessValue = totalValue - 50
let share2 = Math.min(Math.floor(excessValue / 2), elmt2Value)
let share3 = excessValue - share2
console.log("Current:", " " + elmt2Id + ": ", share2, " " + elmt3Id + ": ", share3)
console.log("Total:", totalValue, " Excess: ", excessValue, " " + elmt2Id + ": ", share2, " " + elmt3Id + ": ", share3)
elmt2.value = elmt2Value - share2
elmt3.value = elmt3Value - share3
}
</script>
I don't know how optimal my solution is but it works. Covered some edge cases too.
let inputs = document.querySelectorAll('input');
const max = inputs[0].getAttribute("max");
let value;
inputs.forEach((input, i) => {
input.addEventListener('change',(e) =>handleChange(e)); // adding change event
input.addEventListener('blur',(e) =>handleChange(e)); //adding a blur eventto prevent direct typing of input larger than max
})
const handleChange = (e) =>{
if(e.target.value > max - value){
e.target.value = max-value; //setting max value possible if input value is greater than max
return;
}else{
value = 0;
inputs.forEach( input => {
value+=parseInt(input.value); //calculating value to negate from max
});
inputs.forEach( input => {
if(max-value > 0){
input.setAttribute("max", max-value); //setting max value on every input
}
});
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<input min="0" name="cat1" step="1" type="number" max="50" value="0" />
<input min="0" name="cat2" step="1" type="number" max="50" value="0" />
<input min="0" name="cat3" step="1" type="number" max="50" value="0" />
</body>
</html>
I hope that works for you easy small and fast for lesser number of input in form.
$(function(){
$('input[type=number]').attr('max', '50')
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input min="0" name="cat1" step="1" type="number" value="0" />
<input min="0" name="cat2" step="1" type="number" value="0" />
<input min="0" name="cat3" step="1" type="number" value="0" />

Display values of multiple input type range in one page

I'm trying to display values of every slider I have on my page, this is my code so far:
var i = 0;
var st = 'slider';
var ot = 'output';
var s = '';
var o = '';
for (var x = 0; x < 3; x++) {
i++;
s = st+i;
o = ot+i;
var s = document.getElementById("range"+i);
var o = document.getElementById("limit"+i);
o.innerHTML = s.value;
s.oninput = function() {
o.innerHTML = this.value;
}
}
<div id="slidecontainer">
<input type="range" min="2" max="50" value="20" class="slider" id="range1" >
<label>You chose <span id="limit1"></span></label>
</div>
<div id="slidecontainer">
<input type="range" min="2" max="50" value="20" class="slider" id="range2" >
<label>You chose <span id="limit2"></span></label>
</div>
<div id="slidecontainer">
<input type="range" min="2" max="50" value="20" class="slider" id="range3" >
<label>You chose <span id="limit3"></span></label>
</div>
It's only changing the last value when I move any slider, I want to display the value of each slider respectively. I'm using a loop in my JavaScript code because I have more than 20 sliders and I don't want to write a function for each of them unless that is the only way of doing it. Any suggestions?
The problem you are having is related to variable scope. There is only one variable named o, each iteration of the loop changes this variable. So when the
oninput function is evaluated o equals the last value you set it to equal. The current value of o is not "saved" in the function definition.
See https://www.w3schools.com/js/js_scope.asp for more information.
See solution below, here I find the limit in each call to the function.
function updateLabel() {
var limit = this.parentElement.getElementsByClassName("limit")[0];
limit.innerHTML = this.value;
}
var slideContainers = document.getElementsByClassName("slidecontainer");
for (var i = 0; i < slideContainers.length; i++) {
var slider = slideContainers[i].getElementsByClassName("slider")[0];
updateLabel.call(slider);
slider.oninput = updateLabel;
}
<div class="slidecontainer">
<input type="range" min="2" max="50" value="20" class="slider">
<label>You chose <span class="limit"></span></label>
</div>
<div class="slidecontainer">
<input type="range" min="2" max="50" value="20" class="slider">
<label>You chose <span class="limit"></span></label>
</div>
<div class="slidecontainer">
<input type="range" min="2" max="50" value="20" class="slider">
<label>You chose <span class="limit"></span></label>
</div>

Categories

Resources