I am running into a problem in my application where I am trying to use an range slider to determine the position of a link containing an image. Basically it grabs the value of the ranges and uses it to determine the position. However, that does not happen. Instead it does absolutely nothing. Any thoughts on why this might occur?
JS Code:
//Social Media
var rangeX = document.getElementById("rangeX");
var rangeY = document.getElementById("rangeY");
var socialChooser = document.getElementById("socialsChooser");
var inputInvite = document.getElementById("inputInvite");
var submitsocialMedia = document.getElementById("submitSocial");
var Discord = document.getElementById("discord");
var YouTube = document.getElementById("youtube");
submitsocialMedia.addEventListener("click", function () {
var socialContainer = document.getElementById("socialsContainer");
if ( socialChooser.value === "discord") {
const a = document.getElementById("discordJoin");
if (a.children.length === 0) {
const linkText = document.createElement("img");
linkText.id = "linkText";
console.log(linkText.id);
linkText.src = "/html/imgs/Discord-Logo-White.png";
a.style.marginLeft = rangeX.value + "px";
a.style.marginTop = rangeY.value + "px";
a.appendChild(linkText);
a.title = "Discord Invite Link";
a.href = `${inputInvite.value}`;
}
}
HTML Code:
<input type="range" min="1" max="1000" value="500" id="rangeX"> X
<input type="range" min="1" max="1000" value="500" id="rangeY"> Y
It's hard to test your code. So many elements referenced but not available. Instead, here's a mockup of a working range slider/element added to DOM combo. Maybe it will help you discover what's not working in your setup.
let div = document.querySelector('div');
let rangeX = document.getElementById("rangeX");
let rangeY = document.getElementById("rangeY");
document.querySelector('button').addEventListener('click', () => {
div.innerHTML += `<a href='#' style='margin-left:${rangeX.value}px; margin-top:${rangeY.value}px;'>The link</a>`;
});
div a {
display: block
}
<input type="range" min="1" max="500" value="10" id="rangeX"> X
<input type="range" min="1" max="500" value="10" id="rangeY"> Y
<button>create</button>
<div>
</div>
Related
I am using an Input range slider and JS is giving the default value of 0 first and after that it gives the correct value.
So when I go to change the textContent to the value of the range its always a 0. After the first attempt the value is correct.
I have tried event listener to be "change" instead of "click". The result stays the same.
What am I missing?
JS Fiddle https://jsfiddle.net/5g78a4qL/
HTML
'''
Select your age
<input type="range" min="1" max="100" id="myRange" class="rch-slider">'''
JS
'''let slider = document.getElementById("myRange");
let output = 0;
let personAge = 0;
document.querySelector('#myRange').addEventListener('click', function(event){
document.querySelector('#yourAge').textContent = "Your Age: ";
output = document.getElementById("value")
output.innerHTML = slider.value
slider.oninput = function() {
output.innerHTML = this.value;
personAge = Number(this.value);
}
})
document.querySelector('#myRange').addEventListener('click', function(event){
console.log(personAge);
})'''
Try 'change' event listener instead of click...
document.querySelector('#myRange').addEventListener('change', function(event){
document.querySelector('#yourAge').textContent = "Your Age: ";
output = document.getElementById("value")
output.innerHTML = slider.value
slider.oninput = function() {
output.innerHTML = this.value;
personAge = Number(this.value);
}
})
THE RANGE INPUT:
<input type="range" value="1" min="1" max="100" id="myRange" class="rch-slider">
Try this
<div class="rch-age-section margin-sections">
<div class="rch-age"> <span id="yourAge">Select your age</span> <span id="value"></span></div>
<input type="range" min="1" max="100" id="myRange" class="rch-slider">
</div>
<script>
let slider = document.getElementById("myRange");
let output = document.getElementById("value");
let personAge = 0;
document.querySelector('#myRange').addEventListener('click',
function(event){
document.getElementById("yourAge").textContent = "Your Age: ";
output.textContent = slider.value
personAge = Number(slider.value);
console.log(personAge);
})
</script>
So, I have a input in my template
<input type="range" min="0" max="100" value="0" id="duration_slider" onchange="seek()">
My javascript for seek() and updating the slider is
function seek(){
slider_position = mysong.duration * (mysong.value / 100);
mysong.currentTime = slider_position;
}
function range_slider(){
let position = 0;
if(!isNaN(mysong.duration)){
position = mysong.currentTime * (100 / mysong.duration);
slider.value = position;
}
}
where mysong is the variable i get from my audio input in html.
var mysong = document.getElementById('mysong');
Sorry I don't know much javascript, I needed it while doing my django project. I applied same concept for my volume controls and it worked somehow.
I hope value of your slider_position corresponding to value of slider.value.
So you need to catch that value from slider...
var slider = document.getElementById('duration_slider');
and than define value variable in let slider_position into seek() function
function seek() {
let slider_position = slider.value;
mysong.currentTime = slider_position;
console.log(slider_position); //for displaying value in console
}
<input type="range" id="slider" min="0" max="100" value="0"/>
<script>
var slider = document.getElementById('slider');
const MAX_VALUE = 100;
const MIN_VALUE = 1;
function updateSliderRange(updatedValue){
const currentValue = slider.value;
slider.value = (currentValue >= MIN_VALUE && currentValue <=100)
? updatedValue
: currentValue;
}
</script>
The final div of my code contains 5 sliders (I show here just 2) and a “finish” button. On click, I want to be able to:
Download a CSV file with the chosen values
Display the next div (without displaying the values)
I can only use JS and HTML.
/// phase C ////
var slider1 = document.getElementById("q1");
var demo1 = document.getElementById("demo1");
var vq1 = slider1.value;
demo1.innerHTML = slider1.value;
slider1.oninput = function() {
demo1.innerHTML = this.value;
}
var slider2 = document.getElementById("q2");
var demo2 = document.getElementById("demo2");
var vq2 = slider2.value;
demo2.innerHTML = slider2.value;
slider2.oninput = function() {
demo2.innerHTML = this.value;
}
function Phase_E_action() {
document.getElementById("Phase_D").hidden = true;
document.getElementById("Phase_E").hidden = false;
var fileContent = vq1 + "," + vq2;
var bb = new Blob([fileContent], {
type: 'text/plain'
});
var a = document.createElement('a');
a.downoload = "Exp" + Date().toString().slice(4, 24) + ".csv";
a.href = window.URL.createObjectURL(bb);
a.click();
}
<div id="Phase_D">
<span class="v50_15"><h1>Please state your opinion on Bob</h1></span>
<div class="slidecontainer">
<span class="v50_16"><p>On a scale from 0 to 100, when 0 means mean and ten means nice, how would you rate Bob?</p>
<input type="range" min="1" max="100" value="50" class="slider" id="q1">
<p>Value: <span id="demo1"></span></p>
</span>
</div>
<div class="slidecontainer">
<span class="v50_17"><p>On a scale from 0 to 100, when 0 means bad and ten means good, how would you rate Bob?</p>
<input type="range" min="1" max="100" value="50" class="slider" id="q2">
<p>Value: <span id="demo2"></span></p>
</span>
</div>
</div>
you need to put variable vq1, vq2 inside callback of input event or call directly slider1.value inside Phase_E_action() function
and for download it need to append to the current page
var vq1, vq2;
var slider1 = document.getElementById("q1");
var demo1 = document.getElementById("demo1");
demo1.innerHTML = slider1.value;
slider1.oninput = function() {
// put the variable here
vq1 = demo1.innerHTML = this.value;
}
var slider2 = document.getElementById("q2");
var demo2 = document.getElementById("demo2");
demo2.innerHTML = slider2.value;
slider2.oninput = function() {
vq2 = demo2.innerHTML = this.value;
}
function Phase_E_action() {
var fileContent = vq1 + "," + vq2;
console.log(fileContent)
var bb = new Blob([fileContent], {
type: 'text/plain'
});
var a = document.createElement('a');
a.download = "Exp" + Date().toString().slice(4, 24) + ".csv";
a.href = window.URL.createObjectURL(bb);
a.innerHTML = 'fff'
document.body.appendChild(a)
a.click();
document.body.removeChild(a);
}
<div id="Phase_D">
<span class="v50_15">
<h1>Please state your opinion on Bob</h1>
</span>
<div class="slidecontainer">
<span class="v50_16">
<p>On a scale from 0 to 100, when 0 means mean and ten means nice, how would you rate Bob?</p>
<input type="range" min="1" max="100" value="50" class="slider" id="q1">
<p>Value: <span id="demo1"></span></p>
</span>
</div>
<div class="slidecontainer">
<span class="v50_17">
<p>On a scale from 0 to 100, when 0 means bad and ten means good, how would you rate Bob?</p>
<input type="range" min="1" max="100" value="50" class="slider" id="q2">
<p>Value: <span id="demo2"></span></p>
</span>
</div>
<button onclick="Phase_E_action()">
Download CSV
</button>
note: you can't use download function here because the iframe is sanboxed and allow-downloads flag is not set
I have a group of sliders, they can all take a value from 0 to 100. I need the total of the group to always be less than 100 as they are percentages. I use the max attribute and some simple math to prevent the total from surpassing this.
Originally I just changed the max value, however, this doesn't change the length of the slider just what value all the way right is. This would be confusing to the user as 50% of the bar could be all the way right when it used to be in the middle.
To combat this I used a container div and change the slider's width to the corresponding percentage of the containing div.
This works as intended, but the slider handle slightly moves whenever you change a sibling slider.
Is there a way to prevent these small movements.
Is there a completely different easier way to do this seemly simple task, using only pure js.
<form id="form">
<input id="incm" type="number" value="1000"/>
<ul>
<li>Slider 0
<div class="sliderContainer"><input class="slider" id="pct0" type="range" min="0" max="100" value = "50"/></div>
<output id="pctOutput0"></output>
<output id="amtOutput0"></output>
</li>
<li>Slider 1
<div class="sliderContainer"><input class="slider" id="pct1" type="range" min="0" max="100" value = "50"/></div>
<output id="pctOutput1"></output>
<output id="amtOutput1"></output>
</li>
<li>Slider 2
<div class="sliderContainer"><input class="slider" id="pct2" type="range" min="0" max="100" value = "0"/></div>
<output id="pctOutput2"></output>
<output id="amtOutput2"></output>
</li>
<li>Slider 3
<div class="sliderContainer"><input class="slider" id="pct3" type="range" min="0" max="100" value = "0"/></div>
<output id="pctOutput3"></output>
<output id="amtOutput3"></output>
</li>
<li>Slider 4
<div class="sliderContainer"><input class="slider" id="pct4" type="range" min="0" max="100" value = "0"/></div>
<output id="pctOutput4"></output>
<output id="amtOutput4"></output>
</li>
</ul>
<p><output id="pctSum"></output><output id="amtSum"></output></p>
</form>
function calc() {
var pct = [],
pctI = [],
amt = [],
incm = document.getElementById("incm").value
for (i = 0; i < 5; i++) {
pct[i] = document.getElementById("pct" + i).value
document.getElementById("pctOutput" + i).innerHTML = pct[i] + "%"
pctI[i] = parseInt(pct[i])
amt[i] = pctI[i] * 0.01 * incm
document.getElementById("amtOutput" + i).innerHTML = "£" + amt[i]
}
var pctSum = pctI.reduce((a,b) => a + b, 0)
var amtSum = amt.reduce((a,b) => a + b, 0)
document.getElementById("pctSum").innerHTML = "Total Percentage " + pctSum + "%"
document.getElementById("amtSum").innerHTML = "Total Amount £" + amtSum
for (i = 0; i < 5; i++) {
document.getElementById("pct" + i).max = 100 - pctSum + pctI[i]
document.getElementById("pct" + i).style.width = document.getElementById("pct" + i).max + "%"
}
}
document.getElementById("form").addEventListener("input", calc)
window.onload = calc()
JSFiddle https://jsfiddle.net/Zbedjajohnson/ca5b1psy/5/
Really interesting question. Here's what I've come up with.
function initSliderGroups() {
const sliderGroups = document.querySelectorAll(".sliderGroup");
for (let sliderGroup of sliderGroups) {
const sliders = [...sliderGroup.querySelectorAll(".slider")];
const max = sliderGroup.getAttribute('max');
sliders.forEach(slider => {
slider.max = max;
slider.min = 0;
const sliderContainer = document.createElement('span');
sliderContainer.style = 'position: relative;';
slider.parentNode.insertBefore(sliderContainer, slider);
sliderContainer.appendChild(slider);
const limitDiv = document.createElement('div');
limitDiv.className = 'limitDiv';
limitDiv.style = 'position: absolute; top: 4px; left: 0; z-index: 1; width: 0; height: 5px; background-color: #555; border-radius: 5px;';
sliderContainer.appendChild(limitDiv);
slider.addEventListener("input", () => onSliderInput(slider));
});
function onSliderInput(movingSlider) {
//limit sum of values to max (defined as 100 by .sliderGroup div attribute)
const usedByOthers = sliders.filter(s => s !== movingSlider).map(s => +s.value).reduce((a, b) => a + b);
const available = max - usedByOthers;
if (movingSlider.value > available) movingSlider.value = available;
//update limit bars
for (let slider of sliders) {
const limitDiv = slider.parentNode.querySelector('.limitDiv');
const usedByOthers = sliders.filter(s => s !== slider).map(s => +s.value).reduce((a, b) => a + b);
const available = max - usedByOthers;
const sliderWidth = slider.clientWidth + 1;
const leftOffset = sliderWidth * (available / max);
const width = sliderWidth - leftOffset;
const extraOffset = 17 * (max - available) / max;
limitDiv.style.left = Math.min(leftOffset + extraOffset, sliderWidth) + 'px';
limitDiv.style.width = Math.max(width - extraOffset, 0) + 'px';
}
}
//init
if (sliders[0]) onSliderInput(sliders[0]);
}
}
initSliderGroups();
<div class="sliderGroup" max="100">
<input class="slider" type="range" value="25" /><br/>
<input class="slider" type="range" value="0" /><br/>
<input class="slider" type="range" value="0" /><br/>
<input class="slider" type="range" value="0" /><br/>
</div>
Basically you just give all your slider inputs class="slider", wrap them in an element with class="sliderGroup" max="100", then call initSliderGroups() and it'll limit those sliders to a max combined value of 100 (and shows dark grey limit bars).
In your case you'd do the following:
Add class="sliderGroup" max="100" to your <ul>.
Add my javascript above your javascript.
Delete your for loop in calc that changes max and width of sliders.
I have an HTML element input of type range:
<body onload="rotar()">
<img src="#" id="locator" />
<input type="range" name="points" id="loop" min="1" max="20" data-show-value="true">
</body>
It goes basically like this: This page shows images that change dynamically and I want the slider with ID loop to change its value, just like the images so it moves according to them.
function rotar(){
var slider = document.getElementById("loop");
var locator = document.getElementById('locator'),
dir = 'static/visor/img/',
delayInSeconds = 3,
num = 1,
len = 20;
setInterval(function(){
locator.src = dir + num+'.png';
if (num === len){
num = 1;
}
else{
num++;
}
slider.value = num;
}, delayInSeconds * 50);}
I don't have any image dir so i just did it with an simple input. please check this http://jsfiddle.net/maxofpower/tAs6V/275/
<body onload="rotar()">
<form ><div>
<input id="loop" onchange="amount.value=rangeInput.value" oninput="amount.value=rangeInput.value" type="range" min="0" max="200" name="rangeInput" />
<input id="box" type="text" value="0" name="amount" for="rangeInput" oninput="rangeInput.value=amount.value" />
</div></form>
</body>
<script>
function rotar() {
var slider = document.getElementById("loop");
var num = 1;
setInterval(function(){
slider.value = num++;
}, 500);
};
</script>
Your issue is with the delay passed to the setInterval method, as the delay argument is in milliseconds, to get 2.8 seconds you'd have to multiply the delayInSeconds variable by 1000.
You had some mistakes in your code, you refreferenced the img#locator element with the variable name rotator the you used the variable name locator, which will cause an Undefined variable error. Im my answer I changed the variable's name from rotator to locator, also I made the delay to 2.8 seconds.
Here's a demo:
function rotar() {
var slider = document.getElementById("loop"),
locator = document.getElementById('locator'),
dir = 'static/visor/img/',
delayInSeconds = 2.8,
num = 1,
len = 20;
setInterval(function() {
locator.src = dir + num + '.png';
num = (num === len) ? 1:num + 1;
slider.value = num;
}, delayInSeconds * 1000);
}
<body onload="rotar()">
<img src="#" id="locator" />
<input type="range" name="points" id="loop" min="1" max="20" data-show-value="true">
</body>