I am trying to make the sliders output the values depending on the which button has been clicked.
<!DOCTYPE html>
<html>
<body>
<div id="slidecontainer">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange">
<p>Value: <span id="demo"></span></p>
</div>
<input type="button" onclick="function1()" value="1">
<input type="button" onclick="function2()" value="2">
<input type="button" onclick="function3()" value="3">
<script>
var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
output.innerHTML = slider.value;
slider.oninput = function() {
output.innerHTML = this.value;
}
function function1() {
var a = 'test1'
console.log('test: ' + a +' '+ slider.value);
}
function function2() {
var a = 'test2'
console.log('test: ' + a +' '+ slider.value);
}
function function3() {
var a = 'test3'
console.log('test: ' + a +' '+ slider.value);
}
</script>
</script>
</body>
</html>
As you can see for each of the buttons, the functions are being repeated and only the variable 'a' is being changed. I was wondering if there was a way to make this code more efficient, in other words shorter.
Please let me know if you have any solutions for this.
Thanks.
Well you could inspect the element that triggered the event to get it's associated value like this and to be consistant with yoru slider you can bind to all inputs with a special class like this:
var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
var buttons = document.getElementsByClassName('button');
output.innerHTML = slider.value;
slider.oninput = function() {
output.innerHTML = this.value;
}
for(var i = 0; i < buttons.length; i++) {
var button = buttons[i];
button.onclick = function() {
var a = 'test'+this.value;
console.log('test: ' + a +' '+ slider.value);
}
}
<div id="slidecontainer">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange">
<p>Value: <span id="demo"></span></p>
</div>
<input type="button" class="button" value="1">
<input type="button" class="button" value="2">
<input type="button" class="button" value="3">
There is no need to define the same variable again and again and multiple functions to perform the same task.
Use:
<input type="button" onclick="some_function('test1')" value="1">
<input type="button" onclick="some_function('test2')" value="2">
<input type="button" onclick="some_function('test3')" value="3">
to use the same function.
function some_function(a) {
console.log('test: ' + a +' '+ slider.value);
}
<!DOCTYPE html>
<html>
<body>
<div id="slidecontainer">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange">
<p>Value: <span id="demo"></span></p>
</div>
<input type="button" onclick="function_name('test1')" value="1">
<input type="button" onclick="function_name('test2')" value="2">
<input type="button" onclick="function_name('test3')" value="3">
<script>
var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
output.innerHTML = slider.value;
slider.oninput = function() {
output.innerHTML = this.value;
}
function function_name(a) {
console.log('test: ' + a +' '+ slider.value);
}
</script>
</body>
</html>
let slider = document.getElementById('myRange');
let output = document.getElementById('output');
let setOutputHTML = function (value) {
output.innerHTML = value;
};
let setSliderValue = function (e) {
slider.value = e.currentTarget.value;
slider.dispatchEvent(new Event('input'));
};
slider.addEventListener('input', function (e) {
setOutputHTML(e.currentTarget.value);
});
setOutputHTML(slider.value);
Array.from(document.querySelectorAll('[type="button"]'))
.forEach(function (input) {
input.addEventListener('click', setSliderValue);
});
<div>
<input type="range" min="1" max="100" value="50" class="slider" id="myRange">
<p>Value: <span id="output"></span></p>
</div>
<input type="button" value="25" name="field_slug" />
<input type="button" value="50" name="field_dlug" />
<input type="button" value="75" name="field_flug" />
Basically, just pass this to the function and since the value indicated on the button is what is different for each button, we just concatenate that to 'test' and pass that to the string.
<!DOCTYPE html>
<html>
<body>
<div id="slidecontainer">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange">
<p>Value: <span id="demo"></span></p>
</div>
<input type="button" onclick="setSliderValue(this)" value="1">
<input type="button" onclick="setSliderValue(this)" value="2">
<input type="button" onclick="setSliderValue(this)" value="3">
<script>
var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
output.innerHTML = slider.value;
slider.oninput = function() {
output.innerHTML = this.value;
}
function setSliderValue(button) {
var value = button.value
var testType = 'test' + value;
console.log('test: ' + testType +' '+ slider.value);
}
</script>
</body>
</html>
Related
I have code that looks something like below. When I hit the reset button, I want my paragraph element to update to the default slider values, but they stay at the same value from before the reset. How can I make it so that the paragraph element reflects the reset slider value?
JSFiddle Link: https://jsfiddle.net/apshah/f6ymkcLe/
HTML:
<div class ='slidercontainer' id='slidercontainer'>
<form action method="POST" class="sliderform" id="sliderform">
<div class = "divslider" id="slider1">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange1">
<p>
<span class="sVal" id="val1">50</span>
</p>
</div>
<div class = "divslider" id="slider2">
<input type="range" min="1" max="10" value="5" class="slider" id="myRange2">
<p>
<span class="sVal" id="val2">5</span>
</p>
</div>
</form>
<div class="space1"></div>
<div class='buttonbox'>
<button type="submit" form="sliderform" class="sliderbutton" id="accept">Accept</button>
<button type="reset" form="sliderform" class="sliderbutton" id="reset">Reset</button>
<div class="space2"></div>
</div>
</div>
JavaScript:
document.body.onload = function(){
runSlider("myRange1", 'val1')
runSlider('myRange2', 'val2')
}
function runSlider(inputID, pID){
var slider = document.getElementById(inputID);
var output = document.getElementById(pID);
output.innerHTML = slider.value;
slider.oninput = function() {
output.innerHTML = this.value;
}
}
You should add another listener for this. I used setTimeout because of async.
document.body.onload = function(){
runSlider("myRange1", 'val1')
runSlider('myRange2', 'val2')
registerFormEvent()
}
function registerFormEvent() {
const formEl = document.querySelector(".sliderform");
const onFormReset = function(){
setTimeout(() => {
document.querySelector("#val1").innerHTML = document.querySelector("#myRange1").value;
document.querySelector("#val2").innerHTML = document.querySelector("#myRange2").value;
}, 0)
}
formEl.addEventListener("reset", onFormReset)
}
function runSlider(inputID, pID){
var slider = document.getElementById(inputID);
var output = document.getElementById(pID);
output.innerHTML = slider.value;
slider.oninput = function() {
output.innerHTML = this.value;
}
}
I have 3 range inputs:
When the user starts to drag the range thumb, I'd love the of related input value to be printed in the label before main text. For this I wrote a funtion, but nothng works
let rangeForm = document.querySelectorAll('.form-range');
let rangeValue = document.querySelectorAll('.input-value');
window.onload = () => {
rangeForm.forEach((input) => input.value = '0');
}
function findTotal() {
var tot = 0;
rangeForm.forEach((input) => tot += parseInt(input.value, 10));
document.getElementById('total-cost').innerHTML = tot;
}
function changeLabel() {
rangeValue.forEach((label) => label.inhherHTML = `${parseInt(input.value, 10)}`);
}
<label for="storiesNumber" class="form-label"><p class="input-value"></p>some text</label>
<input type="range" oninput="findTotal();changeLabel()" class="form-range" min="0" max="100" id="storiesNumber">
<label for="postsNumber" class="form-label"><p class="input-value"></p>another text</label>
<input type="range" oninput="findTotal();changeLabel()" class="form-range" min="0" max="100" id="postsNumber">
<label for="reelsNumber" class="form-label"><p class="input-value"></p>more text</label>
<input type="range" oninput="findTotal();changeLabel()" class="form-range" min="0" max="100" id="reelsNumber">
Check out this snippet, I guess it fits your purpose:
let rangeForm = document.querySelectorAll('.form-range');
let rangeValue = document.querySelectorAll('.input-value');
window.onload = () => {
rangeForm.forEach((input) => input.value = '0');
}
function findTotal() {
var tot = 0;
rangeForm.forEach((input) => tot += parseInt(input.value, 10));
document.getElementById('total-cost').innerHTML = tot;
}
function changeLabel(input) {
document.querySelector("label[for="+input.id+"] > .input-value").innerText = `${parseInt(input.value, 10)}`
}
<label for="storiesNumber" class="form-label">
some text: <b class="input-value"></b>
</label>
<input type="range" oninput="findTotal();changeLabel(this)" class="form-range" min="0" max="100" id="storiesNumber">
<br>
<label for="postsNumber" class="form-label">
another text: <b class="input-value"></b>
</label>
<input type="range" oninput="findTotal();changeLabel(this)" class="form-range" min="0" max="100" id="postsNumber">
<br>
<label for="reelsNumber" class="form-label">
more text: <b class="input-value"></b>
</label>
<input type="range" oninput="findTotal();changeLabel(this)" class="form-range" min="0" max="100" id="reelsNumber">
<br>
Total: <b id="total-cost">...</b>
I have the following HTML:
<div class="filters">
<div class="filter-label">6</div>
<div class="filter-inputs">
<input type="number" name="i1" id="i1" value="1" min="0" step="1" />
<input type="number" name="i2" id="i2" value="2" min="0" step="1" />
<input type="number" name="i3" id="i3" value="3" min="0" step="1" />
</div>
</div>
The question:
I'd like to, when any input is changed, I want to get that value and
the value of the other two text boxes and add them all together. Once
I have the total value, I need to then change the text of the label
with the new value.
I also have the following JavaScript (jQuery) to detect when a change has happened, but after that, I can't figure out how to loop through each input in the div and get the value.
$('.filter .filter-inputs input').on('input', function() {
var element = $(this);
// ...
});
I looked at loops like the jQuery each method but I've got no idea how to loop through each input inside the filter-inputs div.
You could create array from inputs using map and get methods and then calculate sum with reduce method.
let inputs = $('.filters input');
let label = $('.filter-label');
inputs.on('input', function() {
let sum = inputs.map(function() {
return $(this).val()
}).get().reduce((r, e) => r + +e, 0);
label.text(sum)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="filters">
<div class="filter-label">6</div>
<div class="filter-inputs">
<input type="number" name="i1" id="i1" value="1" min="0" step="1" />
<input type="number" name="i2" id="i2" value="2" min="0" step="1" />
<input type="number" name="i3" id="i3" value="3" min="0" step="1" />
</div>
</div>
Or you could just create array with Array.from method and then use reduce method to sum values.
let inputs = $('.filters input');
let label = $('.filter-label');
inputs.on('input', function() {
label.text(Array.from(inputs).reduce((r, {value}) => r + +value, 0))
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="filters">
<div class="filter-label">6</div>
<div class="filter-inputs">
<input type="number" name="i1" id="i1" value="1" min="0" step="1" />
<input type="number" name="i2" id="i2" value="2" min="0" step="1" />
<input type="number" name="i3" id="i3" value="3" min="0" step="1" />
</div>
</div>
Use this script
$('.filter-inputs input').change(function(){
var total = 0;
$('.filter-inputs input').each(function(){
total += parseInt($(this).val());
});
$('.filter-label').html(total);
});
No problem!
$('.filter .filter-inputs input').on('input', function() {
//not needed:
//var element = $(this);
// Obtain numeric entries
var i1 = Number($("#i1").val());
var i2 = Number($("#i2").val());
var i3 = Number($("#i3").val());
// Calculate sum of entries
var total = i1 + i2 + i3;
// Populate label div with sum
$(".filter-label").html(String(total));
});
Good luck!
You don't need jQuery for this task http://jsfiddle.net/72e3jLc0/
let label = document.querySelector('.filter-label');
let inputs = document.querySelectorAll('.filter-inputs input');
inputs.forEach(input => {
input.addEventListener('change', e => {
label.innerText = parseInt(label.innerText) + parseInt(input.value);
});
});
Try using the following approach:
$(document).ready(function() {
var total=0;
$("input[type='number']").change(function() {
$(".results").html("");
var objects = $(".filters").find("input[type='number']");
for (var i = 0; i < objects.length; i++) {
total += parseInt($(objects[i]).val());
}
$(".filter-label").text(total);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="filters">
<div class="filter-label">6</div>
<div class="filter-inputs">
<input type="number" name="i1" id="i1" value="1" min="0" step="1" />
<input type="number" name="i2" id="i2" value="2" min="0" step="1" />
<input type="number" name="i3" id="i3" value="3" min="0" step="1" />
</div>
</div>
I know this is an old thread, but I would like to give my contribution.
The id can be replaced with document or "body", and input is not necessary if all your inputs have the class .form-control.
$("#id-of-overall-div-element").on("change", "input, .form-control", function () {
// Do something
});
Every time I click the + button I want the same input to display
The way I do it here works fine but seems like the worst way of doing it as just repeating the same code and changing the id's (also if I want for example 5 inputs I would have to repeat this code 5 times). What would be a better way of doing this?
<html>
<head>
<script language='JavaScript' type='text/javascript'>
function show3(){
document.getElementById('div2').style.display = 'block';
}
</script>
<style>
.hide {
display: none;
}
</style>
</head>
<body>
<div>
<input type="range" min="0" max="1500" value="0" class="slider2" id="one"/>
<p>Value(mm): <input type="text" id="two" size="10" class="special" /></p>
<button onclick="show3();" type="button">+</button>
</div>
<script>
var slider1 = document.getElementById("one");
var output2 = document.getElementById("two");
output2.value = slider1.value;
slider1.oninput = function() {
output2.value = this.value;
}
</script>
<div id="div2" class="hide">
<input type="range" min="0" max="1500" value="0" class="slider2" id="three"/>
<p>Value(mm): <input type="text" id="four" size="10" class="special" /></p>
<button onclick="show3();" type="button">+</button>
</div>
<script>
var slider2 = document.getElementById("three");
var output3 = document.getElementById("four");
output2.value = slider1.value;
slider2.oninput = function() {
output3.value = this.value;
}
</script>
</body>
</html>
<html>
<head>
<script language='JavaScript' type='text/javascript'>
function show3(){
document.getElementById('div2').style.display = 'block';
}
</script>
<style>
.hide {
display: none;
}
</style>
</head>
<body>
<div>
<input type="range" min="0" max="1500" value="0" class="slider2" id="one"/>
<p>Value(mm): <input type="text" id="two" size="10" class="special" /></p>
<button onclick="show3();" type="button">+</button>
</div>
<script>
var slider1 = document.getElementById("one");
var output2 = document.getElementById("two");
output2.value = slider1.value;
slider1.oninput = function() {
output2.value = this.value;
}
</script>
<div id="div2" class="hide">
<input type="range" min="0" max="1500" value="0" class="slider2" id="three"/>
<p>Value(mm): <input type="text" id="four" size="10" class="special" /></p>
<button onclick="show3();" type="button">+</button>
</div>
<script>
var slider2 = document.getElementById("three");
var output3 = document.getElementById("four");
output2.value = slider1.value;
slider2.oninput = function() {
output3.value = this.value;
}
</script>
</body>
</html>
This will work for all the sliders. But you need to keep in mind a couple of things :
This will work only for the sliders that are already rendered in the DOM (even if they are hidden) if you render new sliders to the DOM you will need to attach the event listener as I did it in the foreach loop.
The input id (e.g "one") needs to match the output data-range="one"
function show3(){
document.getElementById('div2').style.display = 'block';
}
var sliders = document.querySelectorAll(".slider"); // slider = common class name
sliders.forEach(( slider ) => {
slider.addEventListener('input', (e) => {
const sliderId = e.target.id;
const output = document.querySelector(`[data-range=${sliderId}]`);
output.value = e.target.value;
});
});
<html>
<head>
<style>
.hide {
display: none;
}
</style>
</head>
<body>
<div>
<input type="range" min="0" max="1500" value="0" class="slider" id="one"/>
<p>Value(mm): <input type="text" data-range="one" id="two" size="10" class="special" /></p>
<button onclick="show3();" type="button">+</button>
</div>
<div id="div2" class="hide">
<input type="range" min="0" max="1500" value="0" class="slider" id="two"/>
<p>Value(mm): <input type="text" data-range="two" id="four" size="10" class="special" /></p>
<button onclick="show3();" type="button">+</button>
</div>
</body>
</html>
Might be easier to include the code in the element and clone it (parentNode is the div) :
<div>
<input type="range" min="0" max="1500" value="0"
oninput="this.parentNode.getElementsByTagName('INPUT')[1].value = this.value"/>
<p>Value(mm): <input type="text" size="10" /></p>
<button type="button"
onclick="this.parentNode.parentNode.append(this.parentNode.cloneNode(true))">+</button>
</div>
I would recommend you to create some kind of class which let you create slider components dynamically.
Here's a quick example (not optimized):
var SliderComponent = (function(doc) {
var defaults = {
containerSelector: 'body',
value: 0,
min: 0,
max: 1500,
inputSize: 10,
inputClass: 'special',
sliderClass: 'slider',
buttonClass: 'button'
}, options;
function SliderComponent(options) {
options = Object.assign({}, defaults, options || {});
this.container = getContainer(options);
this.input = createInput(options);
this.slider = createSlider(options);
this.removeButton = createButton(options.buttonClass, '-');
this.addButton = createButton(options.buttonClass, '+');
this.element = render.apply(this);
this.events = [];
this.events.push(
addEventListener.call(this, 'click', this.removeButton, function() {
this.destroy();
}),
addEventListener.call(this, 'click', this.addButton, function() {
new SliderComponent(options);
}),
addEventListener.call(this, 'input', this.slider, function(event) {
this.input.value = event.target.value;
}),
addEventListener.call(this, 'input', this.input, function(event) {
this.slider.value = event.target.value;
})
)
}
SliderComponent.prototype.destroy = function() {
this.events.forEach(function(e) {
e();
});
this.element.remove();
}
function addEventListener(name, element, listener) {
listener = listener.bind(this);
element.addEventListener(name, listener);
return function() {
element.removeEventListener(name, listener);
};
}
function getContainer(options) {
var container = doc.querySelector(options.containerSelector);
if(!container) {
throw new Error('Container for selector %s not found', options.containerSelector);
}
return container;
}
function createInput(options) {
var input = doc.createElement('input');
input.setAttribute('type', 'number');
input.setAttribute('min', options.min);
input.setAttribute('max', options.max);
input.setAttribute('size', options.inputSize);
input.classList.add(options.inputClass);
input.value = options.value;
return input;
}
function createSlider(options) {
var input = doc.createElement('input');
input.setAttribute('type', 'range');
input.setAttribute('min', options.min);
input.setAttribute('max', options.max);
input.classList.add(options.sliderClass);
input.value = options.value;
return input;
}
function createButton(klass, text) {
var button = doc.createElement('button');
button.setAttribute('type', 'button');
button.classList.add(klass);
button.textContent = text;
return button;
}
function render() {
var element = doc.createElement('div');
element.appendChild(this.slider);
element.appendChild(this.input);
element.appendChild(this.removeButton);
element.appendChild(this.addButton);
return this.container.appendChild(element);
}
return SliderComponent;
})(document);
var sliders = new SliderComponent();
I want to add values by clicking the value buttons by each and every by the following function
function sum() {
var txtFirstNumberValue = document.getElementById('txt1').value;
var txtSecondNumberValue = document.getElementById('txt2').value;
var txtThirdNumberValue = document.getElementById('txt3').value;
var txtFourthNumberValue = document.getElementById('txt4').value;
var result = parseInt(txtFirstNumberValue) + parseInt(txtSecondNumberValue);
var result = parseInt(txtFirstNumberValue) + parseInt(txtThirdNumberValue);
var result = parseInt(txtFirstNumberValue) + parseInt(txtFourthNumberValue);
if (!isNaN(result)) {
document.getElementById('txt1').value = result;
}
}
// Here I gave the other two events to add to the text field by the id names
<!-- here I gave the three Value buttons and on click function -->
<input type="text" id="txt1" value="10" />
<input type="button" id="txt2" value="10" onClick="sum();" />
<input type="button" id="txt3" value="20" onClick="sum();" />
<input type="button" id="txt4" value="30" onClick="sum();" />
You can get the value of the button by passing this.value to the onClick function where this represent the element itself.
function sum(value) {
document.getElementById('txt1').value = Number(document.getElementById('txt1').value) + Number(value);
}
<input type="text" id="txt1" value="10" />
<input type="button" id="txt2" value="10" onClick="sum(this.value);" />
<input type="button" id="txt3" value="20" onClick="sum(this.value);" />
<input type="button" id="txt4" value="30" onClick="sum(this.value);" />
This javascript will help you.
<script>
function sum(e) {
var result = parseInt(e.value) + parseInt(document.getElementById('txt1').value);
if (!isNaN(result)) {
document.getElementById('txt1').value = result;
}
}
</script>