Using offset and jQuery slider - javascript

I am using offset() with the jquery slider and I am so close to achieving my goal, but it is off slighty. I have it animating using animate to the top CSS coordinates but if you check out: http://www.ryancoughlin.com/demos/interactive-slider/index.html - you will see what it is doing. My goal is to have it fadeIn() and display the value to the right of the handle. i know I can offset the text from the handle using a simple margin:0 0 0 20px.
The part is aligning #current_value to the right of the handle. Thoughts?
var slide_int = null;
$(function(){
$("h4.code").click(function () {
$("div#info").toggle("slow");
});
$('#slider').slider({
animate: true,
step: 1,
min: 1,
orientation: 'vertical',
max: 10,
start: function(event, ui){
$('#current_value').empty();
slide_int = setInterval(update_slider, 10);
},
slide: function(event, ui){
setTimeout(update_slider, 10);
},
stop: function(event, ui){
clearInterval(slide_int);
slide_int = null;
}
});
});
function update_slider(){
var offset = $('.ui-slider-handle').offset();
var value = $('#slider').slider('option', 'value');
$('#current_value').text('Value is '+value).css({top:offset.top });
$('#current_value').fadeIn();
}
I know I could use margin to offset it to match, but is there a better way?

There are two problems. The first, like Prestaul said, the slider event fires at the "beginning" of the move, not the end, so the offset is wrong. You could fix this by setting a timeout:
$(function(){
slide: function(event, ui){
setTimeout(update_slider, 10);
},
...
});
function update_slider()
{
var offset = $('.ui-slider-handle').offset();
var value = $('#slider').slider('option', 'value');
$('#current_value').text('Value is '+value).animate({top:offset.top }, 1000 )
$('#current_value').fadeIn();
}
The second problem is that the move is instantaneous, while the animation is not, meaning that the label will lag behind the slider. The best I've come up with is this:
var slide_int = null;
$(function(){
...
start: function(event, ui){
$('#current_value').empty();
// update the slider every 10ms
slide_int = setInterval(update_slider, 10);
},
stop: function(event, ui){
// remove the interval
clearInterval(slide_int);
slide_int = null;
},
...
});
function update_slider()
{
var offset = $('.ui-slider-handle').offset();
var value = $('#slider').slider('option', 'value');
$('#current_value').text('Value is '+value).css({top:offset.top });
$('#current_value').fadeIn();
}
By using css instead of animate, you keep it always next to the slider, in exchange for smooth transitions. Hope this helps!

I had the same problem: the visible value in Jquery Ui slider lags behind from internal value. Fixed the problem by changing the slider event from "slide" to "change".

You just need to use a different event. "slide" fires before the handle is moved so your value is ending up at the previous handle position. Try the "change" event and see if that gets you there.

Related

My jQuery UI slider's animation is buggy and it's freezing the whole page occasionally, how is my code wrong?

