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
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>
I'm trying to make it give me the value that I put in at "summe:" when changing the numbers without actually clicking the calc button how do I do that? I tried with onchange but I cant figure out how to do it
const btncalc = document.querySelector('.calcit');
const summetext = document.querySelector('.summe');
const backend = document.querySelector('.backenduser');
backend.addEventListener('onchange', function() {
var backendanzahl = document.getElementsByClassName("backenduser")[0].value;
var appanzahl = document.getElementsByClassName("appuser")[0].value;
var mytext = "Anzahl der Summe:" + (+backendanzahl * 35 + +appanzahl * 7.5);
summetext.textContent = mytext;
});
App-Benutzer: <input type="number" placeholder="1-100" min="0" max="100" oninput="this.value = this.value > 100 ? 100 : Math.abs(this.value)" class='appuser'></input><br> Backendbenutzer: <input type="number" placeholder="1-15" min="1" max="15" oninput="this.value = this.value > 15 ? 15 : Math.abs(this.value)"
class='backenduser'></input><br>
<button class='calcit'>Berechnen</button><br>
<span class='summe'>0.00</span><br>
Use querySelectorAll to get references to both fields. And then forEach to apply event listener to both. Also as any points out the event you are looking for is change.
const btncalc = document.querySelector('.calcit');
const summetext = document.querySelector('.summe');
const backend = document.querySelector('.backenduser');
const updateOnChange = document.querySelectorAll('.update-on-change');
updateOnChange.forEach(input => {
input.addEventListener('change', function() {
var backendanzahl = document.getElementsByClassName("backenduser")[0].value;
var appanzahl = document.getElementsByClassName("appuser")[0].value;
var mytext = "Anzahl der Summe:" + (+backendanzahl * 35 + +appanzahl * 7.5);
summetext.textContent = mytext;
})
});
App-Benutzer: <input type="number" placeholder="1-100" min="0" max="100" oninput="this.value = this.value > 100 ? 100 : Math.abs(this.value)" class='appuser update-on-change'></input><br> Backendbenutzer: <input type="number" placeholder="1-15" min="1" max="15" oninput="this.value = this.value > 15 ? 15 : Math.abs(this.value)"
class='backenduser update-on-change'></input><br>
<button class='calcit'>Berechnen</button><br>
<span class='summe'>0.00</span><br>
Add an input handler. Change event only triggers when the element has lost focus.
element.addEventListener('input', function (evt) {
//do your stuff here
});
From MDN
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>
I'm trying to obtain a value out of an HTML slider so I can dynamically use it as an integer in JavaScript.The problem I'm having is I can't seem to use the value as a proper integer.
For example, if my slider value was 5 & if l tried to store it in a variable and add 10, it would output as '510' instead.
Maybe I'm an idiot and missing something very fundamental or simple, but it always ends up as a string in the end.I have tried parseInt() as well, but it doesn't seem to help.
I've set up a simple example of code below:
JS
var sliderUnit = document.getElementById("slider");
var outputUnit = document.getElementById("amtOutput");
var a = 0;
var b = 10;
outputUnit.innerHTML = sliderUnit.value;
sliderUnit.oninput = function(){
outputUnit.innerHTML = this.value;
console.log(sliderUnit.value);
a = this.value;
parseInt(a);
}
function test(){
b += a;
console.log("b: " + b + " | a: " + a);
}
HTML
<div class="sliderContainer">
<input type="range" min="1" max="15" value="7" id="slider">
<input type="submit" value="Submit" onclick="test()" />
| Slider number: <span id="amtOutput"></span>
</div>
The problem is that your are calling the parseInt(a) but the returned Integer value is not being handled properly, you should do as this a = parseInt(a);
var sliderUnit = document.getElementById("slider");
var outputUnit = document.getElementById("amtOutput");
var a = 0;
var b = 10;
outputUnit.innerHTML = sliderUnit.value;
sliderUnit.oninput = function(){
outputUnit.innerHTML = this.value;
console.log(sliderUnit.value);
a = this.value;
a = parseInt(a); // Change this line
}
function test(){
b += a;
console.log("b: " + b + " | a: " + a);
}
<div class="sliderContainer">
<input type="range" min="1" max="15" value="7" id="slider">
<input type="submit" value="Submit" onclick="test()" />
| Slider number: <span id="amtOutput"></span>
</div>
If not the variable a will continue to be a string becouse it wasn't changed
You need to parse the string as int using parseInt.
Working code:
var sliderUnit = document.getElementById("slider");
var outputUnit = document.getElementById("amtOutput");
var a = 0;
var b = 10;
outputUnit.innerHTML = sliderUnit.value;
sliderUnit.oninput = function(){
outputUnit.innerHTML = this.value;
console.log(sliderUnit.value);
a = this.value;
parseInt(a);
}
function test(){
b = parseInt(b)
a = parseInt(a);
b += a;
console.log("b: " + b + " | a: " + a);
}
<div class="sliderContainer">
<input type="range" min="1" max="15" value="7" id="slider">
<input type="submit" value="Submit" onclick="test()" />
| Slider number: <span id="amtOutput"></span>
</div>
Working JSFiddle
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.