@@ -17,7 +17,7 @@ angular.module('rzModule', [])
1717. run ( [ '$templateCache' , function ( $templateCache ) {
1818 'use strict' ;
1919 var template = '<span class="rz-bar-wrapper"><span class="rz-bar"></span></span>' + // 0 The slider bar
20- '<span class="rz-bar rz-selection"></span>' + // 1 Highlight between two handles
20+ '<span class="rz-bar-wrapper"><span class=" rz-bar rz- selection"></span ></span>' + // 1 Highlight between two handles
2121 '<span class="rz-pointer"></span>' + // 2 Left slider handle
2222 '<span class="rz-pointer"></span>' + // 3 Right slider handle
2323 '<span class="rz-bubble rz-limit"></span>' + // 4 Floor label
@@ -115,6 +115,27 @@ function throttle(func, wait, options) {
115115 */
116116 this . range = attributes . rzSliderHigh !== undefined && attributes . rzSliderModel !== undefined ;
117117
118+ /**
119+ * Whether to allow draggable range
120+ *
121+ * @type {boolean } Set to true for draggable range slider
122+ */
123+ this . dragRange = this . range && attributes . rzSliderDraggableRange === 'true' ;
124+
125+ /**
126+ * Values recorded when first dragging the bar
127+ *
128+ * @type {Object }
129+ */
130+ this . dragging = {
131+ active : false ,
132+ value : 0 ,
133+ difference : 0 ,
134+ offset : 0 ,
135+ lowDist : 0 ,
136+ highDist : 0
137+ } ;
138+
118139 /**
119140 * Half of the width of the slider handles
120141 *
@@ -510,6 +531,13 @@ function throttle(func, wait, options) {
510531 this . maxH . remove ( ) ;
511532 this . selBar . remove ( ) ;
512533 }
534+
535+ // If using draggable range, use appropriate cursor for this.selBar.
536+ if ( this . dragRange )
537+ {
538+ this . selBar . css ( 'cursor' , 'move' ) ;
539+ this . selBar . addClass ( 'rz-draggable' ) ;
540+ }
513541 } ,
514542
515543 /**
@@ -852,26 +880,61 @@ function throttle(func, wait, options) {
852880
853881 // Events
854882
883+ /**
884+ * Get the X-coordinate of an event
885+ *
886+ * @param {Object } event The event
887+ * @returns {number }
888+ */
889+ getEventX : function ( event )
890+ {
891+ /* http://stackoverflow.com/a/12336075/282882 */
892+ //noinspection JSLint
893+ if ( 'clientX' in event )
894+ {
895+ return event . clientX ;
896+ }
897+
898+ return event . originalEvent === undefined ?
899+ event . touches [ 0 ] . clientX
900+ : event . originalEvent . touches [ 0 ] . clientX ;
901+ } ,
902+
855903 /**
856904 * Bind mouse and touch events to slider handles
857905 *
858906 * @returns {undefined }
859907 */
860908 bindEvents : function ( )
861909 {
910+ var barTracking , barStart , barMove ;
911+
912+ if ( this . dragRange )
913+ {
914+ barTracking = 'rzSliderDrag' ;
915+ barStart = this . onDragStart ;
916+ barMove = this . onDragMove ;
917+ }
918+ else
919+ {
920+ barTracking = 'rzSliderModel' ;
921+ barStart = this . onStart ;
922+ barMove = this . onMove ;
923+ }
924+
862925 this . minH . on ( 'mousedown' , angular . bind ( this , this . onStart , this . minH , 'rzSliderModel' ) ) ;
863926 if ( this . range ) { this . maxH . on ( 'mousedown' , angular . bind ( this , this . onStart , this . maxH , 'rzSliderHigh' ) ) ; }
864927 this . fullBar . on ( 'mousedown' , angular . bind ( this , this . onStart , this . minH , 'rzSliderModel' ) ) ;
865928 this . fullBar . on ( 'mousedown' , angular . bind ( this , this . onMove , this . fullBar ) ) ;
866- this . selBar . on ( 'mousedown' , angular . bind ( this , this . onStart , this . minH , 'rzSliderModel' ) ) ;
867- this . selBar . on ( 'mousedown' , angular . bind ( this , this . onMove , this . selBar ) ) ;
929+ this . selBar . on ( 'mousedown' , angular . bind ( this , barStart , this . minH , barTracking ) ) ;
930+ this . selBar . on ( 'mousedown' , angular . bind ( this , barMove , this . selBar ) ) ;
868931
869932 this . minH . on ( 'touchstart' , angular . bind ( this , this . onStart , this . minH , 'rzSliderModel' ) ) ;
870933 if ( this . range ) { this . maxH . on ( 'touchstart' , angular . bind ( this , this . onStart , this . maxH , 'rzSliderHigh' ) ) ; }
871934 this . fullBar . on ( 'touchstart' , angular . bind ( this , this . onStart , this . minH , 'rzSliderModel' ) ) ;
872935 this . fullBar . on ( 'touchstart' , angular . bind ( this , this . onMove , this . fullBar ) ) ;
873- this . selBar . on ( 'touchstart' , angular . bind ( this , this . onStart , this . minH , 'rzSliderModel' ) ) ;
874- this . selBar . on ( 'touchstart' , angular . bind ( this , this . onMove , this . selBar ) ) ;
936+ this . selBar . on ( 'touchstart' , angular . bind ( this , barStart , this . minH , barTracking ) ) ;
937+ this . selBar . on ( 'touchstart' , angular . bind ( this , barMove , this . selBar ) ) ;
875938 } ,
876939
877940 /**
@@ -899,7 +962,7 @@ function throttle(func, wait, options) {
899962
900963 pointer . addClass ( 'rz-active' ) ;
901964
902- ehMove = angular . bind ( this , this . onMove , pointer ) ;
965+ ehMove = angular . bind ( this , this . dragging . active ? this . onDragMove : this . onMove , pointer ) ;
903966 ehEnd = angular . bind ( this , this . onEnd , ehMove ) ;
904967
905968 $document . on ( eventNames . moveEvent , ehMove ) ;
@@ -915,20 +978,8 @@ function throttle(func, wait, options) {
915978 */
916979 onMove : function ( pointer , event )
917980 {
918- var eventX , sliderLO , newOffset , newValue ;
919-
920- /* http://stackoverflow.com/a/12336075/282882 */
921- //noinspection JSLint
922- if ( 'clientX' in event )
923- {
924- eventX = event . clientX ;
925- }
926- else
927- {
928- eventX = event . originalEvent === undefined ?
929- event . touches [ 0 ] . clientX
930- : event . originalEvent . touches [ 0 ] . clientX ;
931- }
981+ var eventX = this . getEventX ( event ) ,
982+ sliderLO , newOffset , newValue ;
932983
933984 sliderLO = this . sliderElem . rzsl ;
934985 newOffset = eventX - sliderLO - this . handleHalfWidth ;
@@ -955,6 +1006,92 @@ function throttle(func, wait, options) {
9551006 this . positionTrackingHandle ( newValue , newOffset ) ;
9561007 } ,
9571008
1009+ /**
1010+ * onDragStart event handler
1011+ *
1012+ * Handles dragging of the middle bar.
1013+ *
1014+ * @param {Object } pointer The jqLite wrapped DOM element
1015+ * @param {string } ref One of the refLow, refHigh values
1016+ * @param {Event } event The event
1017+ * @returns {undefined }
1018+ */
1019+ onDragStart : function ( pointer , ref , event )
1020+ {
1021+ var offset = this . getEventX ( event ) - this . sliderElem . rzsl - this . handleHalfWidth ;
1022+ this . dragging = {
1023+ active : true ,
1024+ value : this . offsetToValue ( offset ) ,
1025+ difference : this . scope . rzSliderHigh - this . scope . rzSliderModel ,
1026+ offset : offset ,
1027+ lowDist : offset - this . minH . rzsl ,
1028+ highDist : this . maxH . rzsl - offset
1029+ } ;
1030+ this . minH . addClass ( 'rz-active' ) ;
1031+ this . maxH . addClass ( 'rz-active' ) ;
1032+
1033+ this . onStart ( pointer , ref , event ) ;
1034+ } ,
1035+
1036+ /**
1037+ * onDragMove event handler
1038+ *
1039+ * Handles dragging of the middle bar.
1040+ *
1041+ * @param {jqLite } pointer
1042+ * @param {Event } event The event
1043+ * @returns {undefined }
1044+ */
1045+ onDragMove : function ( pointer , event )
1046+ {
1047+ var newOffset = this . getEventX ( event ) - this . sliderElem . rzsl - this . handleHalfWidth ,
1048+ newMinOffset , newMaxOffset ,
1049+ newMinValue , newMaxValue ;
1050+
1051+ if ( newOffset <= this . dragging . lowDist )
1052+ {
1053+ if ( pointer . rzsl === this . dragging . lowDist ) { return ; }
1054+ newMinValue = this . minValue ;
1055+ newMinOffset = 0 ;
1056+ newMaxValue = this . dragging . difference ;
1057+ newMaxOffset = this . valueToOffset ( newMaxValue ) ;
1058+ }
1059+ else if ( newOffset >= this . maxLeft - this . dragging . highDist )
1060+ {
1061+ if ( pointer . rzsl === this . dragging . highDist ) { return ; }
1062+ newMaxValue = this . maxValue ;
1063+ newMaxOffset = this . maxLeft ;
1064+ newMinValue = this . maxValue - this . dragging . difference ;
1065+ newMinOffset = this . valueToOffset ( newMinValue ) ;
1066+ }
1067+ else
1068+ {
1069+ newMinValue = this . offsetToValue ( newOffset - this . dragging . lowDist ) ;
1070+ newMinValue = this . roundStep ( newMinValue ) ;
1071+ newMinOffset = this . valueToOffset ( newMinValue ) ;
1072+ newMaxValue = newMinValue + this . dragging . difference ;
1073+ newMaxOffset = this . valueToOffset ( newMaxValue ) ;
1074+ }
1075+
1076+ this . positionTrackingBar ( newMinValue , newMaxValue , newMinOffset , newMaxOffset ) ;
1077+ } ,
1078+
1079+ /**
1080+ * Set the new value and offset for the entire bar
1081+ *
1082+ * @param {number } newMinValue the new minimum value
1083+ * @param {number } newMaxValue the new maximum value
1084+ * @param {number } newMinOffset the new minimum offset
1085+ * @param {number } newMaxOffset the new maximum offset
1086+ */
1087+ positionTrackingBar : function ( newMinValue , newMaxValue , newMinOffset , newMaxOffset )
1088+ {
1089+ this . scope . rzSliderModel = newMinValue ;
1090+ this . scope . rzSliderHigh = newMaxValue ;
1091+ this . updateHandles ( 'rzSliderModel' , newMinOffset ) ;
1092+ this . updateHandles ( 'rzSliderHigh' , newMaxOffset ) ;
1093+ this . scope . $apply ( ) ;
1094+ } ,
9581095
9591096 /**
9601097 * Set the new value and offset to the current tracking handle
@@ -964,7 +1101,7 @@ function throttle(func, wait, options) {
9641101 */
9651102 positionTrackingHandle : function ( newValue , newOffset )
9661103 {
967- if ( this . range )
1104+ if ( this . range )
9681105 {
9691106 /* This is to check if we need to switch the min and max handles*/
9701107 if ( this . tracking === 'rzSliderModel' && newValue >= this . scope . rzSliderHigh )
@@ -1015,6 +1152,8 @@ function throttle(func, wait, options) {
10151152
10161153 this . scope . $emit ( 'slideEnded' ) ;
10171154 this . tracking = '' ;
1155+
1156+ this . dragging . active = false ;
10181157 } ,
10191158
10201159 /**
@@ -1059,6 +1198,7 @@ function throttle(func, wait, options) {
10591198 rzSliderPrecision : '@' ,
10601199 rzSliderModel : '=?' ,
10611200 rzSliderHigh : '=?' ,
1201+ rzSliderDraggable : '@' ,
10621202 rzSliderTranslate : '&' ,
10631203 rzSliderHideLimitLabels : '=?' ,
10641204 rzSliderAlwaysShowBar : '=?' ,
0 commit comments