implementing a slider with proportional-width thumb using jquery-ui draggable
1. a 2nd slider controls the thumb width 2. slider displays start and end dates, in a demo of using slider as a date picker 3. all implemented on top of jquery-ui "draggable" 4. biggest hack is the option "containment". The natural thing for "containment" is to use the "parent" or named selector option, but these only slide up to 1 pixel shy of the max width of the track. So I use another containment option, an array of 4 numbers, but the setting of those numbers is kludgy
by hrabinowitz
HTML
<h3>implementing a slider with proportional-width thumb using jquery-ui draggable</h3>
<h3>Or to within another DOM element:</h3>
<div id="track" class="track">
<div id="thumb" class="draggable ui-widget-content">
<p>ui.position.left=<span id="offsetX"></span></p>
<div id="startDisplay">
xx
</div>
<div id="endDisplay">
yy
</div>
<div id="startTimeDisplay">
xx:00
</div>
<div id="endTimeDisplay">
yy:00
</div>
</div>
</div>
<br><br><br><br><br><br>
<h4>
Use the 2nd slider to adjust the % width of the first slider thumb
</h4>
<div id="metaSlider">
<div id="meta-handle" class="ui-slider-handle">
</div>
</div>
CSS
.draggable {
position: absolute;
width: 100px;
height: 90px;
/*padding: 0.5em; */
float: left;
/*margin: 0 10px 10px 0;*/
margin: 0 0 0 0;
padding: 0;
background: yellow;
border: .5px solid #ccc;
cursor: ew-resize;
}
#startDisplay {
margin-top: 50px;
}
#endDisplay {
/*margin-top: 50px;*/
float: right;
}
#startTimeDisplay {
margin-top: 12px;
width: 250px;
text-align: left;
}
#endTimeDisplay {
float: right;
text-align: right;
width: 250px;
}
.track {
position: relative;
width: 600px;
height: 90px;
border: 0px solid #ccc;
padding: 0px;
background: lightGray;
margin: 0 0 0 0;
}
#metaSlider {
width: 600px;
}
JavaScript
// my code ===============
var dataRange = {
start: /*1494348611,*/ 1494288000000,
end: /*1525884611*/ 1525824000000
};
//debugger
var dataDiff = dataRange.end - dataRange.start;
var trackWidth = $('.track').width();
var $thumb = $('#thumb');
var getThumbWidth = function() {
return $('#thumb').width();
}
console.log("dataDiff=", dataDiff, "trackWidth=", trackWidth, "thumbWidth=" + getThumbWidth());
function getStartDate(/*ui*/left) {
//var startEpoch = dataRange.start + ui.position.left/trackWidth*dataDiff;
var startEpoch = dataRange.start + left/trackWidth*dataDiff;
return startEpoch;
}
function getEndDate(/*ui*/left) {
//var endEpoch = getStartDate(ui) + getThumbWidth()/trackWidth * dataDiff;
var endEpoch = getStartDate(left) + getThumbWidth()/trackWidth * dataDiff;
return endEpoch;
}
function onDrag(e, ui) {
//$('#offsetX').text(ui.position.left);
var left = +$(ui).position().left;
$('#offsetX').text(left);
var startEpoch = getStartDate(/*ui*/left);
var endEpoch = getEndDate(/*ui*/left);
$startDisplay.text(startEpoch);
$endDisplay.text(endEpoch);
var startDate = new Date(startEpoch);
var endDate = new Date(endEpoch);
$startTimeDisplay.text(startDate.toUTCString());
$endTimeDisplay.text(endDate.toUTCString());
//console.log("endEpoch-startEpoch=", endEpoch - startEpoch);
console.log("e=", e, "ui=", ui);
}
var $metaHandle = $('#meta-handle');
var $startDisplay = $('#startDisplay');
var $endDisplay = $('#endDisplay');
var $startTimeDisplay = $('#startTimeDisplay');
var $endTimeDisplay = $('#endTimeDisplay');
var containment = [8, 0, 508, 90];
var $thumb = $('#thumb');
$('#thumb').draggable({
//containment: ".track",
//containment: 'parent',
containment: containment,
scroll: false,
axis: "x",
drag: onDrag,
start: onDrag
});
// trigger seems to not work?
// $thumb.trigger('drag', {position: {left: 100, top: 100}});
var fakeDragEvent = $.Event("drag");
$thumb.css('left', 500);
//$thumb.draggable('option',...