JQuery slider with fixed minimum value - javascript

I'm trying to make a slider where :
the min/max values are 0/100% (That I can do)
it has a fixed first value that cannot be change and is filled with a color (Let say 30% for the example)
it has an handler to complete the previous value (eg: From 30% to 100%) and will be filled with another color.
Here is that it should look like. '=' is the fixed first value, '-' is what we add, '_' is what remains :
[===|_____] A first
[===------|_] When we move the handler
I tried to make it with a range slider, hiding the first handler but I had a problem with the color thing. All I did was putting a color to the entire background, which is not my goal.

Create a div with background-color for each handler and append them to slider.
$(document).ready(function () {
var minFixedValue = 10;
var maxValue = 30;
var updateEvent = function (event, ui) {
if (ui != undefined) {
var index = $(ui.handle).index();
if (index === 1) return false;
}
$('#slide1 .slide-back').remove();
var backgrouldColorSettings = ['blue', 'grey']
$($('#slide1 a').get().reverse()).each(function (i) {
$('#slide1').append(
$('<div></div>').addClass('slide-back')
.width($(this).offset().left - 5)
.css('background', backgrouldColorSettings[i]));
});
};
$('#slide1').slider({
range: true,
slide: updateEvent,
change: updateEvent,
values: [minFixedValue, maxValue]
});
updateEvent();
});
See jsFilddler here

Related

Get last viewed index with Scrollify

