For those localities whose languages read right-to-left,
it would be great if the jQuery UI components supported that.
jQuery UI Datepicker
provides an isRTL
option that switches the orientation of its
calendar. Now you can do the same thing for
jQuery UI Slider.
At the moment you need to use a modified version of the slider module, but perhaps these changes could be incorporated into the main jQuery UI code.
Right-to-left slider:
$('#sliderRTL').slider({isRTL: true, slide: showValue, change: showValue});
Right-to-left range slider:
$('#sliderRTLRange').slider({isRTL: true, range: true, slide: showValue, change: showValue});
Left-to-right slider:
$('#sliderLTR').slider({slide: showValue, change: showValue});
Left-to-right range slider:
$('#sliderLTRRange').slider({range: true, slide: showValue, change: showValue});
Vertical sliders:
Right-to-left
Right-to-left range
Left-to-right
Left-to-right range
$('#sliderVRTL').slider({orientation: 'vertical', isRTL: true, slide: showValue, change: showValue});
$('#sliderVRTLRange').slider({orientation: 'vertical', isRTL: true, range: true, slide: showValue, change: showValue});
$('#sliderVLTR').slider({orientation: 'vertical', slide: showValue, change: showValue});
$('#sliderVLTRRange').slider({orientation: 'vertical', range: true, slide: showValue, change: showValue});
<link type="text/css" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/themes/south-street/jquery-ui.css" rel="stylesheet">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script>
<link type="text/css" href="css/jquery.ui.slider-rtl.css" rel="stylesheet">
<script type="text/javascript" src="jquery.ui.slider-rtl.js"></script>
Alternately, you can use the packed version jquery.ui.slider-rtl.pack.js
(6.9K vs 17.7K),
or the minified version jquery.ui.slider-rtl.min.js
(11.6K, 3.1K when zipped).$(selector).slider({isRTL: true});
Make the following changes to the jQuery UI slider module.
First add the isRTL
option to the set of default options for the slider.
options: {
animate: false,
distance: 0,
max: 100,
min: 0,
orientation: "horizontal",
isRTL: false, // RTL
range: false,
step: 1,
value: 0,
values: null
},
When creating the slider note that it has the alternate language direction
by adding a class in the _create
function.
this.element
.addClass( "ui-slider" +
" ui-slider-" + this.orientation +
( o.isRTL ? " ui-slider-rtl" : "" ) + // RTL
" ui-widget" +
" ui-widget-content" +
" ui-corner-all" );
Next handle keystrokes differently depending on the isRTL
setting.
Update the keydown
processing to change the orientation of
the LEFT
and RIGHT
keys when this setting is true
.
To make the processing a little easier, introduce a common function
(adjust
) that handles the details.
var adjust = function(minMax, offset) { // RTL
if ( curVal === minMax ) {
return;
}
newVal = self._trimAlignValue( curVal + offset );
};
switch ( event.keyCode ) {
case $.ui.keyCode.HOME:
newVal = self._valueMin();
break;
case $.ui.keyCode.END:
newVal = self._valueMax();
break;
case $.ui.keyCode.PAGE_UP:
newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) );
break;
case $.ui.keyCode.PAGE_DOWN:
newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) );
break;
case $.ui.keyCode.UP:
adjust( self._valueMax(), step ); // RTL
break;
case $.ui.keyCode.RIGHT:
adjust( self._valueMax(), self.options.isRTL ? -step : step ); // RTL
break;
case $.ui.keyCode.DOWN:
adjust( self._valueMin(), -step ); // RTL
break;
case $.ui.keyCode.LEFT:
adjust( self._valueMin(), self.options.isRTL ? step : -step ); // RTL
break;
}
When the slider handle is dragged or the bar is clicked the new position is calculated
and is normalised to a percentage. Update this to reverse the orientation
for the right-to-left case. Within the _normValueFromMouse
function
add the appropriate test. Note that right-to-left in combination with a vertical
orientation results in the minimum value appearing at the top.
if ( this.orientation === "vertical" ) {
percentMouse = 1 - percentMouse;
}
if ( this.options.isRTL ) { // RTL
percentMouse = 1 - percentMouse;
}
Reconfigure the slider in _setOption
if the isRTL
setting is changed.
case "isRTL": // RTL
this.element.toggleClass( "ui-slider-rtl", value );
this._refreshValue();
break;
And finally, update the _refreshValue
function to correctly
adjust the handles and range display on the screen.
if ( this.options.values && this.options.values.length ) {
this.handles.each(function( i, j ) {
valPercent = ( self.values( i ) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100;
valPercent = ( self.options.isRTL ? 100 - valPercent : valPercent ); // RTL
_set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
if ( self.options.range === true ) {
if ( self.orientation === "horizontal" ) {
if ( i === 0 ) {
self.range.stop( 1, 1 )[ animate ? "animate" : "css" ](
self.options.isRTL ? { right: ( 100 - valPercent ) + "%"} : // RTL
{ left: valPercent + "%" }, o.animate );
}
if ( i === 1 ) {
self.range[ animate ? "animate" : "css" ]( {
width: ( ( self.options.isRTL ? -1 : +1 ) * ( valPercent - lastValPercent ) ) + "%" }, // RTL
{ queue: false, duration: o.animate } );
}
} else {
if ( i === 0 ) {
self.range.stop( 1, 1 )[ animate ? "animate" : "css" ](
self.options.isRTL ? { top: ( 100 - valPercent ) + "%" } : // RTL
{ bottom: ( valPercent ) + "%" }, o.animate );
}
if ( i === 1 ) {
self.range[ animate ? "animate" : "css" ]( {
height: ( ( self.options.isRTL ? -1 : +1 ) * ( valPercent - lastValPercent ) ) + "%" }, // RTL
{ queue: false, duration: o.animate } );
}
}
}
lastValPercent = valPercent;
});
} else {
value = this.value();
valueMin = this._valueMin();
valueMax = this._valueMax();
valPercent = ( valueMax !== valueMin ) ?
( value - valueMin ) / ( valueMax - valueMin ) * 100 :
0;
valPercent = ( self.options.isRTL ? 100 - valPercent : valPercent ); // RTL
_set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
if ( oRange === "min" && this.orientation === "horizontal" ) {
this.range.stop( 1, 1 )[ animate ? "animate" : "css" ](
{ width: ( self.options.isRTL ? 100 - valPercent : valPercent ) + "%" }, o.animate ); // RTL
}
if ( oRange === "max" && this.orientation === "horizontal" ) {
this.range[ animate ? "animate" : "css" ]( {
width: ( self.options.isRTL ? valPercent : 100 - valPercent ) + "%" }, // RTL
{ queue: false, duration: o.animate } );
}
if ( oRange === "min" && this.orientation === "vertical" ) {
this.range.stop( 1, 1 )[ animate ? "animate" : "css" ](
{ height: ( self.options.isRTL ? 100 - valPercent : valPercent ) + "%" }, o.animate ); // RTL
}
if ( oRange === "max" && this.orientation === "vertical" ) {
this.range[ animate ? "animate" : "css" ](
{ height: ( self.options.isRTL ? valPercent : 100 - valPercent ) + "%" }, // RTL
{ queue: false, duration: o.animate } );
}
}
The updated slider module (based on jQuery UI 1.8.9) is available for download, along with a patch file detailing the changes from the original module.