Disable certain range in rangeslider.js - javascript

I am using rangeslider.js and I am trying to disable the slider to slide below 20
<input type="range" class="range-slider" value="30" min="0" max="100" from="0" step="1">
I am using start attribute to make that work but it doesn't work that way.
here is the fiddle https://jsfiddle.net/moviecrew/awejnkof/16/

if you set min attribute to 20 then it will create range slider value start from 20
or if you need value must start from 0 to 100 and prevent below 20 then you can try below solution
$('input[type="range"]').rangeslider({
polyfill: false,
onSlide: function(position, value) {
if(value < 20){
$('input[type="range"]').val(20);
$('input[type="range"]').rangeslider('update', true);
}
}
});

Related

Fixed point at 0 in Slider range component

Slider has range, max, min, and two possible value. One of value is set fixed at 0, another one can drag to change value In my website, I tried to construct a slider with a range from -10 to 10. There are two possible value input in slider, one value is 0 and it is fixed. Another value can drag and show the value based on the value to 0.
I initially want to disable one of the value input, but it does not work out, and I want to display like this:
[-10] |---------------------|[0]|-----------<->-----------| [ 10]
or
[-10] |----------<->-----------|[0]|----------------------| [ 10]
but not like start from -10.
[-10] |-------------------------------<->------------| [ 10]
It will render the range from 0 to 10 or 0 to -10, but not from -10 to a point. 0 as the fixed number in the slider.
I'm not sure where to start, any suggestions would be appreciated.
You can listen input event and prevent less / more than you want. I made a little hack. But you have to multiply the value of the second input by minus.
const inputs = document.querySelectorAll("input");
inputs.forEach(p => {
p.addEventListener("input", () => {
if (event.target.value >= 0) {
event.target.value = 0;
}
if (event.target.id == "inp1") {
console.log("first input's value: " + event.target.value)
}
if (event.target.id == "inp2") {
console.log("second input's value: " + event.target.value * -1)
}
});
});
#inp2 {
transform: rotate(180deg);
}
<input type="range" id="inp1" min="-10" max="10">
<input type="range" id="inp2" min="-10" max="10">

Input range move only by one step

