@@ -53,7 +53,6 @@ function SliderDirective() {
5353 '$element' ,
5454 '$attrs' ,
5555 '$$rAF' ,
56- '$timeout' ,
5756 '$window' ,
5857 '$materialEffects' ,
5958 '$aria' ,
@@ -99,7 +98,7 @@ function SliderDirective() {
9998 * We use a controller for all the logic so that we can expose a few
10099 * things to unit tests
101100 */
102- function SliderController ( scope , element , attr , $$rAF , $timeout , $ window, $materialEffects , $aria ) {
101+ function SliderController ( scope , element , attr , $$rAF , $window , $materialEffects , $aria ) {
103102
104103 this . init = function init ( ngModelCtrl ) {
105104 var thumb = angular . element ( element [ 0 ] . querySelector ( '.slider-thumb' ) ) ;
@@ -136,6 +135,7 @@ function SliderController(scope, element, attr, $$rAF, $timeout, $window, $mater
136135 hammertime . on ( 'hammer.input' , onInput ) ;
137136 hammertime . on ( 'panstart' , onPanStart ) ;
138137 hammertime . on ( 'pan' , onPan ) ;
138+ hammertime . on ( 'panend' , onPanEnd ) ;
139139
140140 // On resize, recalculate the slider's dimensions and re-render
141141 var updateAll = $$rAF . debounce ( function ( ) {
@@ -282,18 +282,28 @@ function SliderController(scope, element, attr, $$rAF, $timeout, $window, $mater
282282 * Slide listeners
283283 */
284284 var isSliding = false ;
285+ var isDiscrete = false ;
286+
285287 function onInput ( ev ) {
286288 if ( ! isSliding && ev . eventType === Hammer . INPUT_START &&
287289 ! element [ 0 ] . hasAttribute ( 'disabled' ) ) {
288290
289291 isSliding = true ;
292+ isDiscrete = angular . isDefined ( attr . discrete ) ;
293+
290294 element . addClass ( 'active' ) ;
291295 element [ 0 ] . focus ( ) ;
292296 refreshSliderDimensions ( ) ;
293- doSlide ( ev . center . x ) ;
297+
298+ onPan ( ev ) ;
294299
295300 } else if ( isSliding && ev . eventType === Hammer . INPUT_END ) {
301+
302+ if ( isDiscrete ) onPanEnd ( ev ) ;
303+
296304 isSliding = false ;
305+ isDiscrete = false ;
306+
297307 element . removeClass ( 'panning active' ) ;
298308 }
299309 }
@@ -303,8 +313,26 @@ function SliderController(scope, element, attr, $$rAF, $timeout, $window, $mater
303313 }
304314 function onPan ( ev ) {
305315 if ( ! isSliding ) return ;
306- doSlide ( ev . center . x ) ;
316+
317+ // While panning discrete, update only the
318+ // visual positioning but not the model value.
319+
320+ if ( isDiscrete ) doPan ( ev . center . x ) ;
321+ else doSlide ( ev . center . x ) ;
322+
307323 ev . preventDefault ( ) ;
324+ ev . srcEvent . stopPropagation ( ) ;
325+ }
326+
327+ function onPanEnd ( ev ) {
328+ if ( isDiscrete ) {
329+ // Updating the model and slide position
330+ // and perform an animated snap-to operation
331+ doSlide ( ev . center . x ) ;
332+ ngModelRender ( ) ;
333+
334+ ev . srcEvent . stopPropagation ( ) ;
335+ }
308336 }
309337
310338 /**
@@ -314,9 +342,25 @@ function SliderController(scope, element, attr, $$rAF, $timeout, $window, $mater
314342 this . _onPanStart = onPanStart ;
315343 this . _onPan = onPan ;
316344
317- function doSlide ( x ) {
345+ /**
346+ * Slide the UI by changing the model value
347+ * @param x
348+ */
349+ function doSlide ( x ) {
350+ var percent = ( x - sliderDimensions . left ) / ( sliderDimensions . width ) ;
351+
352+ scope . $evalAsync ( function ( ) {
353+ setModelValue ( min + percent * ( max - min ) ) ;
354+ } ) ;
355+ }
356+
357+ /**
358+ * Slide the UI without changing the model (while dragging/panning)
359+ * @param x
360+ */
361+ function doPan ( x ) {
318362 var percent = ( x - sliderDimensions . left ) / ( sliderDimensions . width ) ;
319- scope . $evalAsync ( function ( ) { setModelValue ( min + percent * ( max - min ) ) ; } ) ;
363+ setSliderPercent ( percent ) ;
320364 }
321365
322366 } ;
0 commit comments