Updated! Again...
I'm pretty new to javascript and I'm learning online but this is the point where I'm stuck.
I was trying to make audio controls for a site (for practice) and since I lack the knowledge to make my own, I decided to use jQuery UI slider. I made a for loop to apply the controls for every future audio element.
The problems are: The slider's handle's left and right border are moving slightly differently when the audio is playing and if I abuse the slider (like moving it fast, left to right) my whole page freezes and requires reload. I'm pretty sure it's my fault, because my code doesn't work at JSFiddle at all.
I uploaded the relevant part of my code here, since JSFiddle couldn't handle the code: https://drive.google.com/open?id=0B3_Wf6a8uWCYN2x6WEgyWGJ3Xzg
The slider is not working here, but I hope someone can find what have I done wrong.
The javascript code of the slider:
// sets up the controls for the audios
$("audio").each(function() {
// calls play/pause on click
var currentAudio = $(this)
var currentAudioDom = $(currentAudio).get(0)
var containerId = $(currentAudio).attr("id") + "-container";
$("#" + containerId).click(function() {
playPause(currentAudioDom)
});
// sets up the slider
var sliderId = $(currentAudio).attr("id") + "-slider";
var audioSlider = $("#" + sliderId);
// slider controls the audio
currentAudioDom.addEventListener("loadedmetadata", function() {
var audioDuration = currentAudio.prop("duration")
audioSlider.slider({
max: audioDuration,
step: 0.1,
animate: "slow",
slide: function(event, ui) {
currentAudioDom.currentTime = ui.value
if (currentAudioDom.paused === false) {
currentAudioDom.muted = true;
}
},
stop: function(event, ui) {
currentAudioDom.muted = false;
}
})
});
// audio conrols the slider
$(currentAudio).on("playing", function() {
setInterval(function() {
$(audioSlider).slider("option", "value", currentAudioDom.currentTime)

unable to return result using jquery

I'm using jquery UI's slider and i want to return the results from multiple sliders so I can performs a calculation.
this is what i have so far but I'm struggling to get any results from out side the function.
$(function() {
var x
$("#slider4").slider({
value: 1,
min: 0,
max: 50,
step: 5,
slide: function(event, ui) {
$("#items").val("$" + ui.value);
x =$("#items").val("$" + ui.value);
}
});
$("#items").val("$" + $("#slider4").slider("value"));
console.log(x) // this doesnt update the console with the slider value
});
Ideally outside the function i would want to add multiple slider results similar to below.
var z = x * y;
To get the value of the slider outside of the slide handler you can either retrieve the value of #items (as you update that within the slide handler):
var sliderValue = $('#items').val();
Or you can read the value from the slider() directly:
var sliderValue = $('#slier4').slider('option', 'value');
Also, note that you do not need to append empty strings when setting val():
$("#slider4").slider({
value: 1,
min: 0,
max: 50,
step: 5,
slide: function(event, ui) {
$("#items").val(ui.value);
}
});
The value does not magically keep updating the textbox, you need to write code that updates the value when the slider value changes. So add a change event
change: function( event, ui ) { $("#items").val(ui.value); }

Fullcalendar v2: How to maintain the same scroll time when navigating weeks?

On Fullcalendar 2, when I navigate between weeks, I'd like to maintain the same time ranges in the vertical scroll. For example, in the below images, I am initially looking at times from 12am-3pm. But when I press the next arrow to go to the next week, it resets at 8am.
I know that I can change the default starting time with
scrollTime: "08:00:00",
but how do I make it so that the vertical time range is "fixed" to what I am on?
Unfortunately this is not build-in functionality. There is a workaround but you will always have a little bit of flickering when you go to the previous/next week.
var scroll = -1,
viewNames = ['agendaWeek', 'agendaDay'];
$('#calendar').fullCalendar({
//...
eventAfterAllRender: function(view) {
if(scroll > -1 && viewNames.indexOf(view.name) !== -1)
//Use a setTimeout hack here because the scrollTime will be set after eventAfterAllRender is processed.
setTimeout(function(){
document.querySelector('.fc-agenda-slots').parentNode.parentNode.scrollTop = scroll;
}, 0);
},
viewDestroy: function(view) {
if(viewNames.indexOf(view.name) !== -1)
scroll = document.querySelector('.fc-agenda-slots').parentNode.parentNode.scrollTop;
}
//...
});
jsfiddle
This code will work for FullCalendar v2. It assumes that the scrolling div is the parent of the parent of the .fc-agenda-slots div.
Working Code compatible with fullcalendar 2.6.1
I started this code from the post below (A1rPun).
Working JSFiddle
var scroll = -1;
$('#calendar').fullCalendar({
// init calendar
header: {left: 'today prev,next, refresh title',
right: 'agendaDay,agendaWeek'},
allDaySlot: false,
defaultView: 'agendaDay',
// when all the events are rendered, scroll to the previous saved scroll position
eventAfterAllRender: function(view) {
if(scroll > -1 && (view.name=='agendaDay' || view.name=='agendaWeek'))
setTimeout(function(){
document.querySelector('.fc-scroller').scrollTop = scroll;
},0);
},
// when view is destroyed, we keep the scroll position in a variable
viewDestroy: function(view) {
if(view.name=='agendaDay' || view.name=='agendaWeek')
scroll = document.querySelector('.fc-scroller').scrollTop;
}
}); // end calendar
This solution is working in 'agendaDay', and 'agendaWeek' views.
It's also working when you switch between them.
I don't think it is very pretty because you need to wait until after all the events are rendered.
The more events you have on your calendar, the more time the scroll will take..
A good solution would be to use the
Fullcalendar option scrollTime
You can set it in viewRender like this.
That will have the effect to make the calendar scroll to this time.
viewRender: function(view, element){
view.options.scrollTime = '09:00:00';
}
Maybe there is a way to convert the scroll value into time and then render it to the calendar.
EDIT 1
I figured out that is way much better to use the
viewRender
callback, instead of the eventAfterAllRender callback to set the scroll position.
Here is the JSFiddle
viewRender: function(view, element){
if(scroll > -1 && (view.name=='agendaDay' || view.name=='agendaWeek')){
setTimeout(function(){
document.querySelector('.fc-scroller').scrollTop = scroll;
},0);
}
},
It's allowing to switch between other wiews (month, basicWeek...) and keep saving the scroll.
And it's a bit faster
What I have is:
var height = $(window).scrollTop();
console.log("current height " + height);
$('#calendar').fullCalendar( 'removeEvents');
$('#calendar').fullCalendar( 'addEventSource', e);
$('#calendar').fullCalendar( 'addEventSource', holiday);
$('#calendar').fullCalendar( 'refetchEvents');
window.scrollTo(0,height);
console.log("scroll to " + height);
and it works for me
Here you can set basic configuration.
scrollTime: '08:00:00',
minTime: '00:00:00', // Set your min time
maxTime: '24:00:00', // Set your max time
yes, main thing is 'height' parameter should not be there in calendar configuration.
Remove below parameter
height: 'auto'
While I would like to see this as build-in function, this is the fastest and at the same time less verbose solution I found:
viewDestroy: function (view) {
if (view.name=='agendaDay' || view.name=='agendaWeek') {
var scrollEl = document.querySelector('.fc-scroller');
var scrollFraction = scrollEl.scrollTop / scrollEl.scrollHeight;
this.scrollTime = moment().startOf('day').add(3600 * 24 * scrollFraction, 's').format('HH:mm:00');
view.options.scrollTime = this.scrollTime;
}
}
Notice that this assumes the scroll range is 12AM-12AM. If you limit your visible area, you should adapt the day duration as well.
You can try it out: JSFiddle
give a unique class to event object. add this code in after event render method.
it will scroll to that specific event
$('.fc-scroller').animate({
scrollTop: $('write here unique class of event').position().top
});
To avoid any scroll "flicking", I did this this way (in fullCalendar 2.9.1) :
viewDestroy: function( aView ) {
// At first view date change, get height of an hour
if( !lineHeight )
lineHeight = $('#calendar').find( "tr.fc-minor" ).height() * 2;
// then convert current scroll to hour decimal
var lScrollCurrHour = Math.max( ($('#calendar').find( ".fc-scroller" )[0].scrollTop - 1) / lineHeight, 0 );
// finally, use moment() to convert to a formatted date
aView.options.scrollTime = moment().startOf('day')
.add(lScrollCurrHour, "hours").format("HH:mm:ss");
}
It will keep separated the scroll for week and days agendas
Hope it helps :o)
you could use this to make the scroll time as your desired time.
customButtons:{
PreviousButton: {
text: 'Prev',
icon: 'left-single-arrow',
click: function() {
$('#calendar').fullCalendar('prev');
$("#calendar").fullCalendar( 'scrollTime',"08:00:00" );
}
}
}`
The method I specified here is only for previous button. Likewise we can have custom button for all the default buttons in full calendar and we can add this method to scroll the time whenever needed.
i hope this would help.

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.

jQuery slider with value on drag handle/slider

I am trying to display the value of the slider inside the drag handle (slider). Any resouce provided is much appreciated. I am using jQuery 1.5.1
Thanks
Are you using jQuery UI Slider ?
If so, this is a solution :
$("#slider").slider({
change: function() {
var value = $("#slider").slider("option","value");
$("#slider").find(".ui-slider-handle").text(value);
},
slide: function() {
var value = $("#slider").slider("option","value");
$("#slider").find(".ui-slider-handle").text(value);
}
});
jsFiddle example here
Just wanted to add a little to the answer.
If you are setting an initial value, or you would like the text to appear on the handle before the slide method is called you will need to add the document ready bit at the bottom, but i have also condensed the code a little
// take value from event, ui.value
$("#slider1").slider({
slide: function (event, ui) {
$("#slider").find(".ui-slider-handle").text(ui.value);
}
});
// sets text initially to value of slider, even if a default value is set
$(document).ready(function() {
var value = $("#slider").slider("option","value");
$("#slider").find(".ui-slider-handle").text(value);
});
Thx all, I have solution for jQuery ui slider with value on drag different handles.
Example for 2 handles:
$("#wt-altitude-range").slider({
range: true,
min: 0,
max: 3000,
values: [ 100, 2500 ],
slide: function(event, ui) {
$(ui.handle).text(ui.value);
}
});
Work for slide event.
ui.handle - current handle, ui.value - current value.

Categories

Resources