I'm trying to use input range moving one by one. For exemple here is my slider :
<input id="replay-input" type="range" min="0" max="100" step="1" value="0">
Really basic. But the problem is that you can freely move from 5 to 89 by one click. What I would like to achieve is to increment or decrements only by one so my value will look like this is if I move the cursor :
0 -> 1 -> 2 -> 3 -> 4
Then if I go back :
4 -> 3 -> 2 -> 1 -> 0
With big max like 5000 we have missing steps because there is too many values on a small area :
4800 -> 4799 -> 4790 -> 4785
Is there a way to avoid this ? One idea may be to use JS and store value and only allow change of one but maybe there is something more simple in HTML ?
https://jsfiddle.net/vcoyxg4v/5/
Thanks !
I would not suggest limiting the default functionality of the slider control, as people expect it to work in a certain way: think also of dragging the slider, using the arrow/page/home/end keys when the control has focus, ...
But for the sake of the exercise, here is code that will make the slider value only increase/decrease with 1. So if you drag, the value will slowly catch up with the mouse position. This solution uses a data property to keep track of the previous value:
$('#replay-input').data({
was: $('#replay-input').val()
}).on('input', function () {
var data = $(this).data();
$(this).data({
was: this.value = +data.was + (this.value > data.was || -1)
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="replay-input" type="range" min="0" max="100" step="1" value="0">
Using animation
As an extension to this idea, you could use the animate method to take care of the progression towards the target value:
$('#replay-input').data({
current: $('#replay-input').val()
}).on('input', function () {
var data = $(this).data(),
value = this.value;
$(this).data(data = {
current: this.value = +data.current, // restore previous value
}).stop().animate({ value }, { // ... and animate towards the target
duration: 500, // Experiment with other durations...
easing: 'swing', // Experiment with other easing values...
step: function(val) {
$(this).data({current: this.value}) // accept change
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="replay-input" type="range" min="0" max="100" step="1" value="0">
As indicated in the comments, you can experiment a bit with the animation options duration and ease to tailor it to your needs.
There is a slight visual glitch just after a click because the slider also receives an input event on mouseup.

Working with a set of range sliders. Fix my jsfiddle?

I need my three range sliders to share from a common "value pool." So if the max is 100, and slider-1 is set to 51. you should expect slider-2 and 3 to take from a shared pool of 49. The way I have it now, if you change slider 1, slider 2 and 3 are equal. This is not ideal!
How would you go about making it so I could set slider-1 to a value of "51" for example,
and then set slider-2 to a value of "30" making slider-3 automatically "19".
And then from there, if I bump slider 3 with a value of "19" up to "20" for example, slider-2 changes to "29.5" and slider-1 changes to "50.5"
Here is a jsfiddle, hope my question makes sense:
https://jsfiddle.net/7ho3zfve/
There are a few things to note: first, you are really using redundant code. If you decide later to add more inputs, you're doing the same thing multiple times. Instead, use classes. You can have a single function or collection of functions that work on all inputs, as the behavior is going to be the same across them all.
Now, if I understand you correctly, you want a set max value to be respected, and any elements that have NOT yet been manually moved, to have their values set to an equal portion of the remaining max value? The code below will do that. It includes a draggable detector (basically, the sliders have a mousedown event that sets the isDragging, and the mousemove event checks that it is, in fact, dragging), which is when the remainder of the maxVal is split. The code is pretty heavily commented, it should get you most of the way to what you're looking for.
The one thing I haven't really worked on yet, and potentially a big pitfall, is that, when two of the three sliders have been manually set, you can still move the THIRD slider to the right. I'm guessing you'd want to catch that, but I haven't worked out that logic yet.
var maxVal = 1000,
isDragging = false,
fixedEls, flexEls;
/***
* Tracking the dragging -- on mousedown, I set the isDragging
* to true, then I check that for the mousemove on this element.
* On mouseup, I reset the isDragging to false, thus ending the
* simulated drag event.
***/
$(".slide-control").on("mousemove", function() {
if (isDragging) {
// I want to keep two collections of sibling elements:
// those that have NOT been moved, and those that HAVE.
// I simply add the .slider-fixed to those that have,
// which are elements I don't want to be moveable later.
fixedEls = $(this).siblings("input.slider-fixed");
flexEls = $(this).siblings("input").not(".slider-fixed");
// The subtotal I will be using is simply the current
// slider element plus any elements that have already had
// their .slider-fixed class set. The resulting value,
// subtracted from the above maxVal, will be the pool of
// values for any non-fixed sliders.
var subtotal = parseInt($(this).val());
fixedEls.each(function() {
subtotal += parseInt($(this).val());
});
// The sharedVals is the remaining value, evenly split
// between all moveable elements.
var sharedVals = (maxVal - subtotal) / flexEls.length;
// Set the element's val to that sharedVal.
flexEls.each(function() {
$(this).val(sharedVals)
})
/***
* The following lines simply output the values of each slider
* to the results pane. Not a necessity, more a debug thing.
***/
$(".results").empty();
$(this).parent().children("input").each(function() {
var myHtml = "<p>Slider " + $(this).prop("id") + ": " + $(this).val() + "</p>"
$(".results").append(myHtml);
})
}
}).on("mouseup", function() {
// When the drag event has ended, set the toggle off.
isDragging = false;
// I don't want this particular slider affected by any other
// movements.
$(this).addClass("slider-fixed");
}).on("mousedown", function() {
isDragging = true;
});
.slide-control {
display: block;
margin-left: 20px;
}
.slider-fixed::before {
margin-left: -20px;
content: ">>";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="header">
<h3>A slider control</h3>
<h4>Note: >> beside a slider indicates that it won't be affected by any further movement of other sliders.</h4>
</div>
<input type="range" id="myRange" value="0" min="0" max="1000" class="slide-control">
<input type="range" id="myRange2" value="0" min="0" max="1000" class="slide-control">
<input type="range" id="myRange3" value="0" min="0" max="1000" class="slide-control">
<div class="results">
</div>
Went with CumminUp07's library suggestion here:keith-wood.name/linkedsliders.html to accomplish this.
Thanks everyone for putting together some useful information and code on this thread.

Change step in HTML5 <input type="range"> on certain value

I'm trying to do an HTML5 <input type="range"> that has:
Minimum value: 50
Maximum value: 2000
Default value: 50
Step: 50
<input name="flevel_gigas" id="flying" type="range" min="50" max="2000" value="50">
When the user passes 500, the step of the input will change from 50 to 250 up to 2000.
I'm doing it with JQuery. The code is:
<script>
$(function(){
function returnStep(value) {
var step;
if(value<500){
step=50;
}
else{
step=250;
}
return step;
}
$('input[name="flevel_gigas"]').on("input change",function(){
var currentValue = $(this).val();
$(this).attr('step', returnStep(currentValue));
});
});
</script>
But it not works. When the slider is at 450 it jumps to 550 then the step changes to 250 and starts counting correctly but only until 1800 (because 1800 plus 250 is 2050 and it exceeds 2000).
Could anyone help me where is the error or the misunderstanding of the range's perfomance?
The problem here is that valid numbers are min + N * step for some integer N.
In your case, valid numbers are (with the bigger step) 50 + N * 250, which is 300 (not seen by the user in your case) 550, 800 and so on.
You will need to change the min to 0 when your step changes - it's a bit of a hack but it will provide a more functional "start value" for your increased step.
you can check this code
html code is this , set min value 0
<input name="flevel_gigas" id="flying" type="range" min="0" max="2000" value="50">
and jQuery Code
<script>
$(function(){
function returnStep(value) {
var step;
if(value<500){
step=50;
}
else{
step=250;
}
return step;
}
$('input[name="flevel_gigas"]').on("input change",function(){
var currentValue = $(this).val();
var step = returnStep(currentValue);
$(this).attr('step', step);
});
});
</script>

jquery scrollTop is bouncing

What did I do wrong? My skill bars are dancing. After loading I want to fixed them.
Check my pen here : http://codepen.io/anon/pen/KdEeWW
$(window).scroll(function() {
if ($(this).scrollTop() > 300) {
$('progress').each(function() {
var max = $(this).val();
$(this).val(0).animate({
value: max
}, {
duration: 2000,
easing: 'easeOutCirc'
});
});
};
});
Your skillbars were dancing because you have written the event on scroll. So if you scroll twice before completion of animation, then it will begin again and also you are not checking whether your animation has been performed.
Just .stop the animation before animating as below:
$(this).stop().val(0).animate({
value: max
}, {
duration: 2000,
easing: 'easeOutCirc'
});
Fiddle DEMO
Update
There is a bug in the way you are doing it right now. Your original value gets overridden every time you scroll thus giving space for less progress display every time. So what you need to do is, store original value in some data-* attribute of each element and set value every time from original value and thus you can also make you value=0 each time. Below changes will accommodate you with the above effect.
HTML
<progress value="80" data-originalvalue="80" max="100"></progress>
//^^^^To store original value
<span>JavaScript/jQuery</span>
<progress value="70" data-originalvalue="70" max="100"></progress>
<span>HTML5/CSS3</span>
<progress value="60" data-originalvalue="60" max="100"></progress>
<span>NodeJS</span>
<progress value="70" data-originalvalue="70" max="100"></progress>
<span>Java/PHP</span>
<progress value="60" data-originalvalue="60" max="100"></progress>
<span>MySQL</span>
<progress value="80" data-originalvalue="80" max="100"></progress>
<span>Photoshop</span>
You JS now would be
$(window).scroll(function() {
if ($(this).scrollTop() > 300) {
$('progress').each(function() {
var max = $(this).data('originalvalue'); //get from data-originalvalue attribute
$(this).val('0').stop().animate({
value: max
}, {
duration: 2000,
easing: 'easeOutCirc'
});
});
};
});
Updated DEMO
Now if you want it to animate only once when it hits users view, you just need to set a global variable value and add one more condition, as below:
var isAnimated=false; //global variable
$(window).scroll(function() {
if ($(this).scrollTop() > 300 && !isAnimated) {//Also check if animated
$('progress').each(function() {
var max = $(this).data('originalvalue');
$(this).val('0');
$(this).stop().animate({
value: max
}, {
duration: 2000,
easing: 'easeOutCirc'
});
});
isAnimated=true;//once done set it to true so that animation will not repeat.
};
});
One time animation demo
It is because you set your value 0 everytime. you can try this. It is easy to implement and you don't need to maintain all this.
http://mynameismatthieu.com/WOW/

Categories

Resources