Files
shiny/srcjs/input_binding_slider.js
2015-03-30 16:17:04 -05:00

170 lines
4.8 KiB
JavaScript

var sliderInputBinding = {};
$.extend(sliderInputBinding, textInputBinding, {
find: function(scope) {
// Check if ionRangeSlider plugin is loaded
if (!$.fn.ionRangeSlider)
return [];
return $(scope).find('input.js-range-slider');
},
getValue: function(el) {
var result = $(el).data('ionRangeSlider').result;
if (this._numValues(el) == 2) {
return [+result.from, +result.to];
}
else {
return +result.from;
}
},
setValue: function(el, value) {
var slider = $(el).data('ionRangeSlider');
if (this._numValues(el) == 2 && value instanceof Array) {
slider.update({ from: value[0], to: value[1] });
} else {
slider.update({ from: value });
}
},
subscribe: function(el, callback) {
$(el).on('change.sliderInputBinding', function(event) {
callback(!$(el).data('updating') && !$(el).data('animating'));
});
},
unsubscribe: function(el) {
$(el).off('.sliderInputBinding');
},
receiveMessage: function(el, data) {
var slider = $(el).data('ionRangeSlider');
var msg = {};
if (data.hasOwnProperty('value')) {
if (this._numValues(el) == 2 && data.value instanceof Array) {
msg.from = data.value[0];
msg.to = data.value[1];
} else {
msg.from = data.value;
// Workaround for ionRangeSlider issue #143
msg.to = data.value;
}
}
if (data.hasOwnProperty('min')) msg.min = data.min;
if (data.hasOwnProperty('max')) msg.max = data.max;
if (data.hasOwnProperty('step')) msg.step = data.step;
if (data.hasOwnProperty('label'))
$(el).parent().find('label[for="' + $escape(el.id) + '"]').text(data.label);
$(el).data('updating', true);
try {
slider.update(msg);
} finally {
$(el).data('updating', false);
}
},
getRatePolicy: function() {
return {
policy: 'debounce',
delay: 250
};
},
getState: function(el) {
},
initialize: function(el) {
$(el).ionRangeSlider();
},
// Number of values; 1 for single slider, 2 for range slider
_numValues: function(el) {
if ($(el).data('ionRangeSlider').options.type === 'double')
return 2;
else
return 1;
}
});
inputBindings.register(sliderInputBinding, 'shiny.sliderInput');
$(document).on('click', '.slider-animate-button', function(evt) {
evt.preventDefault();
var self = $(this);
var target = $('#' + $escape(self.attr('data-target-id')));
var startLabel = 'Play';
var stopLabel = 'Pause';
var loop = self.attr('data-loop') !== undefined &&
!/^\s*false\s*$/i.test(self.attr('data-loop'));
var animInterval = self.attr('data-interval');
if (isNaN(animInterval))
animInterval = 1500;
else
animInterval = +animInterval;
if (!target.data('animTimer')) {
var slider;
var timer;
// Separate code paths:
// Backward compatible code for old-style jsliders (Shiny <= 0.10.2.2),
// and new-style ionsliders.
if (target.hasClass('jslider')) {
slider = target.slider();
// If we're currently at the end, restart
if (!slider.canStepNext())
slider.resetToStart();
timer = setInterval(function() {
if (loop && !slider.canStepNext()) {
slider.resetToStart();
}
else {
slider.stepNext();
if (!loop && !slider.canStepNext()) {
self.click(); // stop the animation
}
}
}, animInterval);
} else {
slider = target.data('ionRangeSlider');
var sliderCanStep = function() {
return slider.result.from < slider.result.max;
};
var sliderReset = function() {
slider.update({from: slider.result.min});
};
var sliderStep = function() {
slider.update({from: slider.result.from + slider.options.step});
};
// If we're currently at the end, restart
if (!sliderCanStep())
sliderReset();
timer = setInterval(function() {
if (loop && !sliderCanStep()) {
sliderReset();
}
else {
sliderStep();
if (!loop && !sliderCanStep()) {
self.click(); // stop the animation
}
}
}, animInterval);
}
target.data('animTimer', timer);
self.attr('title', stopLabel);
self.addClass('playing');
target.data('animating', true);
}
else {
clearTimeout(target.data('animTimer'));
target.removeData('animTimer');
self.attr('title', startLabel);
self.removeClass('playing');
target.removeData('animating');
}
});