I'm using scrollify to swap out fixed position components, and adding/removing classes to animate the transition. I have everything working as I'd like as you progress forward through the scroll, but when you scroll up to see a previous section, its not removing the previous class, and the previous section now animates in behind it.
I don't think the prev method will be of use, because it doesn't call the previous section your were at, only the previous section assuming you are always moving forward.
Here is my code below, you can move forward just fine, but trying to go backwards presents a problem as the new current section will load behind the previous one, and the previous one will still be visible.
jsfilddle here
var wrapper = $('.wrapper');
var currentPosition = 0;
$(wrapper).each(function(index) {
if (currentPosition != index) {
$(this).css('opacity', 0);
} else if (currentPosition == index) {
$(this).css('opacity', 1);
}
});
$(function() {
$.scrollify({
section: ".wrapper",
scrollSpeed: 700,
setHeights: false,
after: function(index, sections) {
var prevWrapper = $.scrollify.current().prev();
var currentWrapper = $.scrollify.current();
var nextWrapper = $.scrollify.current().next();
$(prevWrapper).removeClass('wrapper-enter').addClass('wrapper-leave');
$(currentWrapper).removeClass('wrapper-leave').addClass('wrapper-enter');
},
});
});
The issue is depending on scrolling up or down your "next" or "prev" may not actually be what you think so you are hiding classes incorrectly.
What you could do as scrollify doesn't have an option to detect scroll direction is to create a super quick variable that will detect if you are scrolling up or down. Then simply update your classes then in the after function.
$.scrollify({
section: ".wrapper",
scrollSpeed: 700,
setHeights: false,
after: function(index, sections) {
var prevWrapper = $.scrollify.current().prev();
var currentWrapper = $.scrollify.current();
var nextWrapper = $.scrollify.current().next();
let elem = null;
// Add wrapper-enter to current element.
$(currentWrapper).removeClass('wrapper-leave').addClass('wrapper-enter');
if(lastIndex < index) {
// Scolled down if lastIndex < index
elem = prevWrapper;
} else {
// Scrolled up if last index > index
elem = nextWrapper;
}
$(elem).removeClass('wrapper-enter').addClass('wrapper-leave');
lastIndex = index;
},
In the above I simply created a variable to track the last index.
Here is a working fiddle: https://jsfiddle.net/k1e6x79f/

Bootstrap slider - prevent flipping the two cursors and stop slide

I would like to use Bootstrap slider to represent 3 lengths of axes whose sum doesn't change (the max value of the slider corresponds to this sum).
So I have 2 cursors on bootstrap slider and the 3 intervals represent these lengths.
Here's an example: bootstrap with two cursors
My issue is that I would like to stop dragging the second cursor (on the right) when it is equal (or nearly with a fixed step) to the first one (on the left) and inversely for the first cursor.
I saw there's an slide stop event but this doesn't seem to be the same thing.
I have surely to modify the bootstrap-slider.js source but I don't know how to do for implementing this specific functionality.
It would be like:
slider.on("slide", function(slideEvt) {
if ((cursor2.value - cursor1.value) < step)
{ this.stopSlide();}
});
Using slides events it's possible. The idea is to see which cursor is fixed, and when its value change, block the slide movement, by setting value.
Didn't find a cleaner way to block slide event...
Working code :
var slider = new Slider("#slider1");
var initPos,
fixedCursor,
fixedCursorPos;
slider.on("slideStart", function(slideEvt) {
initPos = slideEvt;
fixedCursor = null;
fixedCursorPos = null;
});
slider.on("slide", function(slideEvt) {
if (initPos[0] !== initPos[1] && (slideEvt[0] !== initPos[0] || slideEvt[1] !== initPos[1])) {
if (fixedCursor == null) {
fixedCursor = (slideEvt[0] === initPos[0] ? 0 : 1);
fixedCursorPos = slideEvt[fixedCursor];
}
if (fixedCursorPos !== slideEvt[fixedCursor]) {
slider.setValue([fixedCursorPos, fixedCursorPos], false, false);
}
}
});
Working JS Bin : http://jsbin.com/kopakiciti/1/edit?html,js,output

JS chart knob: animate from value to value rather than 0

I have this animated donut that changes value on li hover. However, currently it resets to 0 and then animates to the new value. Ideally it should animated from value to value.
Here's a JSFiddle: http://jsfiddle.net/jme11/xx2Ky/
My JS:
var dial = $('.dial');
dial.knob({
readOnly: true
});
$('.pets > li').on('mouseenter', function () {
var button = $(this);
var myVal = button.data('value');
button.css('backgroundColor', 'yellowgreen').siblings().css('backgroundColor', '#ccc');
dial.stop().animate({
value: myVal
}, {
duration: 200,
easing: 'swing',
step: function () {
dial.val(Math.ceil(this.value)).trigger('change');
},
complete: function () {
dial.val(myVal + '%');
}
});
});
I have located the problem; it's this:
dial.val(myVal + '%');
When you animate something with a val attribute, it automatically uses that val value as its starting point. However, your code is setting val to a string. jQuery then gets confused and defaults to 0 the next time you want to animate. If you change the line to
dial.val(myVal);
you'll see it works as desired—with the obvious drawback that you lose your percent sign. You can add it back with knob's format feature, seen here, but I can't get it to work in your jsFiddle.

Fading an element onfocus and onblur

I have a single word counter on the page that counts the number of characters for each input element.
When an input element is focused, a fadeIn function is triggered to fade in the counter element. When the input element loses focus i.e. is blurred, a fadeOut function is triggered on the counter.
However when you focus and blur the elements several times and in fast intervals with either the mouse or the keyboard, the fade effect is noticed less and less. The counter which fades in and out ends up only blinking between opacity: 0 and 1. A page refresh is required to achieve the fade effect again, until it screws up again.
This problem is also triggered if you tab through all elements and regain your initial focus on the browser address bar.
Why does this happen? Could it have something to do with the fade function and setInterval?
Here's an example fade function I use from http://www.scriptiny.com :
var fadeEffect=function(){
return{
init:function(id, flag, target){
this.elem = document.getElementById(id);
clearInterval(this.elem.si);
this.target = target ? target : flag ? 100 : 0;
this.flag = flag || -1;
this.alpha = this.elem.style.opacity ? parseFloat(this.elem.style.opacity) * 100 : 0;
this.si = setInterval(function(){fadeEffect.tween()}, 20);
},
tween:function(){
if(this.alpha == this.target){
clearInterval(this.elem.si);
}else{
var value = Math.round(this.alpha + ((this.target - this.alpha) * .05)) + (1 * this.flag);
this.elem.style.opacity = value / 100;
this.elem.style.filter = 'alpha(opacity=' + value + ')';
this.alpha = value
}
}
}
}();
Perhaps it's because you're not doing clearInterval() properly. You are setting the interval like this:
this.si = setInterval();
but clearing the interval like this:
clearInterval(this.elem.si)
Shouldn't they both be this.si or both be this.elem.si?
Also, how are you invoking fadeEffect? Are you using new fadeEffect()? Are you sure that this is being handled properly when you call methods?
Using jquery probably you are looking for such behaviour:
$(document).ready(function () {
$('#test').fadeTo('fast', 0.5); // to set default opacity. CSS can be used here
$('#test').focus(function () {
$(this).fadeTo('fast', 1);
}).blur(function () {
$(this).fadeTo('fast', 0.5);
});
});
here is live example: http://jsfiddle.net/hrzw7/1/
if you have a lot of such controls, use .class selector: http://jsfiddle.net/hrzw7/3/

Implementing a Parameter to a plugin - Shows 'X' number of elements

The current plugin, shown below, scrolls the top-most div in a series of divs with the same class upwards, then removes it from the container, and appends it to the bottom of the series (within the container). This gives the illusion of a vertical slideshow.
$.fn.rotateEach = function ( opts ) {
var $this = this,
defaults = {
delay: 5000
},
settings = $.extend(defaults, opts),
rotator = function ($elems) {
$elems.eq(0).slideUp(500, function(){
var $eq0 = $elems.eq(0).detach();
$elems.parent().append($eq0);
$eq0.fadeIn();
setTimeout(function(){ rotator( $($elems.selector) ); },
settings.delay);
});
};
setTimeout(function(){ rotator( $this ); }, settings.delay);
};
$('.dynPanelContent').rotateEach();
However, if there are a large number of elements to scroll through, this would make for a VERY long page. As such, I am attempting to re-write this script so that it accepts a parameter which will determine how many elements to display. Any elements exceeding this number will be hidden until they are in the top 'x' number of elements. Here is an example of what I have attempted to implement.
$.fn.rotateEach = function (opts) {
var $this = this,
defaults = {
delay: 5000,
//Add a parameter named elementsShown, pass in a default value of 3
elementsShown: 3
},
settings = $.extend(defaults, opts),
rotator = function ($elems) {
//Hide the elements that are past the number to be shown
for (i = settings.elementsShown; i <= $elems.eq; i++) {
$elems.eq(i).hide();
}
$elems.eq(0).slideUp(500, function () {
var $eq0 = $elems.eq(0).detach();
var $eqN = $elems.eq(settings.elementsShown) - 1;
//Check & Show the element that is now within the show range
if ($elems.eq() == $eqN) {
$elems.eq($eqN).show('slow');
}
$elems.parent().append($eq0);
$eq0.fadeIn();
setTimeout(function () { rotator($($elems.selector)); },
settings.delay);
});
};
You can use simple CSS for this, mate.
If your elements are all of the same height (which your problem has to assume: if you are rotating a whole bunch of things dynamically, you won't want your page to change height), then you don't really need to use JavaScript for this at all. Just set the height of the container to what you want and hide the overflow. Then when you remove and append, everything appears to work. This won't take care of your dynamic configuration, though.
Improved plug-in: http://jsfiddle.net/morrison/tTJaM/
Notes:
Added support for showing X elements.
Added support for rotating only certain elements.
Added support for stopping the rotations:
Stop after X milliseconds.
Stop after X rotations.
overflow-y:hidden is added to container dynamically.
Simplified your detaching/attaching.
Known Issues:
Displaying X elements doesn't check for a maximum.

Categories

Resources