mirror of
https://github.com/rstudio/shiny.git
synced 2026-02-05 04:05:06 -05:00
170 lines
4.5 KiB
JavaScript
170 lines
4.5 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');
|
|
}
|
|
});
|