Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
I
i20rzslider
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
jedife
i20rzslider
Commits
3775ce08
Commit
3775ce08
authored
Dec 06, 2015
by
Valentin Hervieu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Apply editorconfig style to all code base.
parent
29a0d87f
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
2484 additions
and
2483 deletions
+2484
-2483
demo.js
demo/demo.js
+9
-6
rzslider.js
dist/rzslider.js
+1237
-1238
rzslider.min.js
dist/rzslider.min.js
+1
-1
rzslider.js
src/rzslider.js
+1237
-1238
No files found.
demo/demo.js
View file @
3775ce08
...
...
@@ -50,7 +50,11 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) {
}
}
};
$scope
.
otherData
=
{
start
:
0
,
change
:
0
,
end
:
0
};
$scope
.
otherData
=
{
start
:
0
,
change
:
0
,
end
:
0
};
//Slider config with custom display function
$scope
.
slider_translate
=
{
...
...
@@ -69,7 +73,7 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) {
$scope
.
slider_alphabet
=
{
value
:
0
,
options
:
{
stepsArray
:
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
.
split
(
''
)
stepsArray
:
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
.
split
(
''
)
}
};
...
...
@@ -263,7 +267,7 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) {
$scope
.
percentages
=
percentages
;
});
modalInstance
.
rendered
.
then
(
function
()
{
$rootScope
.
$broadcast
(
'rzSliderForceRender'
);
//Force refresh sliders on render. Otherwise bullets are aligned at left side.
$rootScope
.
$broadcast
(
'rzSliderForceRender'
);
//Force refresh sliders on render. Otherwise bullets are aligned at left side.
});
};
...
...
@@ -302,10 +306,9 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) {
}
};
$scope
.
toggleHighValue
=
function
()
{
if
(
$scope
.
slider_all_options
.
maxValue
!=
null
)
{
if
(
$scope
.
slider_all_options
.
maxValue
!=
null
)
{
$scope
.
slider_all_options
.
maxValue
=
undefined
;
}
else
{
}
else
{
$scope
.
slider_all_options
.
maxValue
=
8
;
}
}
...
...
dist/rzslider.js
View file @
3775ce08
...
...
@@ -31,1372 +31,1371 @@
'use strict'
;
var
module
=
angular
.
module
(
'rzModule'
,
[])
.
factory
(
'RzSliderOptions'
,
function
()
{
var
defaultOptions
=
{
floor
:
0
,
ceil
:
null
,
//defaults to rz-slider-model
step
:
1
,
precision
:
0
,
id
:
null
,
translate
:
null
,
stepsArray
:
null
,
draggableRange
:
false
,
showSelectionBar
:
false
,
hideLimitLabels
:
false
,
readOnly
:
false
,
disabled
:
false
,
interval
:
350
,
showTicks
:
false
,
showTicksValues
:
false
,
ticksValuesTooltip
:
null
,
vertical
:
false
,
scale
:
1
,
onStart
:
null
,
onChange
:
null
,
onEnd
:
null
};
var
globalOptions
=
{};
var
factory
=
{};
/**
* `options({})` allows global configuration of all sliders in the
* application.
*
* var app = angular.module( 'App', ['rzModule'], function( RzSliderOptions ) {
.
factory
(
'RzSliderOptions'
,
function
()
{
var
defaultOptions
=
{
floor
:
0
,
ceil
:
null
,
//defaults to rz-slider-model
step
:
1
,
precision
:
0
,
id
:
null
,
translate
:
null
,
stepsArray
:
null
,
draggableRange
:
false
,
showSelectionBar
:
false
,
hideLimitLabels
:
false
,
readOnly
:
false
,
disabled
:
false
,
interval
:
350
,
showTicks
:
false
,
showTicksValues
:
false
,
ticksValuesTooltip
:
null
,
vertical
:
false
,
scale
:
1
,
onStart
:
null
,
onChange
:
null
,
onEnd
:
null
};
var
globalOptions
=
{};
var
factory
=
{};
/**
* `options({})` allows global configuration of all sliders in the
* application.
*
* var app = angular.module( 'App', ['rzModule'], function( RzSliderOptions ) {
* // show ticks for all sliders
* RzSliderOptions.options( { showTicks: true } );
* });
*/
factory
.
options
=
function
(
value
)
{
angular
.
extend
(
globalOptions
,
value
);
*/
factory
.
options
=
function
(
value
)
{
angular
.
extend
(
globalOptions
,
value
);
};
factory
.
getOptions
=
function
(
options
)
{
return
angular
.
extend
({},
defaultOptions
,
globalOptions
,
options
);
};
return
factory
;
})
.
value
(
'rzThrottle'
,
/**
* rzThrottle
*
* Taken from underscore project
*
* @param {Function} func
* @param {number} wait
* @param {ThrottleOptions} options
* @returns {Function}
*/
function
throttle
(
func
,
wait
,
options
)
{
'use strict'
;
var
getTime
=
(
Date
.
now
||
function
()
{
return
new
Date
().
getTime
();
});
var
context
,
args
,
result
;
var
timeout
=
null
;
var
previous
=
0
;
options
=
options
||
{};
var
later
=
function
()
{
previous
=
options
.
leading
===
false
?
0
:
getTime
();
timeout
=
null
;
result
=
func
.
apply
(
context
,
args
);
context
=
args
=
null
;
};
factory
.
getOptions
=
function
(
options
)
{
return
angular
.
extend
({},
defaultOptions
,
globalOptions
,
options
);
return
function
()
{
var
now
=
getTime
();
if
(
!
previous
&&
options
.
leading
===
false
)
{
previous
=
now
;
}
var
remaining
=
wait
-
(
now
-
previous
);
context
=
this
;
args
=
arguments
;
if
(
remaining
<=
0
)
{
clearTimeout
(
timeout
);
timeout
=
null
;
previous
=
now
;
result
=
func
.
apply
(
context
,
args
);
context
=
args
=
null
;
}
else
if
(
!
timeout
&&
options
.
trailing
!==
false
)
{
timeout
=
setTimeout
(
later
,
remaining
);
}
return
result
;
};
return
factory
;
})
.
value
(
'rzThrottle'
,
.
factory
(
'RzSlider'
,
[
'$timeout'
,
'$document'
,
'$window'
,
'$compile'
,
'RzSliderOptions'
,
'rzThrottle'
,
function
(
$timeout
,
$document
,
$window
,
$compile
,
RzSliderOptions
,
rzThrottle
)
{
'use strict'
;
/**
* Slider
*
* @param {ngScope} scope The AngularJS scope
* @param {Element} sliderElem The slider directive element wrapped in jqLite
* @constructor
*/
var
Slider
=
function
(
scope
,
sliderElem
)
{
/**
*
rzThrottl
e
*
The slider's scop
e
*
* Taken from underscore project
* @type {ngScope}
*/
this
.
scope
=
scope
;
/**
* Slider element wrapped in jqLite
*
* @param {Function} func
* @param {number} wait
* @param {ThrottleOptions} options
* @returns {Function}
* @type {jqLite}
*/
function
throttle
(
func
,
wait
,
options
)
{
'use strict'
;
var
getTime
=
(
Date
.
now
||
function
()
{
return
new
Date
().
getTime
();
});
var
context
,
args
,
result
;
var
timeout
=
null
;
var
previous
=
0
;
options
=
options
||
{};
var
later
=
function
()
{
previous
=
options
.
leading
===
false
?
0
:
getTime
();
timeout
=
null
;
result
=
func
.
apply
(
context
,
args
);
context
=
args
=
null
;
};
return
function
()
{
var
now
=
getTime
();
if
(
!
previous
&&
options
.
leading
===
false
)
{
previous
=
now
;
}
var
remaining
=
wait
-
(
now
-
previous
);
context
=
this
;
args
=
arguments
;
if
(
remaining
<=
0
)
{
clearTimeout
(
timeout
);
timeout
=
null
;
previous
=
now
;
result
=
func
.
apply
(
context
,
args
);
context
=
args
=
null
;
}
else
if
(
!
timeout
&&
options
.
trailing
!==
false
)
{
timeout
=
setTimeout
(
later
,
remaining
);
}
return
result
;
};
})
this
.
sliderElem
=
sliderElem
;
.
factory
(
'RzSlider'
,
[
'$timeout'
,
'$document'
,
'$window'
,
'$compile'
,
'RzSliderOptions'
,
'rzThrottle'
,
function
(
$timeout
,
$document
,
$window
,
$compile
,
RzSliderOptions
,
rzThrottle
)
{
'use strict'
;
/**
* Slider type
*
* @type {boolean} Set to true for range slider
*/
this
.
range
=
this
.
scope
.
rzSliderModel
!==
undefined
&&
this
.
scope
.
rzSliderHigh
!==
undefined
;
/**
*
Slide
r
*
Values recorded when first dragging the ba
r
*
* @param {ngScope} scope The AngularJS scope
* @param {Element} sliderElem The slider directive element wrapped in jqLite
* @constructor
* @type {Object}
*/
var
Slider
=
function
(
scope
,
sliderElem
)
{
/**
* The slider's scope
*
* @type {ngScope}
*/
this
.
scope
=
scope
;
this
.
dragging
=
{
active
:
false
,
value
:
0
,
difference
:
0
,
offset
:
0
,
lowDist
:
0
,
highDist
:
0
};
/**
* Slider element wrapped in jqLite
*
* @type {jqLite}
*/
this
.
sliderElem
=
sliderElem
;
/**
* property that handle position (defaults to left for horizontal)
* @type {string}
*/
this
.
positionProperty
=
'left'
;
/**
* Slider type
*
* @type {boolean} Set to true for range slider
*/
this
.
range
=
this
.
scope
.
rzSliderModel
!==
undefined
&&
this
.
scope
.
rzSliderHigh
!==
undefined
;
/**
* property that handle dimension (defaults to width for horizontal)
* @type {string}
*/
this
.
dimensionProperty
=
'width'
;
/**
* Values recorded when first dragging the bar
*
* @type {Object}
*/
this
.
dragging
=
{
active
:
false
,
value
:
0
,
difference
:
0
,
offset
:
0
,
lowDist
:
0
,
highDist
:
0
};
/**
* Half of the width or height of the slider handles
*
* @type {number}
*/
this
.
handleHalfDim
=
0
;
/**
* property that handle position (defaults to left for horizontal)
* @type {string}
*/
this
.
positionProperty
=
'left'
;
/**
* Maximum position the slider handle can have
*
* @type {number}
*/
this
.
maxPos
=
0
;
/**
* property that handle dimension (defaults to width for horizontal)
* @type {string}
*/
this
.
dimensionProperty
=
'width'
;
/**
* Precision
*
* @type {number}
*/
this
.
precision
=
0
;
/**
* Half of the width or height of the slider handles
*
* @type {number}
*/
this
.
handleHalfDim
=
0
;
/**
* Step
*
* @type {number}
*/
this
.
step
=
0
;
/**
* Maximum position the slider handle can have
*
* @type {number
}
*/
this
.
maxPos
=
0
;
/**
* The name of the handle we are currently tracking
*
* @type {string
}
*/
this
.
tracking
=
''
;
/**
* Precision
*
* @type {number}
*/
this
.
precision
=
0
;
/**
* Minimum value (floor) of the model
*
* @type {number}
*/
this
.
minValue
=
0
;
/**
* Step
*
* @type {number}
*/
this
.
step
=
0
;
/**
* Maximum value (ceiling) of the model
*
* @type {number}
*/
this
.
maxValue
=
0
;
/**
* The name of the handle we are currently tracking
*
* @type {string}
*/
this
.
tracking
=
''
;
/**
* Minimum value (floor) of the model
*
* @type {number}
*/
this
.
minValu
e
=
0
;
/**
* The delta between min and max value
*
* @type {number}
*/
this
.
valueRang
e
=
0
;
/**
* Maximum value (ceiling) of the model
*
* @type {number}
*/
this
.
maxValue
=
0
;
/**
* Set to true if init method already executed
*
* @type {boolean}
*/
this
.
initHasRun
=
false
;
// Slider DOM elements wrapped in jqLite
this
.
fullBar
=
null
;
// The whole slider bar
this
.
selBar
=
null
;
// Highlight between two handles
this
.
minH
=
null
;
// Left slider handle
this
.
maxH
=
null
;
// Right slider handle
this
.
flrLab
=
null
;
// Floor label
this
.
ceilLab
=
null
;
// Ceiling label
this
.
minLab
=
null
;
// Label above the low value
this
.
maxLab
=
null
;
// Label above the high value
this
.
cmbLab
=
null
;
// Combined label
this
.
ticks
=
null
;
// The ticks
// Initialize slider
this
.
init
();
};
// Add instance methods
Slider
.
prototype
=
{
/**
* Initialize slider
*
* @returns {undefined}
*/
init
:
function
()
{
var
thrLow
,
thrHigh
,
calcDimFn
=
angular
.
bind
(
this
,
this
.
calcViewDimensions
),
self
=
this
;
this
.
applyOptions
();
this
.
initElemHandles
();
this
.
manageElementsStyle
();
this
.
addAccessibility
();
this
.
manageEventsBindings
();
this
.
setDisabledState
();
this
.
calcViewDimensions
();
this
.
setMinAndMax
();
$timeout
(
function
()
{
self
.
updateCeilLab
();
self
.
updateFloorLab
();
self
.
initHandles
();
self
.
bindEvents
();
});
/**
* The delta between min and max value
*
* @type {number}
*/
this
.
valueRange
=
0
;
// Recalculate slider view dimensions
this
.
scope
.
$on
(
'reCalcViewDimensions'
,
calcDimFn
);
/**
* Set to true if init method already executed
*
* @type {boolean}
*/
this
.
initHasRun
=
false
;
// Slider DOM elements wrapped in jqLite
this
.
fullBar
=
null
;
// The whole slider bar
this
.
selBar
=
null
;
// Highlight between two handles
this
.
minH
=
null
;
// Left slider handle
this
.
maxH
=
null
;
// Right slider handle
this
.
flrLab
=
null
;
// Floor label
this
.
ceilLab
=
null
;
// Ceiling label
this
.
minLab
=
null
;
// Label above the low value
this
.
maxLab
=
null
;
// Label above the high value
this
.
cmbLab
=
null
;
// Combined label
this
.
ticks
=
null
;
// The ticks
// Initialize slider
this
.
init
();
};
// Recalculate stuff if view port dimensions have changed
angular
.
element
(
$window
).
on
(
'resize'
,
calcDimFn
);
// Add instance methods
Slider
.
prototype
=
{
if
(
this
.
options
.
vertical
)
this
.
sliderElem
.
addClass
(
'vertical'
);
/**
* Initialize slider
*
* @returns {undefined}
*/
init
:
function
()
{
var
thrLow
,
thrHigh
,
calcDimFn
=
angular
.
bind
(
this
,
this
.
calcViewDimensions
),
self
=
this
;
this
.
applyOptions
();
this
.
initElemHandles
();
this
.
manageElementsStyle
();
this
.
addAccessibility
();
this
.
manageEventsBindings
();
this
.
setDisabledState
();
this
.
calcViewDimensions
();
this
.
setMinAndMax
();
this
.
initHasRun
=
true
;
$timeout
(
function
()
{
self
.
updateCeilLab
();
self
.
updateFloorLab
();
self
.
initHandles
();
self
.
bindEvents
();
});
// Watch for changes to the model
// Recalculate slider view dimensions
this
.
scope
.
$on
(
'reCalcViewDimensions'
,
calcDimFn
);
thrLow
=
rzThrottle
(
function
()
{
self
.
setMinAndMax
();
self
.
updateLowHandle
(
self
.
valueToOffset
(
self
.
scope
.
rzSliderModel
));
self
.
updateSelectionBar
();
self
.
updateTicksScale
();
// Recalculate stuff if view port dimensions have changed
angular
.
element
(
$window
).
on
(
'resize'
,
calcDimFn
);
if
(
self
.
range
)
{
self
.
updateCmbLabel
();
}
if
(
this
.
options
.
vertical
)
this
.
sliderElem
.
addClass
(
'vertical'
);
},
self
.
options
.
interval
);
thrHigh
=
rzThrottle
(
function
()
{
self
.
setMinAndMax
();
self
.
updateHighHandle
(
self
.
valueToOffset
(
self
.
scope
.
rzSliderHigh
));
self
.
updateSelectionBar
();
self
.
updateTicksScale
();
self
.
updateCmbLabel
();
},
self
.
options
.
interval
);
this
.
scope
.
$on
(
'rzSliderForceRender'
,
function
()
{
self
.
resetLabelsValue
();
thrLow
();
if
(
self
.
range
)
{
thrHigh
();
}
self
.
resetSlider
();
});
this
.
initHasRun
=
true
;
// Watchers
this
.
scope
.
$watch
(
'rzSliderModel'
,
function
(
newValue
,
oldValue
)
{
if
(
newValue
===
oldValue
)
return
;
thrLow
();
});
// Watch for changes to the model
this
.
scope
.
$watch
(
'rzSliderHigh'
,
function
(
newValue
,
oldValue
)
{
if
(
newValue
===
oldValue
)
return
;
if
(
newValue
!=
null
)
thrHigh
();
if
(
self
.
range
&&
newValue
==
null
||
!
self
.
range
&&
newValue
!=
null
)
{
self
.
applyOptions
();
self
.
resetSlider
();
}
});
thrLow
=
rzThrottle
(
function
()
{
self
.
setMinAndMax
();
self
.
updateLowHandle
(
self
.
valueToOffset
(
self
.
scope
.
rzSliderModel
));
self
.
updateSelectionBar
();
self
.
updateTicksScale
();
this
.
scope
.
$watch
(
'rzSliderOptions'
,
function
(
newValue
,
oldValue
)
{
if
(
newValue
===
oldValue
)
return
;
self
.
applyOptions
();
self
.
resetSlider
();
},
true
);
if
(
self
.
range
)
{
self
.
updateCmbLabel
();
}
this
.
scope
.
$on
(
'$destroy'
,
function
()
{
self
.
unbindEvents
();
angular
.
element
(
$window
).
off
(
'resize'
,
calcDimFn
);
});
},
},
self
.
options
.
interval
);
/**
* Read the user options and apply them to the slider model
*/
applyOptions
:
function
()
{
this
.
options
=
RzSliderOptions
.
getOptions
(
this
.
scope
.
rzSliderOptions
);
thrHigh
=
rzThrottle
(
function
()
{
self
.
setMinAndMax
();
self
.
updateHighHandle
(
self
.
valueToOffset
(
self
.
scope
.
rzSliderHigh
));
self
.
updateSelectionBar
();
self
.
updateTicksScale
();
self
.
updateCmbLabel
();
},
self
.
options
.
interval
);
if
(
this
.
options
.
step
<=
0
)
this
.
options
.
step
=
1
;
this
.
range
=
this
.
scope
.
rzSliderModel
!==
undefined
&&
this
.
scope
.
rzSliderHigh
!==
undefined
;
this
.
options
.
draggableRange
=
this
.
range
&&
this
.
options
.
draggableRange
;
this
.
options
.
showTicks
=
this
.
options
.
showTicks
||
this
.
options
.
showTicksValues
;
if
(
this
.
options
.
stepsArray
)
{
this
.
options
.
floor
=
0
;
this
.
options
.
ceil
=
this
.
options
.
stepsArray
.
length
-
1
;
this
.
options
.
step
=
1
;
this
.
customTrFn
=
function
(
value
)
{
return
this
.
options
.
stepsArray
[
value
];
};
}
else
if
(
this
.
options
.
translate
)
this
.
customTrFn
=
this
.
options
.
translate
;
else
this
.
customTrFn
=
function
(
value
)
{
return
String
(
value
);
};
this
.
scope
.
$on
(
'rzSliderForceRender'
,
function
()
{
self
.
resetLabelsValue
();
thrLow
();
if
(
self
.
range
)
{
thrHigh
();
}
self
.
resetSlider
();
});
if
(
this
.
options
.
vertical
)
{
this
.
positionProperty
=
'bottom'
;
this
.
dimensionProperty
=
'height'
;
}
},
// Watchers
this
.
scope
.
$watch
(
'rzSliderModel'
,
function
(
newValue
,
oldValue
)
{
if
(
newValue
===
oldValue
)
return
;
thrLow
();
});
/**
* Resets slider
*
* @returns {undefined}
*/
resetSlider
:
function
()
{
this
.
manageElementsStyle
();
this
.
setMinAndMax
();
this
.
updateCeilLab
();
this
.
updateFloorLab
();
this
.
unbindEvents
();
this
.
manageEventsBindings
();
this
.
setDisabledState
();
this
.
calcViewDimensions
();
},
this
.
scope
.
$watch
(
'rzSliderHigh'
,
function
(
newValue
,
oldValue
)
{
if
(
newValue
===
oldValue
)
return
;
if
(
newValue
!=
null
)
thrHigh
();
if
(
self
.
range
&&
newValue
==
null
||
!
self
.
range
&&
newValue
!=
null
)
{
self
.
applyOptions
();
self
.
resetSlider
();
}
});
/**
* Set the slider children to variables for easy access
*
* Run only once during initialization
*
* @returns {undefined}
*/
initElemHandles
:
function
()
{
// Assign all slider elements to object properties for easy access
angular
.
forEach
(
this
.
sliderElem
.
children
(),
function
(
elem
,
index
)
{
var
jElem
=
angular
.
element
(
elem
);
switch
(
index
)
{
case
0
:
this
.
fullBar
=
jElem
;
break
;
case
1
:
this
.
selBar
=
jElem
;
break
;
case
2
:
this
.
minH
=
jElem
;
break
;
case
3
:
this
.
maxH
=
jElem
;
break
;
case
4
:
this
.
flrLab
=
jElem
;
break
;
case
5
:
this
.
ceilLab
=
jElem
;
break
;
case
6
:
this
.
minLab
=
jElem
;
break
;
case
7
:
this
.
maxLab
=
jElem
;
break
;
case
8
:
this
.
cmbLab
=
jElem
;
break
;
case
9
:
this
.
ticks
=
jElem
;
break
;
}
this
.
scope
.
$watch
(
'rzSliderOptions'
,
function
(
newValue
,
oldValue
)
{
if
(
newValue
===
oldValue
)
return
;
self
.
applyOptions
();
self
.
resetSlider
();
},
true
);
},
this
);
this
.
scope
.
$on
(
'$destroy'
,
function
()
{
self
.
unbindEvents
();
angular
.
element
(
$window
).
off
(
'resize'
,
calcDimFn
);
});
},
// Initialize offset cache properties
this
.
selBar
.
rzsp
=
0
;
this
.
minH
.
rzsp
=
0
;
this
.
maxH
.
rzsp
=
0
;
this
.
flrLab
.
rzsp
=
0
;
this
.
ceilLab
.
rzsp
=
0
;
this
.
minLab
.
rzsp
=
0
;
this
.
maxLab
.
rzsp
=
0
;
this
.
cmbLab
.
rzsp
=
0
;
},
/**
* Read the user options and apply them to the slider model
*/
applyOptions
:
function
()
{
this
.
options
=
RzSliderOptions
.
getOptions
(
this
.
scope
.
rzSliderOptions
);
if
(
this
.
options
.
step
<=
0
)
this
.
options
.
step
=
1
;
this
.
range
=
this
.
scope
.
rzSliderModel
!==
undefined
&&
this
.
scope
.
rzSliderHigh
!==
undefined
;
this
.
options
.
draggableRange
=
this
.
range
&&
this
.
options
.
draggableRange
;
this
.
options
.
showTicks
=
this
.
options
.
showTicks
||
this
.
options
.
showTicksValues
;
if
(
this
.
options
.
stepsArray
)
{
this
.
options
.
floor
=
0
;
this
.
options
.
ceil
=
this
.
options
.
stepsArray
.
length
-
1
;
this
.
options
.
step
=
1
;
this
.
customTrFn
=
function
(
value
)
{
return
this
.
options
.
stepsArray
[
value
];
};
}
else
if
(
this
.
options
.
translate
)
this
.
customTrFn
=
this
.
options
.
translate
;
else
this
.
customTrFn
=
function
(
value
)
{
return
String
(
value
);
};
if
(
this
.
options
.
vertical
)
{
this
.
positionProperty
=
'bottom'
;
this
.
dimensionProperty
=
'height'
;
}
},
/** Update each elements style based on options
*
*/
manageElementsStyle
:
function
()
{
if
(
!
this
.
range
)
this
.
maxH
.
css
(
'display'
,
'none'
);
else
this
.
maxH
.
css
(
'display'
,
null
);
this
.
alwaysHide
(
this
.
flrLab
,
this
.
options
.
showTicksValues
||
this
.
options
.
hideLimitLabels
);
this
.
alwaysHide
(
this
.
ceilLab
,
this
.
options
.
showTicksValues
||
this
.
options
.
hideLimitLabels
);
this
.
alwaysHide
(
this
.
minLab
,
this
.
options
.
showTicksValues
);
this
.
alwaysHide
(
this
.
maxLab
,
this
.
options
.
showTicksValues
||
!
this
.
range
);
this
.
alwaysHide
(
this
.
cmbLab
,
this
.
options
.
showTicksValues
||
!
this
.
range
);
this
.
alwaysHide
(
this
.
selBar
,
!
this
.
range
&&
!
this
.
options
.
showSelectionBar
);
if
(
!
this
.
options
.
showTicks
)
this
.
ticks
.
html
(
''
);
if
(
this
.
options
.
draggableRange
)
this
.
selBar
.
addClass
(
'rz-draggable'
);
else
this
.
selBar
.
removeClass
(
'rz-draggable'
);
},
alwaysHide
:
function
(
el
,
hide
)
{
el
.
rzAlwaysHide
=
hide
;
if
(
hide
)
this
.
hideEl
(
el
);
else
this
.
showEl
(
el
)
},
/**
* Resets slider
*
* @returns {undefined}
*/
resetSlider
:
function
()
{
this
.
manageElementsStyle
();
this
.
setMinAndMax
();
this
.
updateCeilLab
();
this
.
updateFloorLab
();
/**
* Manage the events bindings based on readOnly and disabled options
*
* @returns {undefined}
*/
manageEventsBindings
:
function
()
{
if
(
this
.
options
.
disabled
||
this
.
options
.
readOnly
)
this
.
unbindEvents
();
this
.
manageEventsBindings
();
this
.
setDisabledState
();
this
.
calcViewDimensions
();
},
/**
* Set the slider children to variables for easy access
*
* Run only once during initialization
*
* @returns {undefined}
*/
initElemHandles
:
function
()
{
// Assign all slider elements to object properties for easy access
angular
.
forEach
(
this
.
sliderElem
.
children
(),
function
(
elem
,
index
)
{
var
jElem
=
angular
.
element
(
elem
);
switch
(
index
)
{
case
0
:
this
.
fullBar
=
jElem
;
break
;
case
1
:
this
.
selBar
=
jElem
;
break
;
case
2
:
this
.
minH
=
jElem
;
break
;
case
3
:
this
.
maxH
=
jElem
;
break
;
case
4
:
this
.
flrLab
=
jElem
;
break
;
case
5
:
this
.
ceilLab
=
jElem
;
break
;
case
6
:
this
.
minLab
=
jElem
;
break
;
case
7
:
this
.
maxLab
=
jElem
;
break
;
case
8
:
this
.
cmbLab
=
jElem
;
break
;
case
9
:
this
.
ticks
=
jElem
;
break
;
}
else
if
(
!
this
.
options
.
disabled
||
!
this
.
options
.
readOnly
)
this
.
bindEvents
();
},
},
this
);
// Initialize offset cache properties
this
.
selBar
.
rzsp
=
0
;
this
.
minH
.
rzsp
=
0
;
this
.
maxH
.
rzsp
=
0
;
this
.
flrLab
.
rzsp
=
0
;
this
.
ceilLab
.
rzsp
=
0
;
this
.
minLab
.
rzsp
=
0
;
this
.
maxLab
.
rzsp
=
0
;
this
.
cmbLab
.
rzsp
=
0
;
},
/** Update each elements style based on options
*
*/
manageElementsStyle
:
function
()
{
if
(
!
this
.
range
)
this
.
maxH
.
css
(
'display'
,
'none'
);
else
this
.
maxH
.
css
(
'display'
,
null
);
this
.
alwaysHide
(
this
.
flrLab
,
this
.
options
.
showTicksValues
||
this
.
options
.
hideLimitLabels
);
this
.
alwaysHide
(
this
.
ceilLab
,
this
.
options
.
showTicksValues
||
this
.
options
.
hideLimitLabels
);
this
.
alwaysHide
(
this
.
minLab
,
this
.
options
.
showTicksValues
);
this
.
alwaysHide
(
this
.
maxLab
,
this
.
options
.
showTicksValues
||
!
this
.
range
);
this
.
alwaysHide
(
this
.
cmbLab
,
this
.
options
.
showTicksValues
||
!
this
.
range
);
this
.
alwaysHide
(
this
.
selBar
,
!
this
.
range
&&
!
this
.
options
.
showSelectionBar
);
if
(
!
this
.
options
.
showTicks
)
this
.
ticks
.
html
(
''
);
if
(
this
.
options
.
draggableRange
)
this
.
selBar
.
addClass
(
'rz-draggable'
);
else
this
.
selBar
.
removeClass
(
'rz-draggable'
);
},
alwaysHide
:
function
(
el
,
hide
)
{
el
.
rzAlwaysHide
=
hide
;
if
(
hide
)
this
.
hideEl
(
el
);
else
this
.
showEl
(
el
)
},
/**
* Manage the events bindings based on readOnly and disabled options
*
* @returns {undefined}
*/
manageEventsBindings
:
function
()
{
if
(
this
.
options
.
disabled
||
this
.
options
.
readOnly
)
this
.
unbindEvents
();
else
if
(
!
this
.
options
.
disabled
||
!
this
.
options
.
readOnly
)
this
.
bindEvents
();
},
/**
* Set the disabled state based on rzSliderDisabled
*
* @returns {undefined}
*/
setDisabledState
:
function
()
{
if
(
this
.
options
.
disabled
)
{
this
.
sliderElem
.
attr
(
'disabled'
,
'disabled'
);
}
else
{
this
.
sliderElem
.
attr
(
'disabled'
,
null
);
}
},
/**
* Set the disabled state based on rzSliderDisabled
*
* @returns {undefined}
*/
setDisabledState
:
function
()
{
if
(
this
.
options
.
disabled
)
{
this
.
sliderElem
.
attr
(
'disabled'
,
'disabled'
);
}
else
{
this
.
sliderElem
.
attr
(
'disabled'
,
null
);
}
},
/**
* Reset label values
*
* @return {undefined}
*/
resetLabelsValue
:
function
()
{
this
.
minLab
.
rzsv
=
undefined
;
this
.
maxLab
.
rzsv
=
undefined
;
},
/**
* Initialize slider handles positions and labels
*
* Run only once during initialization and every time view port changes size
*
* @returns {undefined}
*/
initHandles
:
function
()
{
this
.
updateLowHandle
(
this
.
valueToOffset
(
this
.
scope
.
rzSliderModel
));
/*
the order here is important since the selection bar should be
updated after the high handle but before the combined label
*/
if
(
this
.
range
)
this
.
updateHighHandle
(
this
.
valueToOffset
(
this
.
scope
.
rzSliderHigh
));
this
.
updateSelectionBar
();
if
(
this
.
range
)
this
.
updateCmbLabel
();
/**
* Reset label values
*
* @return {undefined}
*/
resetLabelsValue
:
function
()
{
this
.
minLab
.
rzsv
=
undefined
;
this
.
maxLab
.
rzsv
=
undefined
;
},
this
.
updateTicksScale
();
},
/**
* Translate value to human readable format
*
* @param {number|string} value
* @param {jqLite} label
* @param {boolean} [useCustomTr]
* @returns {undefined}
/**
* Initialize slider handles positions and labels
*
* Run only once during initialization and every time view port changes size
*
* @returns {undefined}
*/
initHandles
:
function
()
{
this
.
updateLowHandle
(
this
.
valueToOffset
(
this
.
scope
.
rzSliderModel
));
/*
the order here is important since the selection bar should be
updated after the high handle but before the combined label
*/
translateFn
:
function
(
value
,
label
,
useCustomTr
)
{
useCustomTr
=
useCustomTr
===
undefined
?
true
:
useCustomTr
;
if
(
this
.
range
)
this
.
updateHighHandle
(
this
.
valueToOffset
(
this
.
scope
.
rzSliderHigh
));
this
.
updateSelectionBar
();
if
(
this
.
range
)
this
.
updateCmbLabel
();
var
valStr
=
String
((
useCustomTr
?
this
.
customTrFn
(
value
,
this
.
options
.
id
)
:
value
)),
getDimension
=
false
;
this
.
updateTicksScale
();
},
if
(
label
.
rzsv
===
undefined
||
label
.
rzsv
.
length
!==
valStr
.
length
||
(
label
.
rzsv
.
length
>
0
&&
label
.
rzsd
===
0
))
{
getDimension
=
true
;
label
.
rzsv
=
valStr
;
}
/**
* Translate value to human readable format
*
* @param {number|string} value
* @param {jqLite} label
* @param {boolean} [useCustomTr]
* @returns {undefined}
*/
translateFn
:
function
(
value
,
label
,
useCustomTr
)
{
useCustomTr
=
useCustomTr
===
undefined
?
true
:
useCustomTr
;
label
.
text
(
valStr
);
var
valStr
=
String
((
useCustomTr
?
this
.
customTrFn
(
value
,
this
.
options
.
id
)
:
value
)),
getDimension
=
false
;
// Update width only when length of the label have changed
if
(
getDimension
)
{
this
.
getDimension
(
label
);
}
},
if
(
label
.
rzsv
===
undefined
||
label
.
rzsv
.
length
!==
valStr
.
length
||
(
label
.
rzsv
.
length
>
0
&&
label
.
rzsd
===
0
))
{
getDimension
=
true
;
label
.
rzsv
=
valStr
;
}
/**
* Set maximum and minimum values for the slider and ensure the model and high
* value match these limits
* @returns {undefined}
*/
setMinAndMax
:
function
()
{
label
.
text
(
valStr
);
this
.
step
=
+
this
.
options
.
step
;
this
.
precision
=
+
this
.
options
.
precision
;
// Update width only when length of the label have changed
if
(
getDimension
)
{
this
.
getDimension
(
label
);
}
},
this
.
scope
.
rzSliderModel
=
this
.
roundStep
(
this
.
scope
.
rzSliderModel
);
if
(
this
.
range
)
this
.
scope
.
rzSliderHigh
=
this
.
roundStep
(
this
.
scope
.
rzSliderHigh
);
/**
* Set maximum and minimum values for the slider and ensure the model and high
* value match these limits
* @returns {undefined}
*/
setMinAndMax
:
function
()
{
this
.
minValue
=
this
.
roundStep
(
+
this
.
options
.
floor
);
this
.
step
=
+
this
.
options
.
step
;
this
.
precision
=
+
this
.
options
.
precision
;
if
(
this
.
options
.
ceil
!=
null
)
this
.
maxValue
=
this
.
roundStep
(
+
this
.
options
.
ceil
);
else
this
.
maxValue
=
this
.
options
.
ceil
=
this
.
range
?
this
.
scope
.
rzSliderHigh
:
this
.
scope
.
rzSliderModel
;
this
.
scope
.
rzSliderModel
=
this
.
roundStep
(
this
.
scope
.
rzSliderModel
);
if
(
this
.
range
)
this
.
scope
.
rzSliderHigh
=
this
.
roundStep
(
this
.
scope
.
rzSliderHigh
);
this
.
valueRange
=
this
.
maxValue
-
this
.
minValue
;
},
this
.
minValue
=
this
.
roundStep
(
+
this
.
options
.
floor
);
/**
* Adds accessibility atributes
*
* Run only once during initialization
*
* @returns {undefined}
*/
addAccessibility
:
function
()
{
this
.
sliderElem
.
attr
(
"role"
,
"slider"
);
},
/**
* Calculate dimensions that are dependent on view port size
*
* Run once during initialization and every time view port changes size.
*
* @returns {undefined}
*/
calcViewDimensions
:
function
()
{
var
handleWidth
=
this
.
getDimension
(
this
.
minH
);
if
(
this
.
options
.
ceil
!=
null
)
this
.
maxValue
=
this
.
roundStep
(
+
this
.
options
.
ceil
);
else
this
.
maxValue
=
this
.
options
.
ceil
=
this
.
range
?
this
.
scope
.
rzSliderHigh
:
this
.
scope
.
rzSliderModel
;
this
.
handleHalfDim
=
handleWidth
/
2
;
this
.
barDimension
=
this
.
getDimension
(
this
.
fullBar
);
this
.
valueRange
=
this
.
maxValue
-
this
.
minValue
;
},
this
.
maxPos
=
this
.
barDimension
-
handleWidth
;
/**
* Adds accessibility atributes
*
* Run only once during initialization
*
* @returns {undefined}
*/
addAccessibility
:
function
()
{
this
.
sliderElem
.
attr
(
"role"
,
"slider"
);
},
this
.
getDimension
(
this
.
sliderElem
);
this
.
sliderElem
.
rzsp
=
this
.
sliderElem
[
0
].
getBoundingClientRect
()[
this
.
positionProperty
];
/**
* Calculate dimensions that are dependent on view port size
*
* Run once during initialization and every time view port changes size.
*
* @returns {undefined}
*/
calcViewDimensions
:
function
()
{
var
handleWidth
=
this
.
getDimension
(
this
.
minH
);
if
(
this
.
initHasRun
)
{
this
.
updateFloorLab
();
this
.
updateCeilLab
();
this
.
initHandles
();
}
},
this
.
handleHalfDim
=
handleWidth
/
2
;
this
.
barDimension
=
this
.
getDimension
(
this
.
fullBar
);
/**
* Update the ticks position
*
* @returns {undefined}
*/
updateTicksScale
:
function
()
{
if
(
!
this
.
options
.
showTicks
)
return
;
if
(
!
this
.
step
)
return
;
//if step is 0, the following loop will be endless.
var
positions
=
''
,
ticksCount
=
Math
.
round
((
this
.
maxValue
-
this
.
minValue
)
/
this
.
step
)
+
1
;
for
(
var
i
=
0
;
i
<
ticksCount
;
i
++
)
{
var
value
=
this
.
roundStep
(
this
.
minValue
+
i
*
this
.
step
);
var
selectedClass
=
this
.
isTickSelected
(
value
)
?
'selected'
:
''
;
positions
+=
'<li class="tick '
+
selectedClass
+
'">'
;
if
(
this
.
options
.
showTicksValues
)
{
var
tooltip
=
''
;
if
(
this
.
options
.
ticksValuesTooltip
)
{
tooltip
=
'uib-tooltip="'
+
this
.
options
.
ticksValuesTooltip
(
value
)
+
'"'
;
if
(
this
.
options
.
vertical
)
tooltip
+=
' tooltip-placement="right"'
}
positions
+=
'<span '
+
tooltip
+
' class="tick-value">'
+
this
.
getDisplayValue
(
value
)
+
'</span>'
;
}
positions
+=
'</li>'
;
}
this
.
ticks
.
html
(
positions
);
if
(
this
.
options
.
ticksValuesTooltip
)
$compile
(
this
.
ticks
.
contents
())(
this
.
scope
);
},
isTickSelected
:
function
(
value
)
{
if
(
!
this
.
range
&&
this
.
options
.
showSelectionBar
&&
value
<=
this
.
scope
.
rzSliderModel
)
return
true
;
if
(
this
.
range
&&
value
>=
this
.
scope
.
rzSliderModel
&&
value
<=
this
.
scope
.
rzSliderHigh
)
return
true
;
return
false
;
},
/**
* Update position of the ceiling label
*
* @returns {undefined}
*/
updateCeilLab
:
function
()
{
this
.
translateFn
(
this
.
maxValue
,
this
.
ceilLab
);
this
.
setPosition
(
this
.
ceilLab
,
this
.
barDimension
-
this
.
ceilLab
.
rzsd
);
this
.
getDimension
(
this
.
ceilLab
);
},
/**
* Update position of the floor label
*
* @returns {undefined}
*/
updateFloorLab
:
function
()
{
this
.
translateFn
(
this
.
minValue
,
this
.
flrLab
);
this
.
getDimension
(
this
.
flrLab
);
},
/**
* Call the onStart callback if defined
*
* @returns {undefined}
*/
callOnStart
:
function
()
{
if
(
this
.
options
.
onStart
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onStart
(
self
.
options
.
id
);
});
}
},
this
.
maxPos
=
this
.
barDimension
-
handleWidth
;
/**
* Call the onChange callback if defined
*
* @returns {undefined}
*/
callOnChange
:
function
()
{
if
(
this
.
options
.
onChange
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onChange
(
self
.
options
.
id
);
});
}
},
this
.
getDimension
(
this
.
sliderElem
);
this
.
sliderElem
.
rzsp
=
this
.
sliderElem
[
0
].
getBoundingClientRect
()[
this
.
positionProperty
];
/**
* Call the onEnd callback if defined
*
* @returns {undefined}
*/
callOnEnd
:
function
()
{
if
(
this
.
options
.
onEnd
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onEnd
(
self
.
options
.
id
);
});
}
},
if
(
this
.
initHasRun
)
{
this
.
updateFloorLab
();
this
.
updateCeilLab
();
this
.
initHandles
();
}
},
/**
* Update slider handles and label positions
*
* @param {string} which
* @param {number} newOffset
*/
updateHandles
:
function
(
which
,
newOffset
)
{
if
(
which
===
'rzSliderModel'
)
{
this
.
updateLowHandle
(
newOffset
);
this
.
updateSelectionBar
();
this
.
updateTicksScale
();
if
(
this
.
range
)
{
this
.
updateCmbLabel
();
/**
* Update the ticks position
*
* @returns {undefined}
*/
updateTicksScale
:
function
()
{
if
(
!
this
.
options
.
showTicks
)
return
;
if
(
!
this
.
step
)
return
;
//if step is 0, the following loop will be endless.
var
positions
=
''
,
ticksCount
=
Math
.
round
((
this
.
maxValue
-
this
.
minValue
)
/
this
.
step
)
+
1
;
for
(
var
i
=
0
;
i
<
ticksCount
;
i
++
)
{
var
value
=
this
.
roundStep
(
this
.
minValue
+
i
*
this
.
step
);
var
selectedClass
=
this
.
isTickSelected
(
value
)
?
'selected'
:
''
;
positions
+=
'<li class="tick '
+
selectedClass
+
'">'
;
if
(
this
.
options
.
showTicksValues
)
{
var
tooltip
=
''
;
if
(
this
.
options
.
ticksValuesTooltip
)
{
tooltip
=
'uib-tooltip="'
+
this
.
options
.
ticksValuesTooltip
(
value
)
+
'"'
;
if
(
this
.
options
.
vertical
)
tooltip
+=
' tooltip-placement="right"'
}
return
;
positions
+=
'<span '
+
tooltip
+
' class="tick-value">'
+
this
.
getDisplayValue
(
value
)
+
'</span>'
;
}
positions
+=
'</li>'
;
}
this
.
ticks
.
html
(
positions
);
if
(
this
.
options
.
ticksValuesTooltip
)
$compile
(
this
.
ticks
.
contents
())(
this
.
scope
);
},
isTickSelected
:
function
(
value
)
{
if
(
!
this
.
range
&&
this
.
options
.
showSelectionBar
&&
value
<=
this
.
scope
.
rzSliderModel
)
return
true
;
if
(
this
.
range
&&
value
>=
this
.
scope
.
rzSliderModel
&&
value
<=
this
.
scope
.
rzSliderHigh
)
return
true
;
return
false
;
},
if
(
which
===
'rzSliderHigh'
)
{
this
.
updateHighHandle
(
newOffset
);
this
.
updateSelectionBar
();
this
.
updateTicksScale
();
/**
* Update position of the ceiling label
*
* @returns {undefined}
*/
updateCeilLab
:
function
()
{
this
.
translateFn
(
this
.
maxValue
,
this
.
ceilLab
);
this
.
setPosition
(
this
.
ceilLab
,
this
.
barDimension
-
this
.
ceilLab
.
rzsd
);
this
.
getDimension
(
this
.
ceilLab
);
},
if
(
this
.
range
)
{
this
.
updateCmbLabel
();
}
return
;
}
/**
* Update position of the floor label
*
* @returns {undefined}
*/
updateFloorLab
:
function
()
{
this
.
translateFn
(
this
.
minValue
,
this
.
flrLab
);
this
.
getDimension
(
this
.
flrLab
);
},
/**
* Call the onStart callback if defined
*
* @returns {undefined}
*/
callOnStart
:
function
()
{
if
(
this
.
options
.
onStart
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onStart
(
self
.
options
.
id
);
});
}
},
/**
* Call the onChange callback if defined
*
* @returns {undefined}
*/
callOnChange
:
function
()
{
if
(
this
.
options
.
onChange
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onChange
(
self
.
options
.
id
);
});
}
},
// Update both
/**
* Call the onEnd callback if defined
*
* @returns {undefined}
*/
callOnEnd
:
function
()
{
if
(
this
.
options
.
onEnd
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onEnd
(
self
.
options
.
id
);
});
}
},
/**
* Update slider handles and label positions
*
* @param {string} which
* @param {number} newOffset
*/
updateHandles
:
function
(
which
,
newOffset
)
{
if
(
which
===
'rzSliderModel'
)
{
this
.
updateLowHandle
(
newOffset
);
this
.
updateHighHandle
(
newOffset
);
this
.
updateSelectionBar
();
this
.
updateTicksScale
();
this
.
updateCmbLabel
();
},
/**
* Update low slider handle position and label
*
* @param {number} newOffset
* @returns {undefined}
*/
updateLowHandle
:
function
(
newOffset
)
{
this
.
setPosition
(
this
.
minH
,
newOffset
);
this
.
translateFn
(
this
.
scope
.
rzSliderModel
,
this
.
minLab
);
var
pos
=
Math
.
min
(
Math
.
max
(
newOffset
-
this
.
minLab
.
rzsd
/
2
+
this
.
handleHalfDim
,
0
),
this
.
barDimension
-
this
.
ceilLab
.
rzsd
);
this
.
setPosition
(
this
.
minLab
,
pos
);
this
.
shFloorCeil
();
},
/**
* Update high slider handle position and label
*
* @param {number} newOffset
* @returns {undefined}
*/
updateHighHandle
:
function
(
newOffset
)
{
this
.
setPosition
(
this
.
maxH
,
newOffset
);
this
.
translateFn
(
this
.
scope
.
rzSliderHigh
,
this
.
maxLab
);
var
pos
=
Math
.
min
((
newOffset
-
this
.
maxLab
.
rzsd
/
2
+
this
.
handleHalfDim
),
(
this
.
barDimension
-
this
.
ceilLab
.
rzsd
));
this
.
setPosition
(
this
.
maxLab
,
pos
);
this
.
shFloorCeil
();
},
/**
* Show / hide floor / ceiling label
*
* @returns {undefined}
*/
shFloorCeil
:
function
()
{
var
flHidden
=
false
,
clHidden
=
false
;
if
(
this
.
range
)
{
this
.
updateCmbLabel
();
}
return
;
}
if
(
this
.
minLab
.
rzsp
<=
this
.
flrLab
.
rzsp
+
this
.
flrLab
.
rzsd
+
5
)
{
flHidden
=
true
;
this
.
hideEl
(
this
.
flrLab
);
}
else
{
flHidden
=
false
;
this
.
showEl
(
this
.
flrLab
);
if
(
which
===
'rzSliderHigh'
)
{
this
.
updateHighHandle
(
newOffset
);
this
.
updateSelectionBar
();
this
.
updateTicksScale
();
if
(
this
.
range
)
{
this
.
updateCmbLabel
();
}
return
;
}
// Update both
this
.
updateLowHandle
(
newOffset
);
this
.
updateHighHandle
(
newOffset
);
this
.
updateSelectionBar
();
this
.
updateTicksScale
();
this
.
updateCmbLabel
();
},
/**
* Update low slider handle position and label
*
* @param {number} newOffset
* @returns {undefined}
*/
updateLowHandle
:
function
(
newOffset
)
{
this
.
setPosition
(
this
.
minH
,
newOffset
);
this
.
translateFn
(
this
.
scope
.
rzSliderModel
,
this
.
minLab
);
var
pos
=
Math
.
min
(
Math
.
max
(
newOffset
-
this
.
minLab
.
rzsd
/
2
+
this
.
handleHalfDim
,
0
),
this
.
barDimension
-
this
.
ceilLab
.
rzsd
);
this
.
setPosition
(
this
.
minLab
,
pos
);
this
.
shFloorCeil
();
},
/**
* Update high slider handle position and label
*
* @param {number} newOffset
* @returns {undefined}
*/
updateHighHandle
:
function
(
newOffset
)
{
this
.
setPosition
(
this
.
maxH
,
newOffset
);
this
.
translateFn
(
this
.
scope
.
rzSliderHigh
,
this
.
maxLab
);
var
pos
=
Math
.
min
((
newOffset
-
this
.
maxLab
.
rzsd
/
2
+
this
.
handleHalfDim
),
(
this
.
barDimension
-
this
.
ceilLab
.
rzsd
));
this
.
setPosition
(
this
.
maxLab
,
pos
);
this
.
shFloorCeil
();
},
if
(
this
.
minLab
.
rzsp
+
this
.
minLab
.
rzsd
>=
this
.
ceilLab
.
rzsp
-
this
.
handleHalfDim
-
10
)
{
clHidden
=
true
;
/**
* Show / hide floor / ceiling label
*
* @returns {undefined}
*/
shFloorCeil
:
function
()
{
var
flHidden
=
false
,
clHidden
=
false
;
if
(
this
.
minLab
.
rzsp
<=
this
.
flrLab
.
rzsp
+
this
.
flrLab
.
rzsd
+
5
)
{
flHidden
=
true
;
this
.
hideEl
(
this
.
flrLab
);
}
else
{
flHidden
=
false
;
this
.
showEl
(
this
.
flrLab
);
}
if
(
this
.
minLab
.
rzsp
+
this
.
minLab
.
rzsd
>=
this
.
ceilLab
.
rzsp
-
this
.
handleHalfDim
-
10
)
{
clHidden
=
true
;
this
.
hideEl
(
this
.
ceilLab
);
}
else
{
clHidden
=
false
;
this
.
showEl
(
this
.
ceilLab
);
}
if
(
this
.
range
)
{
if
(
this
.
maxLab
.
rzsp
+
this
.
maxLab
.
rzsd
>=
this
.
ceilLab
.
rzsp
-
10
)
{
this
.
hideEl
(
this
.
ceilLab
);
}
else
{
clHidden
=
false
;
}
else
if
(
!
clHidden
)
{
this
.
showEl
(
this
.
ceilLab
);
}
if
(
this
.
range
)
{
if
(
this
.
maxLab
.
rzsp
+
this
.
maxLab
.
rzsd
>=
this
.
ceilLab
.
rzsp
-
10
)
{
this
.
hideEl
(
this
.
ceilLab
);
}
else
if
(
!
clHidden
)
{
this
.
showEl
(
this
.
ceilLab
);
}
// Hide or show floor label
if
(
this
.
maxLab
.
rzsp
<=
this
.
flrLab
.
rzsp
+
this
.
flrLab
.
rzsd
+
this
.
handleHalfDim
)
{
this
.
hideEl
(
this
.
flrLab
);
}
else
if
(
!
flHidden
)
{
this
.
showEl
(
this
.
flrLab
);
}
// Hide or show floor label
if
(
this
.
maxLab
.
rzsp
<=
this
.
flrLab
.
rzsp
+
this
.
flrLab
.
rzsd
+
this
.
handleHalfDim
)
{
this
.
hideEl
(
this
.
flrLab
);
}
else
if
(
!
flHidden
)
{
this
.
showEl
(
this
.
flrLab
);
}
},
}
},
/**
* Update slider selection bar, combined label and range label
*
* @returns {undefined}
*/
updateSelectionBar
:
function
()
{
this
.
setDimension
(
this
.
selBar
,
Math
.
abs
(
this
.
maxH
.
rzsp
-
this
.
minH
.
rzsp
)
+
this
.
handleHalfDim
);
this
.
setPosition
(
this
.
selBar
,
this
.
range
?
this
.
minH
.
rzsp
+
this
.
handleHalfDim
:
0
);
},
/**
* Update combined label position and value
*
* @returns {undefined}
*/
updateCmbLabel
:
function
()
{
var
lowTr
,
highTr
;
if
(
this
.
minLab
.
rzsp
+
this
.
minLab
.
rzsd
+
10
>=
this
.
maxLab
.
rzsp
)
{
lowTr
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderModel
);
highTr
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderHigh
);
this
.
translateFn
(
lowTr
+
' - '
+
highTr
,
this
.
cmbLab
,
false
);
var
pos
=
Math
.
min
(
Math
.
max
((
this
.
selBar
.
rzsp
+
this
.
selBar
.
rzsd
/
2
-
this
.
cmbLab
.
rzsd
/
2
),
0
),
(
this
.
barDimension
-
this
.
cmbLab
.
rzsd
));
this
.
setPosition
(
this
.
cmbLab
,
pos
);
this
.
hideEl
(
this
.
minLab
);
this
.
hideEl
(
this
.
maxLab
);
this
.
showEl
(
this
.
cmbLab
);
}
else
{
this
.
showEl
(
this
.
maxLab
);
this
.
showEl
(
this
.
minLab
);
this
.
hideEl
(
this
.
cmbLab
);
}
},
/**
* Update slider selection bar, combined label and range label
*
* @returns {undefined}
*/
updateSelectionBar
:
function
()
{
this
.
setDimension
(
this
.
selBar
,
Math
.
abs
(
this
.
maxH
.
rzsp
-
this
.
minH
.
rzsp
)
+
this
.
handleHalfDim
);
this
.
setPosition
(
this
.
selBar
,
this
.
range
?
this
.
minH
.
rzsp
+
this
.
handleHalfDim
:
0
);
},
/**
* Return the translated value if a translate function is provided else the original value
* @param value
* @returns {*}
*/
getDisplayValue
:
function
(
value
)
{
return
this
.
customTrFn
(
value
,
this
.
options
.
id
);
},
/**
* Round value to step and precision
*
* @param {number} value
* @returns {number}
*/
roundStep
:
function
(
value
)
{
var
step
=
this
.
step
,
remainder
=
+
((
value
-
this
.
minValue
)
%
step
).
toFixed
(
3
),
steppedValue
=
remainder
>
(
step
/
2
)
?
value
+
step
-
remainder
:
value
-
remainder
;
steppedValue
=
steppedValue
.
toFixed
(
this
.
precision
);
return
+
steppedValue
;
},
/**
* Hide element
*
* @param element
* @returns {jqLite} The jqLite wrapped DOM element
*/
hideEl
:
function
(
element
)
{
return
element
.
css
({
opacity
:
0
});
},
/**
* Update combined label position and value
*
* @returns {undefined}
*/
updateCmbLabel
:
function
()
{
var
lowTr
,
highTr
;
if
(
this
.
minLab
.
rzsp
+
this
.
minLab
.
rzsd
+
10
>=
this
.
maxLab
.
rzsp
)
{
lowTr
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderModel
);
highTr
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderHigh
);
this
.
translateFn
(
lowTr
+
' - '
+
highTr
,
this
.
cmbLab
,
false
);
var
pos
=
Math
.
min
(
Math
.
max
((
this
.
selBar
.
rzsp
+
this
.
selBar
.
rzsd
/
2
-
this
.
cmbLab
.
rzsd
/
2
),
0
),
(
this
.
barDimension
-
this
.
cmbLab
.
rzsd
));
this
.
setPosition
(
this
.
cmbLab
,
pos
);
this
.
hideEl
(
this
.
minLab
);
this
.
hideEl
(
this
.
maxLab
);
this
.
showEl
(
this
.
cmbLab
);
}
else
{
this
.
showEl
(
this
.
maxLab
);
this
.
showEl
(
this
.
minLab
);
this
.
hideEl
(
this
.
cmbLab
);
}
},
/**
* Show element
*
* @param element The jqLite wrapped DOM element
* @returns {jqLite} The jqLite
*/
showEl
:
function
(
element
)
{
if
(
!!
element
.
rzAlwaysHide
)
{
return
element
;
}
/**
* Return the translated value if a translate function is provided else the original value
* @param value
* @returns {*}
*/
getDisplayValue
:
function
(
value
)
{
return
this
.
customTrFn
(
value
,
this
.
options
.
id
);
},
return
element
.
css
({
opacity
:
1
});
},
/**
* Set element left/top offset depending on whether slider is horizontal or vertical
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @param {number} pos
* @returns {number}
*/
setPosition
:
function
(
elem
,
pos
)
{
elem
.
rzsp
=
pos
;
var
css
=
{};
css
[
this
.
positionProperty
]
=
pos
+
'px'
;
elem
.
css
(
css
);
return
pos
;
},
/**
* Get element width/height depending on whether slider is horizontal or vertical
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @returns {number}
*/
getDimension
:
function
(
elem
)
{
var
val
=
elem
[
0
].
getBoundingClientRect
();
if
(
this
.
options
.
vertical
)
elem
.
rzsd
=
(
val
.
bottom
-
val
.
top
)
*
this
.
options
.
scale
;
else
elem
.
rzsd
=
(
val
.
right
-
val
.
left
)
*
this
.
options
.
scale
;
return
elem
.
rzsd
;
},
/**
* Set element width/height depending on whether slider is horizontal or vertical
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @param {number} dim
* @returns {number}
*/
setDimension
:
function
(
elem
,
dim
)
{
elem
.
rzsd
=
dim
;
var
css
=
{};
css
[
this
.
dimensionProperty
]
=
dim
+
'px'
;
elem
.
css
(
css
);
return
dim
;
},
/**
* Translate value to pixel offset
*
* @param {number} val
* @returns {number}
*/
valueToOffset
:
function
(
val
)
{
return
(
this
.
sanitizeOffsetValue
(
val
)
-
this
.
minValue
)
*
this
.
maxPos
/
this
.
valueRange
||
0
;
},
/**
* Ensure that the position rendered is within the slider bounds, even if the value is not
*
* @param {number} val
* @returns {number}
*/
sanitizeOffsetValue
:
function
(
val
)
{
return
Math
.
min
(
Math
.
max
(
val
,
this
.
minValue
),
this
.
maxValue
);
},
/**
* Translate offset to model value
*
* @param {number} offset
* @returns {number}
*/
offsetToValue
:
function
(
offset
)
{
return
(
offset
/
this
.
maxPos
)
*
this
.
valueRange
+
this
.
minValue
;
},
/**
* Round value to step and precision
*
* @param {number} value
* @returns {number}
*/
roundStep
:
function
(
value
)
{
var
step
=
this
.
step
,
remainder
=
+
((
value
-
this
.
minValue
)
%
step
).
toFixed
(
3
),
steppedValue
=
remainder
>
(
step
/
2
)
?
value
+
step
-
remainder
:
value
-
remainder
;
// Events
steppedValue
=
steppedValue
.
toFixed
(
this
.
precision
);
return
+
steppedValue
;
},
/**
* Get the X-coordinate or Y-coordinate of an event
*
* @param {Object} event The event
* @returns {number}
*/
getEventXY
:
function
(
event
)
{
/* http://stackoverflow.com/a/12336075/282882 */
//noinspection JSLint
var
clientXY
=
this
.
options
.
vertical
?
'clientY'
:
'clientX'
;
if
(
clientXY
in
event
)
{
return
event
[
clientXY
];
}
/**
* Hide element
*
* @param element
* @returns {jqLite} The jqLite wrapped DOM element
*/
hideEl
:
function
(
element
)
{
return
element
.
css
({
opacity
:
0
});
},
return
event
.
originalEvent
===
undefined
?
event
.
touches
[
0
][
clientXY
]
:
event
.
originalEvent
.
touches
[
0
][
clientXY
];
},
/**
* Show element
*
* @param element The jqLite wrapped DOM element
* @returns {jqLite} The jqLite
*/
showEl
:
function
(
element
)
{
if
(
!!
element
.
rzAlwaysHide
)
{
return
element
;
}
/**
* Compute the event position depending on whether the slider is horizontal or vertical
* @param event
* @returns {number}
*/
getEventPosition
:
function
(
event
)
{
var
sliderPos
=
this
.
sliderElem
.
rzsp
,
eventPos
=
0
;
if
(
this
.
options
.
vertical
)
eventPos
=
-
this
.
getEventXY
(
event
)
+
sliderPos
;
else
eventPos
=
this
.
getEventXY
(
event
)
-
sliderPos
;
return
(
eventPos
-
this
.
handleHalfDim
)
*
this
.
options
.
scale
;
},
/**
* Get the handle closest to an event.
*
* @param event {Event} The event
* @returns {jqLite} The handle closest to the event.
*/
getNearestHandle
:
function
(
event
)
{
if
(
!
this
.
range
)
{
return
this
.
minH
;
}
var
offset
=
this
.
getEventPosition
(
event
);
return
Math
.
abs
(
offset
-
this
.
minH
.
rzsp
)
<
Math
.
abs
(
offset
-
this
.
maxH
.
rzsp
)
?
this
.
minH
:
this
.
maxH
;
},
/**
* Bind mouse and touch events to slider handles
*
* @returns {undefined}
*/
bindEvents
:
function
()
{
if
(
this
.
options
.
readOnly
||
this
.
options
.
disabled
)
return
;
var
barTracking
,
barStart
,
barMove
;
if
(
this
.
options
.
draggableRange
)
{
barTracking
=
'rzSliderDrag'
;
barStart
=
this
.
onDragStart
;
barMove
=
this
.
onDragMove
;
}
else
{
barTracking
=
'rzSliderModel'
;
barStart
=
this
.
onStart
;
barMove
=
this
.
onMove
;
}
return
element
.
css
({
opacity
:
1
});
},
this
.
minH
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
minH
,
'rzSliderModel'
));
if
(
this
.
range
)
{
this
.
maxH
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
maxH
,
'rzSliderHigh'
));
}
this
.
fullBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
this
.
fullBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
fullBar
));
this
.
selBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
barStart
,
null
,
barTracking
));
this
.
selBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
barMove
,
this
.
selBar
));
this
.
ticks
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
this
.
ticks
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
ticks
));
this
.
minH
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
minH
,
'rzSliderModel'
));
if
(
this
.
range
)
{
this
.
maxH
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
maxH
,
'rzSliderHigh'
));
}
this
.
fullBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
this
.
fullBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
fullBar
));
this
.
selBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
barStart
,
null
,
barTracking
));
this
.
selBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
barMove
,
this
.
selBar
));
this
.
ticks
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
this
.
ticks
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
ticks
));
},
/**
* Unbind mouse and touch events to slider handles
*
* @returns {undefined}
*/
unbindEvents
:
function
()
{
this
.
minH
.
off
();
this
.
maxH
.
off
();
this
.
fullBar
.
off
();
this
.
selBar
.
off
();
this
.
ticks
.
off
();
},
/**
* onStart event handler
*
* @param {?Object} pointer The jqLite wrapped DOM element; if null, the closest handle is used
* @param {?string} ref The name of the handle being changed; if null, the closest handle's value is modified
* @param {Event} event The event
* @returns {undefined}
*/
onStart
:
function
(
pointer
,
ref
,
event
)
{
var
ehMove
,
ehEnd
,
eventNames
=
this
.
getEventNames
(
event
);
/**
* Set element left/top offset depending on whether slider is horizontal or vertical
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @param {number} pos
* @returns {number}
*/
setPosition
:
function
(
elem
,
pos
)
{
elem
.
rzsp
=
pos
;
var
css
=
{};
css
[
this
.
positionProperty
]
=
pos
+
'px'
;
elem
.
css
(
css
);
return
pos
;
},
event
.
stopPropagation
();
event
.
preventDefault
();
/**
* Get element width/height depending on whether slider is horizontal or vertical
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @returns {number}
*/
getDimension
:
function
(
elem
)
{
var
val
=
elem
[
0
].
getBoundingClientRect
();
if
(
this
.
options
.
vertical
)
elem
.
rzsd
=
(
val
.
bottom
-
val
.
top
)
*
this
.
options
.
scale
;
else
elem
.
rzsd
=
(
val
.
right
-
val
.
left
)
*
this
.
options
.
scale
;
return
elem
.
rzsd
;
},
if
(
this
.
tracking
!==
''
)
{
return
;
}
/**
* Set element width/height depending on whether slider is horizontal or vertical
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @param {number} dim
* @returns {number}
*/
setDimension
:
function
(
elem
,
dim
)
{
elem
.
rzsd
=
dim
;
var
css
=
{};
css
[
this
.
dimensionProperty
]
=
dim
+
'px'
;
elem
.
css
(
css
);
return
dim
;
},
// We have to do this in case the HTML where the sliders are on
// have been animated into view.
this
.
calcViewDimensions
();
/**
* Translate value to pixel offset
*
* @param {number} val
* @returns {number}
*/
valueToOffset
:
function
(
val
)
{
return
(
this
.
sanitizeOffsetValue
(
val
)
-
this
.
minValue
)
*
this
.
maxPos
/
this
.
valueRange
||
0
;
},
if
(
pointer
)
{
this
.
tracking
=
ref
;
}
else
{
pointer
=
this
.
getNearestHandle
(
event
);
this
.
tracking
=
pointer
===
this
.
minH
?
'rzSliderModel'
:
'rzSliderHigh'
;
}
/**
* Ensure that the position rendered is within the slider bounds, even if the value is not
*
* @param {number} val
* @returns {number}
*/
sanitizeOffsetValue
:
function
(
val
)
{
return
Math
.
min
(
Math
.
max
(
val
,
this
.
minValue
),
this
.
maxValue
);
},
pointer
.
addClass
(
'rz-active'
);
/**
* Translate offset to model value
*
* @param {number} offset
* @returns {number}
*/
offsetToValue
:
function
(
offset
)
{
return
(
offset
/
this
.
maxPos
)
*
this
.
valueRange
+
this
.
minValue
;
},
ehMove
=
angular
.
bind
(
this
,
this
.
dragging
.
active
?
this
.
onDragMove
:
this
.
onMove
,
pointer
);
ehEnd
=
angular
.
bind
(
this
,
this
.
onEnd
,
ehMove
);
// Events
$document
.
on
(
eventNames
.
moveEvent
,
ehMove
);
$document
.
one
(
eventNames
.
endEvent
,
ehEnd
);
this
.
callOnStart
();
},
/**
* Get the X-coordinate or Y-coordinate of an event
*
* @param {Object} event The event
* @returns {number}
*/
getEventXY
:
function
(
event
)
{
/* http://stackoverflow.com/a/12336075/282882 */
//noinspection JSLint
var
clientXY
=
this
.
options
.
vertical
?
'clientY'
:
'clientX'
;
if
(
clientXY
in
event
)
{
return
event
[
clientXY
];
}
/**
* onMove event handler
*
* @param {jqLite} pointer
* @param {Event} event The event
* @returns {undefined}
*/
onMove
:
function
(
pointer
,
event
)
{
var
newOffset
=
this
.
getEventPosition
(
event
),
newValue
;
if
(
newOffset
<=
0
)
{
if
(
pointer
.
rzsp
===
0
)
return
;
newValue
=
this
.
minValue
;
newOffset
=
0
;
}
else
if
(
newOffset
>=
this
.
maxPos
)
{
if
(
pointer
.
rzsp
===
this
.
maxPos
)
return
;
newValue
=
this
.
maxValue
;
newOffset
=
this
.
maxPos
;
}
else
{
newValue
=
this
.
offsetToValue
(
newOffset
);
newValue
=
this
.
roundStep
(
newValue
);
newOffset
=
this
.
valueToOffset
(
newValue
);
}
this
.
positionTrackingHandle
(
newValue
,
newOffset
);
},
/**
* onDragStart event handler
*
* Handles dragging of the middle bar.
*
* @param {Object} pointer The jqLite wrapped DOM element
* @param {string} ref One of the refLow, refHigh values
* @param {Event} event The event
* @returns {undefined}
*/
onDragStart
:
function
(
pointer
,
ref
,
event
)
{
var
offset
=
this
.
getEventPosition
(
event
);
this
.
dragging
=
{
active
:
true
,
value
:
this
.
offsetToValue
(
offset
),
difference
:
this
.
scope
.
rzSliderHigh
-
this
.
scope
.
rzSliderModel
,
offset
:
offset
,
lowDist
:
offset
-
this
.
minH
.
rzsp
,
highDist
:
this
.
maxH
.
rzsp
-
offset
};
this
.
minH
.
addClass
(
'rz-active'
);
this
.
maxH
.
addClass
(
'rz-active'
);
this
.
onStart
(
pointer
,
ref
,
event
);
},
/**
* onDragMove event handler
*
* Handles dragging of the middle bar.
*
* @param {jqLite} pointer
* @param {Event} event The event
* @returns {undefined}
*/
onDragMove
:
function
(
pointer
,
event
)
{
var
newOffset
=
this
.
getEventPosition
(
event
),
newMinOffset
,
newMaxOffset
,
newMinValue
,
newMaxValue
;
if
(
newOffset
<=
this
.
dragging
.
lowDist
)
{
if
(
pointer
.
rzsp
===
this
.
dragging
.
lowDist
)
{
return
;
}
newMinValue
=
this
.
minValue
;
newMinOffset
=
0
;
newMaxValue
=
this
.
minValue
+
this
.
dragging
.
difference
;
newMaxOffset
=
this
.
valueToOffset
(
newMaxValue
);
}
else
if
(
newOffset
>=
this
.
maxPos
-
this
.
dragging
.
highDist
)
{
if
(
pointer
.
rzsp
===
this
.
dragging
.
highDist
)
{
return
;
}
newMaxValue
=
this
.
maxValue
;
newMaxOffset
=
this
.
maxPos
;
newMinValue
=
this
.
maxValue
-
this
.
dragging
.
difference
;
newMinOffset
=
this
.
valueToOffset
(
newMinValue
);
}
else
{
newMinValue
=
this
.
offsetToValue
(
newOffset
-
this
.
dragging
.
lowDist
);
newMinValue
=
this
.
roundStep
(
newMinValue
);
newMinOffset
=
this
.
valueToOffset
(
newMinValue
);
newMaxValue
=
newMinValue
+
this
.
dragging
.
difference
;
newMaxOffset
=
this
.
valueToOffset
(
newMaxValue
);
}
return
event
.
originalEvent
===
undefined
?
event
.
touches
[
0
][
clientXY
]
:
event
.
originalEvent
.
touches
[
0
][
clientXY
];
},
this
.
positionTrackingBar
(
newMinValue
,
newMaxValue
,
newMinOffset
,
newMaxOffset
);
},
/**
* Compute the event position depending on whether the slider is horizontal or vertical
* @param event
* @returns {number}
*/
getEventPosition
:
function
(
event
)
{
var
sliderPos
=
this
.
sliderElem
.
rzsp
,
eventPos
=
0
;
if
(
this
.
options
.
vertical
)
eventPos
=
-
this
.
getEventXY
(
event
)
+
sliderPos
;
else
eventPos
=
this
.
getEventXY
(
event
)
-
sliderPos
;
return
(
eventPos
-
this
.
handleHalfDim
)
*
this
.
options
.
scale
;
},
/**
* Set the new value and offset for the entire bar
*
* @param {number} newMinValue the new minimum value
* @param {number} newMaxValue the new maximum value
* @param {number} newMinOffset the new minimum offset
* @param {number} newMaxOffset the new maximum offset
*/
positionTrackingBar
:
function
(
newMinValue
,
newMaxValue
,
newMinOffset
,
newMaxOffset
)
{
this
.
scope
.
rzSliderModel
=
newMinValue
;
this
.
scope
.
rzSliderHigh
=
newMaxValue
;
this
.
updateHandles
(
'rzSliderModel'
,
newMinOffset
);
this
.
updateHandles
(
'rzSliderHigh'
,
newMaxOffset
);
this
.
scope
.
$apply
();
this
.
callOnChange
();
},
/**
* Get the handle closest to an event.
*
* @param event {Event} The event
* @returns {jqLite} The handle closest to the event.
*/
getNearestHandle
:
function
(
event
)
{
if
(
!
this
.
range
)
{
return
this
.
minH
;
}
var
offset
=
this
.
getEventPosition
(
event
);
return
Math
.
abs
(
offset
-
this
.
minH
.
rzsp
)
<
Math
.
abs
(
offset
-
this
.
maxH
.
rzsp
)
?
this
.
minH
:
this
.
maxH
;
},
/**
* Set the new value and offset to the current tracking handle
*
* @param {number} newValue new model value
* @param {number} newOffset new offset value
*/
positionTrackingHandle
:
function
(
newValue
,
newOffset
)
{
if
(
this
.
range
)
{
/* This is to check if we need to switch the min and max handles*/
if
(
this
.
tracking
===
'rzSliderModel'
&&
newValue
>=
this
.
scope
.
rzSliderHigh
)
{
this
.
scope
[
this
.
tracking
]
=
this
.
scope
.
rzSliderHigh
;
this
.
updateHandles
(
this
.
tracking
,
this
.
maxH
.
rzsp
);
this
.
tracking
=
'rzSliderHigh'
;
this
.
minH
.
removeClass
(
'rz-active'
);
this
.
maxH
.
addClass
(
'rz-active'
);
/* We need to apply here because we are not sure that we will enter the next block */
this
.
scope
.
$apply
();
this
.
callOnChange
();
}
else
if
(
this
.
tracking
===
'rzSliderHigh'
&&
newValue
<=
this
.
scope
.
rzSliderModel
)
{
this
.
scope
[
this
.
tracking
]
=
this
.
scope
.
rzSliderModel
;
this
.
updateHandles
(
this
.
tracking
,
this
.
minH
.
rzsp
);
this
.
tracking
=
'rzSliderModel'
;
this
.
maxH
.
removeClass
(
'rz-active'
);
this
.
minH
.
addClass
(
'rz-active'
);
/* We need to apply here because we are not sure that we will enter the next block */
this
.
scope
.
$apply
();
this
.
callOnChange
();
}
/**
* Bind mouse and touch events to slider handles
*
* @returns {undefined}
*/
bindEvents
:
function
()
{
if
(
this
.
options
.
readOnly
||
this
.
options
.
disabled
)
return
;
var
barTracking
,
barStart
,
barMove
;
if
(
this
.
options
.
draggableRange
)
{
barTracking
=
'rzSliderDrag'
;
barStart
=
this
.
onDragStart
;
barMove
=
this
.
onDragMove
;
}
else
{
barTracking
=
'rzSliderModel'
;
barStart
=
this
.
onStart
;
barMove
=
this
.
onMove
;
}
this
.
minH
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
minH
,
'rzSliderModel'
));
if
(
this
.
range
)
{
this
.
maxH
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
maxH
,
'rzSliderHigh'
));
}
this
.
fullBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
this
.
fullBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
fullBar
));
this
.
selBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
barStart
,
null
,
barTracking
));
this
.
selBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
barMove
,
this
.
selBar
));
this
.
ticks
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
this
.
ticks
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
ticks
));
this
.
minH
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
minH
,
'rzSliderModel'
));
if
(
this
.
range
)
{
this
.
maxH
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
maxH
,
'rzSliderHigh'
));
}
this
.
fullBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
this
.
fullBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
fullBar
));
this
.
selBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
barStart
,
null
,
barTracking
));
this
.
selBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
barMove
,
this
.
selBar
));
this
.
ticks
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
this
.
ticks
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
ticks
));
},
/**
* Unbind mouse and touch events to slider handles
*
* @returns {undefined}
*/
unbindEvents
:
function
()
{
this
.
minH
.
off
();
this
.
maxH
.
off
();
this
.
fullBar
.
off
();
this
.
selBar
.
off
();
this
.
ticks
.
off
();
},
/**
* onStart event handler
*
* @param {?Object} pointer The jqLite wrapped DOM element; if null, the closest handle is used
* @param {?string} ref The name of the handle being changed; if null, the closest handle's value is modified
* @param {Event} event The event
* @returns {undefined}
*/
onStart
:
function
(
pointer
,
ref
,
event
)
{
var
ehMove
,
ehEnd
,
eventNames
=
this
.
getEventNames
(
event
);
event
.
stopPropagation
();
event
.
preventDefault
();
if
(
this
.
tracking
!==
''
)
{
return
;
}
// We have to do this in case the HTML where the sliders are on
// have been animated into view.
this
.
calcViewDimensions
();
if
(
pointer
)
{
this
.
tracking
=
ref
;
}
else
{
pointer
=
this
.
getNearestHandle
(
event
);
this
.
tracking
=
pointer
===
this
.
minH
?
'rzSliderModel'
:
'rzSliderHigh'
;
}
pointer
.
addClass
(
'rz-active'
);
ehMove
=
angular
.
bind
(
this
,
this
.
dragging
.
active
?
this
.
onDragMove
:
this
.
onMove
,
pointer
);
ehEnd
=
angular
.
bind
(
this
,
this
.
onEnd
,
ehMove
);
$document
.
on
(
eventNames
.
moveEvent
,
ehMove
);
$document
.
one
(
eventNames
.
endEvent
,
ehEnd
);
this
.
callOnStart
();
},
/**
* onMove event handler
*
* @param {jqLite} pointer
* @param {Event} event The event
* @returns {undefined}
*/
onMove
:
function
(
pointer
,
event
)
{
var
newOffset
=
this
.
getEventPosition
(
event
),
newValue
;
if
(
newOffset
<=
0
)
{
if
(
pointer
.
rzsp
===
0
)
return
;
newValue
=
this
.
minValue
;
newOffset
=
0
;
}
else
if
(
newOffset
>=
this
.
maxPos
)
{
if
(
pointer
.
rzsp
===
this
.
maxPos
)
return
;
newValue
=
this
.
maxValue
;
newOffset
=
this
.
maxPos
;
}
else
{
newValue
=
this
.
offsetToValue
(
newOffset
);
newValue
=
this
.
roundStep
(
newValue
);
newOffset
=
this
.
valueToOffset
(
newValue
);
}
this
.
positionTrackingHandle
(
newValue
,
newOffset
);
},
/**
* onDragStart event handler
*
* Handles dragging of the middle bar.
*
* @param {Object} pointer The jqLite wrapped DOM element
* @param {string} ref One of the refLow, refHigh values
* @param {Event} event The event
* @returns {undefined}
*/
onDragStart
:
function
(
pointer
,
ref
,
event
)
{
var
offset
=
this
.
getEventPosition
(
event
);
this
.
dragging
=
{
active
:
true
,
value
:
this
.
offsetToValue
(
offset
),
difference
:
this
.
scope
.
rzSliderHigh
-
this
.
scope
.
rzSliderModel
,
offset
:
offset
,
lowDist
:
offset
-
this
.
minH
.
rzsp
,
highDist
:
this
.
maxH
.
rzsp
-
offset
};
this
.
minH
.
addClass
(
'rz-active'
);
this
.
maxH
.
addClass
(
'rz-active'
);
this
.
onStart
(
pointer
,
ref
,
event
);
},
/**
* onDragMove event handler
*
* Handles dragging of the middle bar.
*
* @param {jqLite} pointer
* @param {Event} event The event
* @returns {undefined}
*/
onDragMove
:
function
(
pointer
,
event
)
{
var
newOffset
=
this
.
getEventPosition
(
event
),
newMinOffset
,
newMaxOffset
,
newMinValue
,
newMaxValue
;
if
(
newOffset
<=
this
.
dragging
.
lowDist
)
{
if
(
pointer
.
rzsp
===
this
.
dragging
.
lowDist
)
{
return
;
}
newMinValue
=
this
.
minValue
;
newMinOffset
=
0
;
newMaxValue
=
this
.
minValue
+
this
.
dragging
.
difference
;
newMaxOffset
=
this
.
valueToOffset
(
newMaxValue
);
}
else
if
(
newOffset
>=
this
.
maxPos
-
this
.
dragging
.
highDist
)
{
if
(
pointer
.
rzsp
===
this
.
dragging
.
highDist
)
{
return
;
}
newMaxValue
=
this
.
maxValue
;
newMaxOffset
=
this
.
maxPos
;
newMinValue
=
this
.
maxValue
-
this
.
dragging
.
difference
;
newMinOffset
=
this
.
valueToOffset
(
newMinValue
);
}
else
{
newMinValue
=
this
.
offsetToValue
(
newOffset
-
this
.
dragging
.
lowDist
);
newMinValue
=
this
.
roundStep
(
newMinValue
);
newMinOffset
=
this
.
valueToOffset
(
newMinValue
);
newMaxValue
=
newMinValue
+
this
.
dragging
.
difference
;
newMaxOffset
=
this
.
valueToOffset
(
newMaxValue
);
}
this
.
positionTrackingBar
(
newMinValue
,
newMaxValue
,
newMinOffset
,
newMaxOffset
);
},
/**
* Set the new value and offset for the entire bar
*
* @param {number} newMinValue the new minimum value
* @param {number} newMaxValue the new maximum value
* @param {number} newMinOffset the new minimum offset
* @param {number} newMaxOffset the new maximum offset
*/
positionTrackingBar
:
function
(
newMinValue
,
newMaxValue
,
newMinOffset
,
newMaxOffset
)
{
this
.
scope
.
rzSliderModel
=
newMinValue
;
this
.
scope
.
rzSliderHigh
=
newMaxValue
;
this
.
updateHandles
(
'rzSliderModel'
,
newMinOffset
);
this
.
updateHandles
(
'rzSliderHigh'
,
newMaxOffset
);
this
.
scope
.
$apply
();
this
.
callOnChange
();
},
if
(
this
.
scope
[
this
.
tracking
]
!==
newValue
)
{
this
.
scope
[
this
.
tracking
]
=
newValue
;
this
.
updateHandles
(
this
.
tracking
,
newOffset
);
/**
* Set the new value and offset to the current tracking handle
*
* @param {number} newValue new model value
* @param {number} newOffset new offset value
*/
positionTrackingHandle
:
function
(
newValue
,
newOffset
)
{
if
(
this
.
range
)
{
/* This is to check if we need to switch the min and max handles*/
if
(
this
.
tracking
===
'rzSliderModel'
&&
newValue
>=
this
.
scope
.
rzSliderHigh
)
{
this
.
scope
[
this
.
tracking
]
=
this
.
scope
.
rzSliderHigh
;
this
.
updateHandles
(
this
.
tracking
,
this
.
maxH
.
rzsp
);
this
.
tracking
=
'rzSliderHigh'
;
this
.
minH
.
removeClass
(
'rz-active'
);
this
.
maxH
.
addClass
(
'rz-active'
);
/* We need to apply here because we are not sure that we will enter the next block */
this
.
scope
.
$apply
();
this
.
callOnChange
();
}
else
if
(
this
.
tracking
===
'rzSliderHigh'
&&
newValue
<=
this
.
scope
.
rzSliderModel
)
{
this
.
scope
[
this
.
tracking
]
=
this
.
scope
.
rzSliderModel
;
this
.
updateHandles
(
this
.
tracking
,
this
.
minH
.
rzsp
);
this
.
tracking
=
'rzSliderModel'
;
this
.
maxH
.
removeClass
(
'rz-active'
);
this
.
minH
.
addClass
(
'rz-active'
);
/* We need to apply here because we are not sure that we will enter the next block */
this
.
scope
.
$apply
();
this
.
callOnChange
();
}
},
/**
* onEnd event handler
*
* @param {Event} event The event
* @param {Function} ehMove The the bound move event handler
* @returns {undefined}
*/
onEnd
:
function
(
ehMove
,
event
)
{
var
moveEventName
=
this
.
getEventNames
(
event
).
moveEvent
;
}
if
(
this
.
scope
[
this
.
tracking
]
!==
newValue
)
{
this
.
scope
[
this
.
tracking
]
=
newValue
;
this
.
updateHandles
(
this
.
tracking
,
newOffset
);
this
.
scope
.
$apply
();
this
.
callOnChange
();
}
},
this
.
minH
.
removeClass
(
'rz-active'
);
this
.
maxH
.
removeClass
(
'rz-active'
);
/**
* onEnd event handler
*
* @param {Event} event The event
* @param {Function} ehMove The the bound move event handler
* @returns {undefined}
*/
onEnd
:
function
(
ehMove
,
event
)
{
var
moveEventName
=
this
.
getEventNames
(
event
).
moveEvent
;
$document
.
off
(
moveEventName
,
ehMove
);
this
.
minH
.
removeClass
(
'rz-active'
);
this
.
maxH
.
removeClass
(
'rz-active'
);
this
.
scope
.
$emit
(
'slideEnded'
);
this
.
tracking
=
''
;
$document
.
off
(
moveEventName
,
ehMove
);
this
.
dragging
.
active
=
false
;
this
.
callOnEnd
();
},
this
.
scope
.
$emit
(
'slideEnded'
);
this
.
tracking
=
''
;
/**
* Get event names for move and event end
*
* @param {Event} event The event
*
* @return {{moveEvent: string, endEvent: string}}
*/
getEventNames
:
function
(
event
)
{
var
eventNames
=
{
moveEvent
:
''
,
endEvent
:
''
};
this
.
dragging
.
active
=
false
;
this
.
callOnEnd
();
},
if
(
event
.
touches
||
(
event
.
originalEvent
!==
undefined
&&
event
.
originalEvent
.
touches
))
{
eventNames
.
moveEvent
=
'touchmove'
;
eventNames
.
endEvent
=
'touchend'
;
}
else
{
eventNames
.
moveEvent
=
'mousemove'
;
eventNames
.
endEvent
=
'mouseup'
;
}
/**
* Get event names for move and event end
*
* @param {Event} event The event
*
* @return {{moveEvent: string, endEvent: string}}
*/
getEventNames
:
function
(
event
)
{
var
eventNames
=
{
moveEvent
:
''
,
endEvent
:
''
};
return
eventNames
;
if
(
event
.
touches
||
(
event
.
originalEvent
!==
undefined
&&
event
.
originalEvent
.
touches
))
{
eventNames
.
moveEvent
=
'touchmove'
;
eventNames
.
endEvent
=
'touchend'
;
}
else
{
eventNames
.
moveEvent
=
'mousemove'
;
eventNames
.
endEvent
=
'mouseup'
;
}
};
return
Slider
;
}])
return
eventNames
;
}
};
.
directive
(
'rzslider'
,
[
'RzSlider'
,
function
(
RzSlider
)
{
'use strict'
;
return
Slider
;
}])
return
{
restrict
:
'E'
,
scope
:
{
rzSliderModel
:
'=?'
,
rzSliderHigh
:
'=?'
,
rzSliderOptions
:
'=?'
,
rzSliderTplUrl
:
'@'
},
/**
* Return template URL
*
* @param {jqLite} elem
* @param {Object} attrs
* @return {string}
*/
templateUrl
:
function
(
elem
,
attrs
)
{
//noinspection JSUnresolvedVariable
return
attrs
.
rzSliderTplUrl
||
'rzSliderTpl.html'
;
},
.
directive
(
'rzslider'
,
[
'RzSlider'
,
function
(
RzSlider
)
{
'use strict'
;
link
:
function
(
scope
,
elem
)
{
return
new
RzSlider
(
scope
,
elem
);
}
};
}]);
return
{
restrict
:
'E'
,
scope
:
{
rzSliderModel
:
'=?'
,
rzSliderHigh
:
'=?'
,
rzSliderOptions
:
'=?'
,
rzSliderTplUrl
:
'@'
},
/**
* Return template URL
*
* @param {jqLite} elem
* @param {Object} attrs
* @return {string}
*/
templateUrl
:
function
(
elem
,
attrs
)
{
//noinspection JSUnresolvedVariable
return
attrs
.
rzSliderTplUrl
||
'rzSliderTpl.html'
;
},
link
:
function
(
scope
,
elem
)
{
return
new
RzSlider
(
scope
,
elem
);
}
};
}]);
// IDE assist
...
...
dist/rzslider.min.js
View file @
3775ce08
/*! angularjs-slider - v2.1.0 - (c) Rafal Zajac <rzajac@gmail.com>, Valentin Hervieu <valentin@hervieu.me>, Jussi Saarivirta <jusasi@gmail.com>, Angelin Sirbu <angelin.sirbu@gmail.com>, https://github.com/rzajac/angularjs-slider.git - 2015-1
1-29
*/
/*! angularjs-slider - v2.1.0 - (c) Rafal Zajac <rzajac@gmail.com>, Valentin Hervieu <valentin@hervieu.me>, Jussi Saarivirta <jusasi@gmail.com>, Angelin Sirbu <angelin.sirbu@gmail.com>, https://github.com/rzajac/angularjs-slider.git - 2015-1
2-06
*/
!
function
(
a
,
b
){
"use strict"
;
"function"
==
typeof
define
&&
define
.
amd
?
define
([
"angular"
],
b
):
"object"
==
typeof
module
&&
module
.
exports
?
module
.
exports
=
b
(
require
(
"angular"
)):
b
(
a
.
angular
)}(
this
,
function
(
a
){
"use strict"
;
var
b
=
a
.
module
(
"rzModule"
,[]).
factory
(
"RzSliderOptions"
,
function
(){
var
b
=
{
floor
:
0
,
ceil
:
null
,
step
:
1
,
precision
:
0
,
id
:
null
,
translate
:
null
,
stepsArray
:
null
,
draggableRange
:
!
1
,
showSelectionBar
:
!
1
,
hideLimitLabels
:
!
1
,
readOnly
:
!
1
,
disabled
:
!
1
,
interval
:
350
,
showTicks
:
!
1
,
showTicksValues
:
!
1
,
ticksValuesTooltip
:
null
,
vertical
:
!
1
,
scale
:
1
,
onStart
:
null
,
onChange
:
null
,
onEnd
:
null
},
c
=
{},
d
=
{};
return
d
.
options
=
function
(
b
){
a
.
extend
(
c
,
b
)},
d
.
getOptions
=
function
(
d
){
return
a
.
extend
({},
b
,
c
,
d
)},
d
}).
value
(
"rzThrottle"
,
function
(
a
,
b
,
c
){
var
d
,
e
,
f
,
g
=
Date
.
now
||
function
(){
return
(
new
Date
).
getTime
()},
h
=
null
,
i
=
0
;
c
=
c
||
{};
var
j
=
function
(){
i
=
c
.
leading
===!
1
?
0
:
g
(),
h
=
null
,
f
=
a
.
apply
(
d
,
e
),
d
=
e
=
null
};
return
function
(){
var
k
=
g
();
i
||
c
.
leading
!==!
1
||
(
i
=
k
);
var
l
=
b
-
(
k
-
i
);
return
d
=
this
,
e
=
arguments
,
0
>=
l
?(
clearTimeout
(
h
),
h
=
null
,
i
=
k
,
f
=
a
.
apply
(
d
,
e
),
d
=
e
=
null
):
h
||
c
.
trailing
===!
1
||
(
h
=
setTimeout
(
j
,
l
)),
f
}}).
factory
(
"RzSlider"
,[
"$timeout"
,
"$document"
,
"$window"
,
"$compile"
,
"RzSliderOptions"
,
"rzThrottle"
,
function
(
b
,
c
,
d
,
e
,
f
,
g
){
var
h
=
function
(
a
,
b
){
this
.
scope
=
a
,
this
.
sliderElem
=
b
,
this
.
range
=
void
0
!==
this
.
scope
.
rzSliderModel
&&
void
0
!==
this
.
scope
.
rzSliderHigh
,
this
.
dragging
=
{
active
:
!
1
,
value
:
0
,
difference
:
0
,
offset
:
0
,
lowDist
:
0
,
highDist
:
0
},
this
.
positionProperty
=
"left"
,
this
.
dimensionProperty
=
"width"
,
this
.
handleHalfDim
=
0
,
this
.
maxPos
=
0
,
this
.
precision
=
0
,
this
.
step
=
0
,
this
.
tracking
=
""
,
this
.
minValue
=
0
,
this
.
maxValue
=
0
,
this
.
valueRange
=
0
,
this
.
initHasRun
=!
1
,
this
.
fullBar
=
null
,
this
.
selBar
=
null
,
this
.
minH
=
null
,
this
.
maxH
=
null
,
this
.
flrLab
=
null
,
this
.
ceilLab
=
null
,
this
.
minLab
=
null
,
this
.
maxLab
=
null
,
this
.
cmbLab
=
null
,
this
.
ticks
=
null
,
this
.
init
()};
return
h
.
prototype
=
{
init
:
function
(){
var
c
,
e
,
f
=
a
.
bind
(
this
,
this
.
calcViewDimensions
),
h
=
this
;
this
.
applyOptions
(),
this
.
initElemHandles
(),
this
.
manageElementsStyle
(),
this
.
addAccessibility
(),
this
.
manageEventsBindings
(),
this
.
setDisabledState
(),
this
.
calcViewDimensions
(),
this
.
setMinAndMax
(),
b
(
function
(){
h
.
updateCeilLab
(),
h
.
updateFloorLab
(),
h
.
initHandles
(),
h
.
bindEvents
()}),
this
.
scope
.
$on
(
"reCalcViewDimensions"
,
f
),
a
.
element
(
d
).
on
(
"resize"
,
f
),
this
.
options
.
vertical
&&
this
.
sliderElem
.
addClass
(
"vertical"
),
this
.
initHasRun
=!
0
,
c
=
g
(
function
(){
h
.
setMinAndMax
(),
h
.
updateLowHandle
(
h
.
valueToOffset
(
h
.
scope
.
rzSliderModel
)),
h
.
updateSelectionBar
(),
h
.
updateTicksScale
(),
h
.
range
&&
h
.
updateCmbLabel
()},
h
.
options
.
interval
),
e
=
g
(
function
(){
h
.
setMinAndMax
(),
h
.
updateHighHandle
(
h
.
valueToOffset
(
h
.
scope
.
rzSliderHigh
)),
h
.
updateSelectionBar
(),
h
.
updateTicksScale
(),
h
.
updateCmbLabel
()},
h
.
options
.
interval
),
this
.
scope
.
$on
(
"rzSliderForceRender"
,
function
(){
h
.
resetLabelsValue
(),
c
(),
h
.
range
&&
e
(),
h
.
resetSlider
()}),
this
.
scope
.
$watch
(
"rzSliderModel"
,
function
(
a
,
b
){
a
!==
b
&&
c
()}),
this
.
scope
.
$watch
(
"rzSliderHigh"
,
function
(
a
,
b
){
a
!==
b
&&
(
null
!=
a
&&
e
(),(
h
.
range
&&
null
==
a
||!
h
.
range
&&
null
!=
a
)
&&
(
h
.
applyOptions
(),
h
.
resetSlider
()))}),
this
.
scope
.
$watch
(
"rzSliderOptions"
,
function
(
a
,
b
){
a
!==
b
&&
(
h
.
applyOptions
(),
h
.
resetSlider
())},
!
0
),
this
.
scope
.
$on
(
"$destroy"
,
function
(){
h
.
unbindEvents
(),
a
.
element
(
d
).
off
(
"resize"
,
f
)})},
applyOptions
:
function
(){
this
.
options
=
f
.
getOptions
(
this
.
scope
.
rzSliderOptions
),
this
.
options
.
step
<=
0
&&
(
this
.
options
.
step
=
1
),
this
.
range
=
void
0
!==
this
.
scope
.
rzSliderModel
&&
void
0
!==
this
.
scope
.
rzSliderHigh
,
this
.
options
.
draggableRange
=
this
.
range
&&
this
.
options
.
draggableRange
,
this
.
options
.
showTicks
=
this
.
options
.
showTicks
||
this
.
options
.
showTicksValues
,
this
.
options
.
stepsArray
?(
this
.
options
.
floor
=
0
,
this
.
options
.
ceil
=
this
.
options
.
stepsArray
.
length
-
1
,
this
.
options
.
step
=
1
,
this
.
customTrFn
=
function
(
a
){
return
this
.
options
.
stepsArray
[
a
]}):
this
.
options
.
translate
?
this
.
customTrFn
=
this
.
options
.
translate
:
this
.
customTrFn
=
function
(
a
){
return
String
(
a
)},
this
.
options
.
vertical
&&
(
this
.
positionProperty
=
"bottom"
,
this
.
dimensionProperty
=
"height"
)},
resetSlider
:
function
(){
this
.
manageElementsStyle
(),
this
.
setMinAndMax
(),
this
.
updateCeilLab
(),
this
.
updateFloorLab
(),
this
.
unbindEvents
(),
this
.
manageEventsBindings
(),
this
.
setDisabledState
(),
this
.
calcViewDimensions
()},
initElemHandles
:
function
(){
a
.
forEach
(
this
.
sliderElem
.
children
(),
function
(
b
,
c
){
var
d
=
a
.
element
(
b
);
switch
(
c
){
case
0
:
this
.
fullBar
=
d
;
break
;
case
1
:
this
.
selBar
=
d
;
break
;
case
2
:
this
.
minH
=
d
;
break
;
case
3
:
this
.
maxH
=
d
;
break
;
case
4
:
this
.
flrLab
=
d
;
break
;
case
5
:
this
.
ceilLab
=
d
;
break
;
case
6
:
this
.
minLab
=
d
;
break
;
case
7
:
this
.
maxLab
=
d
;
break
;
case
8
:
this
.
cmbLab
=
d
;
break
;
case
9
:
this
.
ticks
=
d
}},
this
),
this
.
selBar
.
rzsp
=
0
,
this
.
minH
.
rzsp
=
0
,
this
.
maxH
.
rzsp
=
0
,
this
.
flrLab
.
rzsp
=
0
,
this
.
ceilLab
.
rzsp
=
0
,
this
.
minLab
.
rzsp
=
0
,
this
.
maxLab
.
rzsp
=
0
,
this
.
cmbLab
.
rzsp
=
0
},
manageElementsStyle
:
function
(){
this
.
range
?
this
.
maxH
.
css
(
"display"
,
null
):
this
.
maxH
.
css
(
"display"
,
"none"
),
this
.
alwaysHide
(
this
.
flrLab
,
this
.
options
.
showTicksValues
||
this
.
options
.
hideLimitLabels
),
this
.
alwaysHide
(
this
.
ceilLab
,
this
.
options
.
showTicksValues
||
this
.
options
.
hideLimitLabels
),
this
.
alwaysHide
(
this
.
minLab
,
this
.
options
.
showTicksValues
),
this
.
alwaysHide
(
this
.
maxLab
,
this
.
options
.
showTicksValues
||!
this
.
range
),
this
.
alwaysHide
(
this
.
cmbLab
,
this
.
options
.
showTicksValues
||!
this
.
range
),
this
.
alwaysHide
(
this
.
selBar
,
!
this
.
range
&&!
this
.
options
.
showSelectionBar
),
this
.
options
.
showTicks
||
this
.
ticks
.
html
(
""
),
this
.
options
.
draggableRange
?
this
.
selBar
.
addClass
(
"rz-draggable"
):
this
.
selBar
.
removeClass
(
"rz-draggable"
)},
alwaysHide
:
function
(
a
,
b
){
a
.
rzAlwaysHide
=
b
,
b
?
this
.
hideEl
(
a
):
this
.
showEl
(
a
)},
manageEventsBindings
:
function
(){
this
.
options
.
disabled
||
this
.
options
.
readOnly
?
this
.
unbindEvents
():
this
.
options
.
disabled
&&
this
.
options
.
readOnly
||
this
.
bindEvents
()},
setDisabledState
:
function
(){
this
.
options
.
disabled
?
this
.
sliderElem
.
attr
(
"disabled"
,
"disabled"
):
this
.
sliderElem
.
attr
(
"disabled"
,
null
)},
resetLabelsValue
:
function
(){
this
.
minLab
.
rzsv
=
void
0
,
this
.
maxLab
.
rzsv
=
void
0
},
initHandles
:
function
(){
this
.
updateLowHandle
(
this
.
valueToOffset
(
this
.
scope
.
rzSliderModel
)),
this
.
range
&&
this
.
updateHighHandle
(
this
.
valueToOffset
(
this
.
scope
.
rzSliderHigh
)),
this
.
updateSelectionBar
(),
this
.
range
&&
this
.
updateCmbLabel
(),
this
.
updateTicksScale
()},
translateFn
:
function
(
a
,
b
,
c
){
c
=
void
0
===
c
?
!
0
:
c
;
var
d
=
String
(
c
?
this
.
customTrFn
(
a
,
this
.
options
.
id
):
a
),
e
=!
1
;(
void
0
===
b
.
rzsv
||
b
.
rzsv
.
length
!==
d
.
length
||
b
.
rzsv
.
length
>
0
&&
0
===
b
.
rzsd
)
&&
(
e
=!
0
,
b
.
rzsv
=
d
),
b
.
text
(
d
),
e
&&
this
.
getDimension
(
b
)},
setMinAndMax
:
function
(){
this
.
step
=+
this
.
options
.
step
,
this
.
precision
=+
this
.
options
.
precision
,
this
.
scope
.
rzSliderModel
=
this
.
roundStep
(
this
.
scope
.
rzSliderModel
),
this
.
range
&&
(
this
.
scope
.
rzSliderHigh
=
this
.
roundStep
(
this
.
scope
.
rzSliderHigh
)),
this
.
minValue
=
this
.
roundStep
(
+
this
.
options
.
floor
),
null
!=
this
.
options
.
ceil
?
this
.
maxValue
=
this
.
roundStep
(
+
this
.
options
.
ceil
):
this
.
maxValue
=
this
.
options
.
ceil
=
this
.
range
?
this
.
scope
.
rzSliderHigh
:
this
.
scope
.
rzSliderModel
,
this
.
valueRange
=
this
.
maxValue
-
this
.
minValue
},
addAccessibility
:
function
(){
this
.
sliderElem
.
attr
(
"role"
,
"slider"
)},
calcViewDimensions
:
function
(){
var
a
=
this
.
getDimension
(
this
.
minH
);
this
.
handleHalfDim
=
a
/
2
,
this
.
barDimension
=
this
.
getDimension
(
this
.
fullBar
),
this
.
maxPos
=
this
.
barDimension
-
a
,
this
.
getDimension
(
this
.
sliderElem
),
this
.
sliderElem
.
rzsp
=
this
.
sliderElem
[
0
].
getBoundingClientRect
()[
this
.
positionProperty
],
this
.
initHasRun
&&
(
this
.
updateFloorLab
(),
this
.
updateCeilLab
(),
this
.
initHandles
())},
updateTicksScale
:
function
(){
if
(
this
.
options
.
showTicks
&&
this
.
step
){
for
(
var
a
=
""
,
b
=
Math
.
round
((
this
.
maxValue
-
this
.
minValue
)
/
this
.
step
)
+
1
,
c
=
0
;
b
>
c
;
c
++
){
var
d
=
this
.
roundStep
(
this
.
minValue
+
c
*
this
.
step
),
f
=
this
.
isTickSelected
(
d
)?
"selected"
:
""
;
if
(
a
+=
'<li class="tick '
+
f
+
'">'
,
this
.
options
.
showTicksValues
){
var
g
=
""
;
this
.
options
.
ticksValuesTooltip
&&
(
g
=
'uib-tooltip="'
+
this
.
options
.
ticksValuesTooltip
(
d
)
+
'"'
,
this
.
options
.
vertical
&&
(
g
+=
' tooltip-placement="right"'
)),
a
+=
"<span "
+
g
+
' class="tick-value">'
+
this
.
getDisplayValue
(
d
)
+
"</span>"
}
a
+=
"</li>"
}
this
.
ticks
.
html
(
a
),
this
.
options
.
ticksValuesTooltip
&&
e
(
this
.
ticks
.
contents
())(
this
.
scope
)}},
isTickSelected
:
function
(
a
){
return
!
this
.
range
&&
this
.
options
.
showSelectionBar
&&
a
<=
this
.
scope
.
rzSliderModel
?
!
0
:
this
.
range
&&
a
>=
this
.
scope
.
rzSliderModel
&&
a
<=
this
.
scope
.
rzSliderHigh
?
!
0
:
!
1
},
updateCeilLab
:
function
(){
this
.
translateFn
(
this
.
maxValue
,
this
.
ceilLab
),
this
.
setPosition
(
this
.
ceilLab
,
this
.
barDimension
-
this
.
ceilLab
.
rzsd
),
this
.
getDimension
(
this
.
ceilLab
)},
updateFloorLab
:
function
(){
this
.
translateFn
(
this
.
minValue
,
this
.
flrLab
),
this
.
getDimension
(
this
.
flrLab
)},
callOnStart
:
function
(){
if
(
this
.
options
.
onStart
){
var
a
=
this
;
b
(
function
(){
a
.
options
.
onStart
(
a
.
options
.
id
)})}},
callOnChange
:
function
(){
if
(
this
.
options
.
onChange
){
var
a
=
this
;
b
(
function
(){
a
.
options
.
onChange
(
a
.
options
.
id
)})}},
callOnEnd
:
function
(){
if
(
this
.
options
.
onEnd
){
var
a
=
this
;
b
(
function
(){
a
.
options
.
onEnd
(
a
.
options
.
id
)})}},
updateHandles
:
function
(
a
,
b
){
return
"rzSliderModel"
===
a
?(
this
.
updateLowHandle
(
b
),
this
.
updateSelectionBar
(),
this
.
updateTicksScale
(),
void
(
this
.
range
&&
this
.
updateCmbLabel
())):
"rzSliderHigh"
===
a
?(
this
.
updateHighHandle
(
b
),
this
.
updateSelectionBar
(),
this
.
updateTicksScale
(),
void
(
this
.
range
&&
this
.
updateCmbLabel
())):(
this
.
updateLowHandle
(
b
),
this
.
updateHighHandle
(
b
),
this
.
updateSelectionBar
(),
this
.
updateTicksScale
(),
void
this
.
updateCmbLabel
())},
updateLowHandle
:
function
(
a
){
this
.
setPosition
(
this
.
minH
,
a
),
this
.
translateFn
(
this
.
scope
.
rzSliderModel
,
this
.
minLab
);
var
b
=
Math
.
min
(
Math
.
max
(
a
-
this
.
minLab
.
rzsd
/
2
+
this
.
handleHalfDim
,
0
),
this
.
barDimension
-
this
.
ceilLab
.
rzsd
);
this
.
setPosition
(
this
.
minLab
,
b
),
this
.
shFloorCeil
()},
updateHighHandle
:
function
(
a
){
this
.
setPosition
(
this
.
maxH
,
a
),
this
.
translateFn
(
this
.
scope
.
rzSliderHigh
,
this
.
maxLab
);
var
b
=
Math
.
min
(
a
-
this
.
maxLab
.
rzsd
/
2
+
this
.
handleHalfDim
,
this
.
barDimension
-
this
.
ceilLab
.
rzsd
);
this
.
setPosition
(
this
.
maxLab
,
b
),
this
.
shFloorCeil
()},
shFloorCeil
:
function
(){
var
a
=!
1
,
b
=!
1
;
this
.
minLab
.
rzsp
<=
this
.
flrLab
.
rzsp
+
this
.
flrLab
.
rzsd
+
5
?(
a
=!
0
,
this
.
hideEl
(
this
.
flrLab
)):(
a
=!
1
,
this
.
showEl
(
this
.
flrLab
)),
this
.
minLab
.
rzsp
+
this
.
minLab
.
rzsd
>=
this
.
ceilLab
.
rzsp
-
this
.
handleHalfDim
-
10
?(
b
=!
0
,
this
.
hideEl
(
this
.
ceilLab
)):(
b
=!
1
,
this
.
showEl
(
this
.
ceilLab
)),
this
.
range
&&
(
this
.
maxLab
.
rzsp
+
this
.
maxLab
.
rzsd
>=
this
.
ceilLab
.
rzsp
-
10
?
this
.
hideEl
(
this
.
ceilLab
):
b
||
this
.
showEl
(
this
.
ceilLab
),
this
.
maxLab
.
rzsp
<=
this
.
flrLab
.
rzsp
+
this
.
flrLab
.
rzsd
+
this
.
handleHalfDim
?
this
.
hideEl
(
this
.
flrLab
):
a
||
this
.
showEl
(
this
.
flrLab
))},
updateSelectionBar
:
function
(){
this
.
setDimension
(
this
.
selBar
,
Math
.
abs
(
this
.
maxH
.
rzsp
-
this
.
minH
.
rzsp
)
+
this
.
handleHalfDim
),
this
.
setPosition
(
this
.
selBar
,
this
.
range
?
this
.
minH
.
rzsp
+
this
.
handleHalfDim
:
0
)},
updateCmbLabel
:
function
(){
var
a
,
b
;
if
(
this
.
minLab
.
rzsp
+
this
.
minLab
.
rzsd
+
10
>=
this
.
maxLab
.
rzsp
){
a
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderModel
),
b
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderHigh
),
this
.
translateFn
(
a
+
" - "
+
b
,
this
.
cmbLab
,
!
1
);
var
c
=
Math
.
min
(
Math
.
max
(
this
.
selBar
.
rzsp
+
this
.
selBar
.
rzsd
/
2
-
this
.
cmbLab
.
rzsd
/
2
,
0
),
this
.
barDimension
-
this
.
cmbLab
.
rzsd
);
this
.
setPosition
(
this
.
cmbLab
,
c
),
this
.
hideEl
(
this
.
minLab
),
this
.
hideEl
(
this
.
maxLab
),
this
.
showEl
(
this
.
cmbLab
)}
else
this
.
showEl
(
this
.
maxLab
),
this
.
showEl
(
this
.
minLab
),
this
.
hideEl
(
this
.
cmbLab
)},
getDisplayValue
:
function
(
a
){
return
this
.
customTrFn
(
a
,
this
.
options
.
id
)},
roundStep
:
function
(
a
){
var
b
=
this
.
step
,
c
=+
((
a
-
this
.
minValue
)
%
b
).
toFixed
(
3
),
d
=
c
>
b
/
2
?
a
+
b
-
c
:
a
-
c
;
return
d
=
d
.
toFixed
(
this
.
precision
),
+
d
},
hideEl
:
function
(
a
){
return
a
.
css
({
opacity
:
0
})},
showEl
:
function
(
a
){
return
a
.
rzAlwaysHide
?
a
:
a
.
css
({
opacity
:
1
})},
setPosition
:
function
(
a
,
b
){
a
.
rzsp
=
b
;
var
c
=
{};
return
c
[
this
.
positionProperty
]
=
b
+
"px"
,
a
.
css
(
c
),
b
},
getDimension
:
function
(
a
){
var
b
=
a
[
0
].
getBoundingClientRect
();
return
this
.
options
.
vertical
?
a
.
rzsd
=
(
b
.
bottom
-
b
.
top
)
*
this
.
options
.
scale
:
a
.
rzsd
=
(
b
.
right
-
b
.
left
)
*
this
.
options
.
scale
,
a
.
rzsd
},
setDimension
:
function
(
a
,
b
){
a
.
rzsd
=
b
;
var
c
=
{};
return
c
[
this
.
dimensionProperty
]
=
b
+
"px"
,
a
.
css
(
c
),
b
},
valueToOffset
:
function
(
a
){
return
(
this
.
sanitizeOffsetValue
(
a
)
-
this
.
minValue
)
*
this
.
maxPos
/
this
.
valueRange
||
0
},
sanitizeOffsetValue
:
function
(
a
){
return
Math
.
min
(
Math
.
max
(
a
,
this
.
minValue
),
this
.
maxValue
)},
offsetToValue
:
function
(
a
){
return
a
/
this
.
maxPos
*
this
.
valueRange
+
this
.
minValue
},
getEventXY
:
function
(
a
){
var
b
=
this
.
options
.
vertical
?
"clientY"
:
"clientX"
;
return
b
in
a
?
a
[
b
]:
void
0
===
a
.
originalEvent
?
a
.
touches
[
0
][
b
]:
a
.
originalEvent
.
touches
[
0
][
b
]},
getEventPosition
:
function
(
a
){
var
b
=
this
.
sliderElem
.
rzsp
,
c
=
0
;
return
c
=
this
.
options
.
vertical
?
-
this
.
getEventXY
(
a
)
+
b
:
this
.
getEventXY
(
a
)
-
b
,(
c
-
this
.
handleHalfDim
)
*
this
.
options
.
scale
},
getNearestHandle
:
function
(
a
){
if
(
!
this
.
range
)
return
this
.
minH
;
var
b
=
this
.
getEventPosition
(
a
);
return
Math
.
abs
(
b
-
this
.
minH
.
rzsp
)
<
Math
.
abs
(
b
-
this
.
maxH
.
rzsp
)?
this
.
minH
:
this
.
maxH
},
bindEvents
:
function
(){
if
(
!
this
.
options
.
readOnly
&&!
this
.
options
.
disabled
){
var
b
,
c
,
d
;
this
.
options
.
draggableRange
?(
b
=
"rzSliderDrag"
,
c
=
this
.
onDragStart
,
d
=
this
.
onDragMove
):(
b
=
"rzSliderModel"
,
c
=
this
.
onStart
,
d
=
this
.
onMove
),
this
.
minH
.
on
(
"mousedown"
,
a
.
bind
(
this
,
this
.
onStart
,
this
.
minH
,
"rzSliderModel"
)),
this
.
range
&&
this
.
maxH
.
on
(
"mousedown"
,
a
.
bind
(
this
,
this
.
onStart
,
this
.
maxH
,
"rzSliderHigh"
)),
this
.
fullBar
.
on
(
"mousedown"
,
a
.
bind
(
this
,
this
.
onStart
,
null
,
null
)),
this
.
fullBar
.
on
(
"mousedown"
,
a
.
bind
(
this
,
this
.
onMove
,
this
.
fullBar
)),
this
.
selBar
.
on
(
"mousedown"
,
a
.
bind
(
this
,
c
,
null
,
b
)),
this
.
selBar
.
on
(
"mousedown"
,
a
.
bind
(
this
,
d
,
this
.
selBar
)),
this
.
ticks
.
on
(
"mousedown"
,
a
.
bind
(
this
,
this
.
onStart
,
null
,
null
)),
this
.
ticks
.
on
(
"mousedown"
,
a
.
bind
(
this
,
this
.
onMove
,
this
.
ticks
)),
this
.
minH
.
on
(
"touchstart"
,
a
.
bind
(
this
,
this
.
onStart
,
this
.
minH
,
"rzSliderModel"
)),
this
.
range
&&
this
.
maxH
.
on
(
"touchstart"
,
a
.
bind
(
this
,
this
.
onStart
,
this
.
maxH
,
"rzSliderHigh"
)),
this
.
fullBar
.
on
(
"touchstart"
,
a
.
bind
(
this
,
this
.
onStart
,
null
,
null
)),
this
.
fullBar
.
on
(
"touchstart"
,
a
.
bind
(
this
,
this
.
onMove
,
this
.
fullBar
)),
this
.
selBar
.
on
(
"touchstart"
,
a
.
bind
(
this
,
c
,
null
,
b
)),
this
.
selBar
.
on
(
"touchstart"
,
a
.
bind
(
this
,
d
,
this
.
selBar
)),
this
.
ticks
.
on
(
"touchstart"
,
a
.
bind
(
this
,
this
.
onStart
,
null
,
null
)),
this
.
ticks
.
on
(
"touchstart"
,
a
.
bind
(
this
,
this
.
onMove
,
this
.
ticks
))}},
unbindEvents
:
function
(){
this
.
minH
.
off
(),
this
.
maxH
.
off
(),
this
.
fullBar
.
off
(),
this
.
selBar
.
off
(),
this
.
ticks
.
off
()},
onStart
:
function
(
b
,
d
,
e
){
var
f
,
g
,
h
=
this
.
getEventNames
(
e
);
e
.
stopPropagation
(),
e
.
preventDefault
(),
""
===
this
.
tracking
&&
(
this
.
calcViewDimensions
(),
b
?
this
.
tracking
=
d
:(
b
=
this
.
getNearestHandle
(
e
),
this
.
tracking
=
b
===
this
.
minH
?
"rzSliderModel"
:
"rzSliderHigh"
),
b
.
addClass
(
"rz-active"
),
f
=
a
.
bind
(
this
,
this
.
dragging
.
active
?
this
.
onDragMove
:
this
.
onMove
,
b
),
g
=
a
.
bind
(
this
,
this
.
onEnd
,
f
),
c
.
on
(
h
.
moveEvent
,
f
),
c
.
one
(
h
.
endEvent
,
g
),
this
.
callOnStart
())},
onMove
:
function
(
a
,
b
){
var
c
,
d
=
this
.
getEventPosition
(
b
);
if
(
0
>=
d
){
if
(
0
===
a
.
rzsp
)
return
;
c
=
this
.
minValue
,
d
=
0
}
else
if
(
d
>=
this
.
maxPos
){
if
(
a
.
rzsp
===
this
.
maxPos
)
return
;
c
=
this
.
maxValue
,
d
=
this
.
maxPos
}
else
c
=
this
.
offsetToValue
(
d
),
c
=
this
.
roundStep
(
c
),
d
=
this
.
valueToOffset
(
c
);
this
.
positionTrackingHandle
(
c
,
d
)},
onDragStart
:
function
(
a
,
b
,
c
){
var
d
=
this
.
getEventPosition
(
c
);
this
.
dragging
=
{
active
:
!
0
,
value
:
this
.
offsetToValue
(
d
),
difference
:
this
.
scope
.
rzSliderHigh
-
this
.
scope
.
rzSliderModel
,
offset
:
d
,
lowDist
:
d
-
this
.
minH
.
rzsp
,
highDist
:
this
.
maxH
.
rzsp
-
d
},
this
.
minH
.
addClass
(
"rz-active"
),
this
.
maxH
.
addClass
(
"rz-active"
),
this
.
onStart
(
a
,
b
,
c
)},
onDragMove
:
function
(
a
,
b
){
var
c
,
d
,
e
,
f
,
g
=
this
.
getEventPosition
(
b
);
if
(
g
<=
this
.
dragging
.
lowDist
){
if
(
a
.
rzsp
===
this
.
dragging
.
lowDist
)
return
;
e
=
this
.
minValue
,
c
=
0
,
f
=
this
.
minValue
+
this
.
dragging
.
difference
,
d
=
this
.
valueToOffset
(
f
)}
else
if
(
g
>=
this
.
maxPos
-
this
.
dragging
.
highDist
){
if
(
a
.
rzsp
===
this
.
dragging
.
highDist
)
return
;
f
=
this
.
maxValue
,
d
=
this
.
maxPos
,
e
=
this
.
maxValue
-
this
.
dragging
.
difference
,
c
=
this
.
valueToOffset
(
e
)}
else
e
=
this
.
offsetToValue
(
g
-
this
.
dragging
.
lowDist
),
e
=
this
.
roundStep
(
e
),
c
=
this
.
valueToOffset
(
e
),
f
=
e
+
this
.
dragging
.
difference
,
d
=
this
.
valueToOffset
(
f
);
this
.
positionTrackingBar
(
e
,
f
,
c
,
d
)},
positionTrackingBar
:
function
(
a
,
b
,
c
,
d
){
this
.
scope
.
rzSliderModel
=
a
,
this
.
scope
.
rzSliderHigh
=
b
,
this
.
updateHandles
(
"rzSliderModel"
,
c
),
this
.
updateHandles
(
"rzSliderHigh"
,
d
),
this
.
scope
.
$apply
(),
this
.
callOnChange
()},
positionTrackingHandle
:
function
(
a
,
b
){
this
.
range
&&
(
"rzSliderModel"
===
this
.
tracking
&&
a
>=
this
.
scope
.
rzSliderHigh
?(
this
.
scope
[
this
.
tracking
]
=
this
.
scope
.
rzSliderHigh
,
this
.
updateHandles
(
this
.
tracking
,
this
.
maxH
.
rzsp
),
this
.
tracking
=
"rzSliderHigh"
,
this
.
minH
.
removeClass
(
"rz-active"
),
this
.
maxH
.
addClass
(
"rz-active"
),
this
.
scope
.
$apply
(),
this
.
callOnChange
()):
"rzSliderHigh"
===
this
.
tracking
&&
a
<=
this
.
scope
.
rzSliderModel
&&
(
this
.
scope
[
this
.
tracking
]
=
this
.
scope
.
rzSliderModel
,
this
.
updateHandles
(
this
.
tracking
,
this
.
minH
.
rzsp
),
this
.
tracking
=
"rzSliderModel"
,
this
.
maxH
.
removeClass
(
"rz-active"
),
this
.
minH
.
addClass
(
"rz-active"
),
this
.
scope
.
$apply
(),
this
.
callOnChange
())),
this
.
scope
[
this
.
tracking
]
!==
a
&&
(
this
.
scope
[
this
.
tracking
]
=
a
,
this
.
updateHandles
(
this
.
tracking
,
b
),
this
.
scope
.
$apply
(),
this
.
callOnChange
())},
onEnd
:
function
(
a
,
b
){
var
d
=
this
.
getEventNames
(
b
).
moveEvent
;
this
.
minH
.
removeClass
(
"rz-active"
),
this
.
maxH
.
removeClass
(
"rz-active"
),
c
.
off
(
d
,
a
),
this
.
scope
.
$emit
(
"slideEnded"
),
this
.
tracking
=
""
,
this
.
dragging
.
active
=!
1
,
this
.
callOnEnd
()},
getEventNames
:
function
(
a
){
var
b
=
{
moveEvent
:
""
,
endEvent
:
""
};
return
a
.
touches
||
void
0
!==
a
.
originalEvent
&&
a
.
originalEvent
.
touches
?(
b
.
moveEvent
=
"touchmove"
,
b
.
endEvent
=
"touchend"
):(
b
.
moveEvent
=
"mousemove"
,
b
.
endEvent
=
"mouseup"
),
b
}},
h
}]).
directive
(
"rzslider"
,[
"RzSlider"
,
function
(
a
){
return
{
restrict
:
"E"
,
scope
:{
rzSliderModel
:
"=?"
,
rzSliderHigh
:
"=?"
,
rzSliderOptions
:
"=?"
,
rzSliderTplUrl
:
"@"
},
templateUrl
:
function
(
a
,
b
){
return
b
.
rzSliderTplUrl
||
"rzSliderTpl.html"
},
link
:
function
(
b
,
c
){
return
new
a
(
b
,
c
)}}}]);
return
b
.
run
([
"$templateCache"
,
function
(
a
){
a
.
put
(
"rzSliderTpl.html"
,
'<span class=rz-bar-wrapper><span class=rz-bar></span></span> <span class=rz-bar-wrapper><span class="rz-bar rz-selection"></span></span> <span class=rz-pointer></span> <span class=rz-pointer></span> <span class="rz-bubble rz-limit"></span> <span class="rz-bubble rz-limit"></span> <span class=rz-bubble></span> <span class=rz-bubble></span> <span class=rz-bubble></span><ul class=rz-ticks></ul>'
)}]),
b
});
\ No newline at end of file
src/rzslider.js
View file @
3775ce08
...
...
@@ -31,1372 +31,1371 @@
'use strict'
;
var
module
=
angular
.
module
(
'rzModule'
,
[])
.
factory
(
'RzSliderOptions'
,
function
()
{
var
defaultOptions
=
{
floor
:
0
,
ceil
:
null
,
//defaults to rz-slider-model
step
:
1
,
precision
:
0
,
id
:
null
,
translate
:
null
,
stepsArray
:
null
,
draggableRange
:
false
,
showSelectionBar
:
false
,
hideLimitLabels
:
false
,
readOnly
:
false
,
disabled
:
false
,
interval
:
350
,
showTicks
:
false
,
showTicksValues
:
false
,
ticksValuesTooltip
:
null
,
vertical
:
false
,
scale
:
1
,
onStart
:
null
,
onChange
:
null
,
onEnd
:
null
};
var
globalOptions
=
{};
var
factory
=
{};
/**
* `options({})` allows global configuration of all sliders in the
* application.
*
* var app = angular.module( 'App', ['rzModule'], function( RzSliderOptions ) {
.
factory
(
'RzSliderOptions'
,
function
()
{
var
defaultOptions
=
{
floor
:
0
,
ceil
:
null
,
//defaults to rz-slider-model
step
:
1
,
precision
:
0
,
id
:
null
,
translate
:
null
,
stepsArray
:
null
,
draggableRange
:
false
,
showSelectionBar
:
false
,
hideLimitLabels
:
false
,
readOnly
:
false
,
disabled
:
false
,
interval
:
350
,
showTicks
:
false
,
showTicksValues
:
false
,
ticksValuesTooltip
:
null
,
vertical
:
false
,
scale
:
1
,
onStart
:
null
,
onChange
:
null
,
onEnd
:
null
};
var
globalOptions
=
{};
var
factory
=
{};
/**
* `options({})` allows global configuration of all sliders in the
* application.
*
* var app = angular.module( 'App', ['rzModule'], function( RzSliderOptions ) {
* // show ticks for all sliders
* RzSliderOptions.options( { showTicks: true } );
* });
*/
factory
.
options
=
function
(
value
)
{
angular
.
extend
(
globalOptions
,
value
);
*/
factory
.
options
=
function
(
value
)
{
angular
.
extend
(
globalOptions
,
value
);
};
factory
.
getOptions
=
function
(
options
)
{
return
angular
.
extend
({},
defaultOptions
,
globalOptions
,
options
);
};
return
factory
;
})
.
value
(
'rzThrottle'
,
/**
* rzThrottle
*
* Taken from underscore project
*
* @param {Function} func
* @param {number} wait
* @param {ThrottleOptions} options
* @returns {Function}
*/
function
throttle
(
func
,
wait
,
options
)
{
'use strict'
;
var
getTime
=
(
Date
.
now
||
function
()
{
return
new
Date
().
getTime
();
});
var
context
,
args
,
result
;
var
timeout
=
null
;
var
previous
=
0
;
options
=
options
||
{};
var
later
=
function
()
{
previous
=
options
.
leading
===
false
?
0
:
getTime
();
timeout
=
null
;
result
=
func
.
apply
(
context
,
args
);
context
=
args
=
null
;
};
factory
.
getOptions
=
function
(
options
)
{
return
angular
.
extend
({},
defaultOptions
,
globalOptions
,
options
);
return
function
()
{
var
now
=
getTime
();
if
(
!
previous
&&
options
.
leading
===
false
)
{
previous
=
now
;
}
var
remaining
=
wait
-
(
now
-
previous
);
context
=
this
;
args
=
arguments
;
if
(
remaining
<=
0
)
{
clearTimeout
(
timeout
);
timeout
=
null
;
previous
=
now
;
result
=
func
.
apply
(
context
,
args
);
context
=
args
=
null
;
}
else
if
(
!
timeout
&&
options
.
trailing
!==
false
)
{
timeout
=
setTimeout
(
later
,
remaining
);
}
return
result
;
};
return
factory
;
})
.
value
(
'rzThrottle'
,
.
factory
(
'RzSlider'
,
function
(
$timeout
,
$document
,
$window
,
$compile
,
RzSliderOptions
,
rzThrottle
)
{
'use strict'
;
/**
* Slider
*
* @param {ngScope} scope The AngularJS scope
* @param {Element} sliderElem The slider directive element wrapped in jqLite
* @constructor
*/
var
Slider
=
function
(
scope
,
sliderElem
)
{
/**
*
rzThrottl
e
*
The slider's scop
e
*
* Taken from underscore project
* @type {ngScope}
*/
this
.
scope
=
scope
;
/**
* Slider element wrapped in jqLite
*
* @param {Function} func
* @param {number} wait
* @param {ThrottleOptions} options
* @returns {Function}
* @type {jqLite}
*/
function
throttle
(
func
,
wait
,
options
)
{
'use strict'
;
var
getTime
=
(
Date
.
now
||
function
()
{
return
new
Date
().
getTime
();
});
var
context
,
args
,
result
;
var
timeout
=
null
;
var
previous
=
0
;
options
=
options
||
{};
var
later
=
function
()
{
previous
=
options
.
leading
===
false
?
0
:
getTime
();
timeout
=
null
;
result
=
func
.
apply
(
context
,
args
);
context
=
args
=
null
;
};
return
function
()
{
var
now
=
getTime
();
if
(
!
previous
&&
options
.
leading
===
false
)
{
previous
=
now
;
}
var
remaining
=
wait
-
(
now
-
previous
);
context
=
this
;
args
=
arguments
;
if
(
remaining
<=
0
)
{
clearTimeout
(
timeout
);
timeout
=
null
;
previous
=
now
;
result
=
func
.
apply
(
context
,
args
);
context
=
args
=
null
;
}
else
if
(
!
timeout
&&
options
.
trailing
!==
false
)
{
timeout
=
setTimeout
(
later
,
remaining
);
}
return
result
;
};
})
this
.
sliderElem
=
sliderElem
;
.
factory
(
'RzSlider'
,
function
(
$timeout
,
$document
,
$window
,
$compile
,
RzSliderOptions
,
rzThrottle
)
{
'use strict'
;
/**
* Slider type
*
* @type {boolean} Set to true for range slider
*/
this
.
range
=
this
.
scope
.
rzSliderModel
!==
undefined
&&
this
.
scope
.
rzSliderHigh
!==
undefined
;
/**
*
Slide
r
*
Values recorded when first dragging the ba
r
*
* @param {ngScope} scope The AngularJS scope
* @param {Element} sliderElem The slider directive element wrapped in jqLite
* @constructor
* @type {Object}
*/
var
Slider
=
function
(
scope
,
sliderElem
)
{
/**
* The slider's scope
*
* @type {ngScope}
*/
this
.
scope
=
scope
;
this
.
dragging
=
{
active
:
false
,
value
:
0
,
difference
:
0
,
offset
:
0
,
lowDist
:
0
,
highDist
:
0
};
/**
* Slider element wrapped in jqLite
*
* @type {jqLite}
*/
this
.
sliderElem
=
sliderElem
;
/**
* property that handle position (defaults to left for horizontal)
* @type {string}
*/
this
.
positionProperty
=
'left'
;
/**
* Slider type
*
* @type {boolean} Set to true for range slider
*/
this
.
range
=
this
.
scope
.
rzSliderModel
!==
undefined
&&
this
.
scope
.
rzSliderHigh
!==
undefined
;
/**
* property that handle dimension (defaults to width for horizontal)
* @type {string}
*/
this
.
dimensionProperty
=
'width'
;
/**
* Values recorded when first dragging the bar
*
* @type {Object}
*/
this
.
dragging
=
{
active
:
false
,
value
:
0
,
difference
:
0
,
offset
:
0
,
lowDist
:
0
,
highDist
:
0
};
/**
* Half of the width or height of the slider handles
*
* @type {number}
*/
this
.
handleHalfDim
=
0
;
/**
* property that handle position (defaults to left for horizontal)
* @type {string}
*/
this
.
positionProperty
=
'left'
;
/**
* Maximum position the slider handle can have
*
* @type {number}
*/
this
.
maxPos
=
0
;
/**
* property that handle dimension (defaults to width for horizontal)
* @type {string}
*/
this
.
dimensionProperty
=
'width'
;
/**
* Precision
*
* @type {number}
*/
this
.
precision
=
0
;
/**
* Half of the width or height of the slider handles
*
* @type {number}
*/
this
.
handleHalfDim
=
0
;
/**
* Step
*
* @type {number}
*/
this
.
step
=
0
;
/**
* Maximum position the slider handle can have
*
* @type {number
}
*/
this
.
maxPos
=
0
;
/**
* The name of the handle we are currently tracking
*
* @type {string
}
*/
this
.
tracking
=
''
;
/**
* Precision
*
* @type {number}
*/
this
.
precision
=
0
;
/**
* Minimum value (floor) of the model
*
* @type {number}
*/
this
.
minValue
=
0
;
/**
* Step
*
* @type {number}
*/
this
.
step
=
0
;
/**
* Maximum value (ceiling) of the model
*
* @type {number}
*/
this
.
maxValue
=
0
;
/**
* The name of the handle we are currently tracking
*
* @type {string}
*/
this
.
tracking
=
''
;
/**
* Minimum value (floor) of the model
*
* @type {number}
*/
this
.
minValu
e
=
0
;
/**
* The delta between min and max value
*
* @type {number}
*/
this
.
valueRang
e
=
0
;
/**
* Maximum value (ceiling) of the model
*
* @type {number}
*/
this
.
maxValue
=
0
;
/**
* Set to true if init method already executed
*
* @type {boolean}
*/
this
.
initHasRun
=
false
;
// Slider DOM elements wrapped in jqLite
this
.
fullBar
=
null
;
// The whole slider bar
this
.
selBar
=
null
;
// Highlight between two handles
this
.
minH
=
null
;
// Left slider handle
this
.
maxH
=
null
;
// Right slider handle
this
.
flrLab
=
null
;
// Floor label
this
.
ceilLab
=
null
;
// Ceiling label
this
.
minLab
=
null
;
// Label above the low value
this
.
maxLab
=
null
;
// Label above the high value
this
.
cmbLab
=
null
;
// Combined label
this
.
ticks
=
null
;
// The ticks
// Initialize slider
this
.
init
();
};
// Add instance methods
Slider
.
prototype
=
{
/**
* Initialize slider
*
* @returns {undefined}
*/
init
:
function
()
{
var
thrLow
,
thrHigh
,
calcDimFn
=
angular
.
bind
(
this
,
this
.
calcViewDimensions
),
self
=
this
;
this
.
applyOptions
();
this
.
initElemHandles
();
this
.
manageElementsStyle
();
this
.
addAccessibility
();
this
.
manageEventsBindings
();
this
.
setDisabledState
();
this
.
calcViewDimensions
();
this
.
setMinAndMax
();
$timeout
(
function
()
{
self
.
updateCeilLab
();
self
.
updateFloorLab
();
self
.
initHandles
();
self
.
bindEvents
();
});
/**
* The delta between min and max value
*
* @type {number}
*/
this
.
valueRange
=
0
;
// Recalculate slider view dimensions
this
.
scope
.
$on
(
'reCalcViewDimensions'
,
calcDimFn
);
/**
* Set to true if init method already executed
*
* @type {boolean}
*/
this
.
initHasRun
=
false
;
// Slider DOM elements wrapped in jqLite
this
.
fullBar
=
null
;
// The whole slider bar
this
.
selBar
=
null
;
// Highlight between two handles
this
.
minH
=
null
;
// Left slider handle
this
.
maxH
=
null
;
// Right slider handle
this
.
flrLab
=
null
;
// Floor label
this
.
ceilLab
=
null
;
// Ceiling label
this
.
minLab
=
null
;
// Label above the low value
this
.
maxLab
=
null
;
// Label above the high value
this
.
cmbLab
=
null
;
// Combined label
this
.
ticks
=
null
;
// The ticks
// Initialize slider
this
.
init
();
};
// Recalculate stuff if view port dimensions have changed
angular
.
element
(
$window
).
on
(
'resize'
,
calcDimFn
);
// Add instance methods
Slider
.
prototype
=
{
if
(
this
.
options
.
vertical
)
this
.
sliderElem
.
addClass
(
'vertical'
);
/**
* Initialize slider
*
* @returns {undefined}
*/
init
:
function
()
{
var
thrLow
,
thrHigh
,
calcDimFn
=
angular
.
bind
(
this
,
this
.
calcViewDimensions
),
self
=
this
;
this
.
applyOptions
();
this
.
initElemHandles
();
this
.
manageElementsStyle
();
this
.
addAccessibility
();
this
.
manageEventsBindings
();
this
.
setDisabledState
();
this
.
calcViewDimensions
();
this
.
setMinAndMax
();
this
.
initHasRun
=
true
;
$timeout
(
function
()
{
self
.
updateCeilLab
();
self
.
updateFloorLab
();
self
.
initHandles
();
self
.
bindEvents
();
});
// Watch for changes to the model
// Recalculate slider view dimensions
this
.
scope
.
$on
(
'reCalcViewDimensions'
,
calcDimFn
);
thrLow
=
rzThrottle
(
function
()
{
self
.
setMinAndMax
();
self
.
updateLowHandle
(
self
.
valueToOffset
(
self
.
scope
.
rzSliderModel
));
self
.
updateSelectionBar
();
self
.
updateTicksScale
();
// Recalculate stuff if view port dimensions have changed
angular
.
element
(
$window
).
on
(
'resize'
,
calcDimFn
);
if
(
self
.
range
)
{
self
.
updateCmbLabel
();
}
if
(
this
.
options
.
vertical
)
this
.
sliderElem
.
addClass
(
'vertical'
);
},
self
.
options
.
interval
);
thrHigh
=
rzThrottle
(
function
()
{
self
.
setMinAndMax
();
self
.
updateHighHandle
(
self
.
valueToOffset
(
self
.
scope
.
rzSliderHigh
));
self
.
updateSelectionBar
();
self
.
updateTicksScale
();
self
.
updateCmbLabel
();
},
self
.
options
.
interval
);
this
.
scope
.
$on
(
'rzSliderForceRender'
,
function
()
{
self
.
resetLabelsValue
();
thrLow
();
if
(
self
.
range
)
{
thrHigh
();
}
self
.
resetSlider
();
});
this
.
initHasRun
=
true
;
// Watchers
this
.
scope
.
$watch
(
'rzSliderModel'
,
function
(
newValue
,
oldValue
)
{
if
(
newValue
===
oldValue
)
return
;
thrLow
();
});
// Watch for changes to the model
this
.
scope
.
$watch
(
'rzSliderHigh'
,
function
(
newValue
,
oldValue
)
{
if
(
newValue
===
oldValue
)
return
;
if
(
newValue
!=
null
)
thrHigh
();
if
(
self
.
range
&&
newValue
==
null
||
!
self
.
range
&&
newValue
!=
null
)
{
self
.
applyOptions
();
self
.
resetSlider
();
}
});
thrLow
=
rzThrottle
(
function
()
{
self
.
setMinAndMax
();
self
.
updateLowHandle
(
self
.
valueToOffset
(
self
.
scope
.
rzSliderModel
));
self
.
updateSelectionBar
();
self
.
updateTicksScale
();
this
.
scope
.
$watch
(
'rzSliderOptions'
,
function
(
newValue
,
oldValue
)
{
if
(
newValue
===
oldValue
)
return
;
self
.
applyOptions
();
self
.
resetSlider
();
},
true
);
if
(
self
.
range
)
{
self
.
updateCmbLabel
();
}
this
.
scope
.
$on
(
'$destroy'
,
function
()
{
self
.
unbindEvents
();
angular
.
element
(
$window
).
off
(
'resize'
,
calcDimFn
);
});
},
},
self
.
options
.
interval
);
/**
* Read the user options and apply them to the slider model
*/
applyOptions
:
function
()
{
this
.
options
=
RzSliderOptions
.
getOptions
(
this
.
scope
.
rzSliderOptions
);
thrHigh
=
rzThrottle
(
function
()
{
self
.
setMinAndMax
();
self
.
updateHighHandle
(
self
.
valueToOffset
(
self
.
scope
.
rzSliderHigh
));
self
.
updateSelectionBar
();
self
.
updateTicksScale
();
self
.
updateCmbLabel
();
},
self
.
options
.
interval
);
if
(
this
.
options
.
step
<=
0
)
this
.
options
.
step
=
1
;
this
.
range
=
this
.
scope
.
rzSliderModel
!==
undefined
&&
this
.
scope
.
rzSliderHigh
!==
undefined
;
this
.
options
.
draggableRange
=
this
.
range
&&
this
.
options
.
draggableRange
;
this
.
options
.
showTicks
=
this
.
options
.
showTicks
||
this
.
options
.
showTicksValues
;
if
(
this
.
options
.
stepsArray
)
{
this
.
options
.
floor
=
0
;
this
.
options
.
ceil
=
this
.
options
.
stepsArray
.
length
-
1
;
this
.
options
.
step
=
1
;
this
.
customTrFn
=
function
(
value
)
{
return
this
.
options
.
stepsArray
[
value
];
};
}
else
if
(
this
.
options
.
translate
)
this
.
customTrFn
=
this
.
options
.
translate
;
else
this
.
customTrFn
=
function
(
value
)
{
return
String
(
value
);
};
this
.
scope
.
$on
(
'rzSliderForceRender'
,
function
()
{
self
.
resetLabelsValue
();
thrLow
();
if
(
self
.
range
)
{
thrHigh
();
}
self
.
resetSlider
();
});
if
(
this
.
options
.
vertical
)
{
this
.
positionProperty
=
'bottom'
;
this
.
dimensionProperty
=
'height'
;
}
},
// Watchers
this
.
scope
.
$watch
(
'rzSliderModel'
,
function
(
newValue
,
oldValue
)
{
if
(
newValue
===
oldValue
)
return
;
thrLow
();
});
/**
* Resets slider
*
* @returns {undefined}
*/
resetSlider
:
function
()
{
this
.
manageElementsStyle
();
this
.
setMinAndMax
();
this
.
updateCeilLab
();
this
.
updateFloorLab
();
this
.
unbindEvents
();
this
.
manageEventsBindings
();
this
.
setDisabledState
();
this
.
calcViewDimensions
();
},
this
.
scope
.
$watch
(
'rzSliderHigh'
,
function
(
newValue
,
oldValue
)
{
if
(
newValue
===
oldValue
)
return
;
if
(
newValue
!=
null
)
thrHigh
();
if
(
self
.
range
&&
newValue
==
null
||
!
self
.
range
&&
newValue
!=
null
)
{
self
.
applyOptions
();
self
.
resetSlider
();
}
});
/**
* Set the slider children to variables for easy access
*
* Run only once during initialization
*
* @returns {undefined}
*/
initElemHandles
:
function
()
{
// Assign all slider elements to object properties for easy access
angular
.
forEach
(
this
.
sliderElem
.
children
(),
function
(
elem
,
index
)
{
var
jElem
=
angular
.
element
(
elem
);
switch
(
index
)
{
case
0
:
this
.
fullBar
=
jElem
;
break
;
case
1
:
this
.
selBar
=
jElem
;
break
;
case
2
:
this
.
minH
=
jElem
;
break
;
case
3
:
this
.
maxH
=
jElem
;
break
;
case
4
:
this
.
flrLab
=
jElem
;
break
;
case
5
:
this
.
ceilLab
=
jElem
;
break
;
case
6
:
this
.
minLab
=
jElem
;
break
;
case
7
:
this
.
maxLab
=
jElem
;
break
;
case
8
:
this
.
cmbLab
=
jElem
;
break
;
case
9
:
this
.
ticks
=
jElem
;
break
;
}
this
.
scope
.
$watch
(
'rzSliderOptions'
,
function
(
newValue
,
oldValue
)
{
if
(
newValue
===
oldValue
)
return
;
self
.
applyOptions
();
self
.
resetSlider
();
},
true
);
},
this
);
this
.
scope
.
$on
(
'$destroy'
,
function
()
{
self
.
unbindEvents
();
angular
.
element
(
$window
).
off
(
'resize'
,
calcDimFn
);
});
},
// Initialize offset cache properties
this
.
selBar
.
rzsp
=
0
;
this
.
minH
.
rzsp
=
0
;
this
.
maxH
.
rzsp
=
0
;
this
.
flrLab
.
rzsp
=
0
;
this
.
ceilLab
.
rzsp
=
0
;
this
.
minLab
.
rzsp
=
0
;
this
.
maxLab
.
rzsp
=
0
;
this
.
cmbLab
.
rzsp
=
0
;
},
/**
* Read the user options and apply them to the slider model
*/
applyOptions
:
function
()
{
this
.
options
=
RzSliderOptions
.
getOptions
(
this
.
scope
.
rzSliderOptions
);
if
(
this
.
options
.
step
<=
0
)
this
.
options
.
step
=
1
;
this
.
range
=
this
.
scope
.
rzSliderModel
!==
undefined
&&
this
.
scope
.
rzSliderHigh
!==
undefined
;
this
.
options
.
draggableRange
=
this
.
range
&&
this
.
options
.
draggableRange
;
this
.
options
.
showTicks
=
this
.
options
.
showTicks
||
this
.
options
.
showTicksValues
;
if
(
this
.
options
.
stepsArray
)
{
this
.
options
.
floor
=
0
;
this
.
options
.
ceil
=
this
.
options
.
stepsArray
.
length
-
1
;
this
.
options
.
step
=
1
;
this
.
customTrFn
=
function
(
value
)
{
return
this
.
options
.
stepsArray
[
value
];
};
}
else
if
(
this
.
options
.
translate
)
this
.
customTrFn
=
this
.
options
.
translate
;
else
this
.
customTrFn
=
function
(
value
)
{
return
String
(
value
);
};
if
(
this
.
options
.
vertical
)
{
this
.
positionProperty
=
'bottom'
;
this
.
dimensionProperty
=
'height'
;
}
},
/** Update each elements style based on options
*
*/
manageElementsStyle
:
function
()
{
if
(
!
this
.
range
)
this
.
maxH
.
css
(
'display'
,
'none'
);
else
this
.
maxH
.
css
(
'display'
,
null
);
this
.
alwaysHide
(
this
.
flrLab
,
this
.
options
.
showTicksValues
||
this
.
options
.
hideLimitLabels
);
this
.
alwaysHide
(
this
.
ceilLab
,
this
.
options
.
showTicksValues
||
this
.
options
.
hideLimitLabels
);
this
.
alwaysHide
(
this
.
minLab
,
this
.
options
.
showTicksValues
);
this
.
alwaysHide
(
this
.
maxLab
,
this
.
options
.
showTicksValues
||
!
this
.
range
);
this
.
alwaysHide
(
this
.
cmbLab
,
this
.
options
.
showTicksValues
||
!
this
.
range
);
this
.
alwaysHide
(
this
.
selBar
,
!
this
.
range
&&
!
this
.
options
.
showSelectionBar
);
if
(
!
this
.
options
.
showTicks
)
this
.
ticks
.
html
(
''
);
if
(
this
.
options
.
draggableRange
)
this
.
selBar
.
addClass
(
'rz-draggable'
);
else
this
.
selBar
.
removeClass
(
'rz-draggable'
);
},
alwaysHide
:
function
(
el
,
hide
)
{
el
.
rzAlwaysHide
=
hide
;
if
(
hide
)
this
.
hideEl
(
el
);
else
this
.
showEl
(
el
)
},
/**
* Resets slider
*
* @returns {undefined}
*/
resetSlider
:
function
()
{
this
.
manageElementsStyle
();
this
.
setMinAndMax
();
this
.
updateCeilLab
();
this
.
updateFloorLab
();
/**
* Manage the events bindings based on readOnly and disabled options
*
* @returns {undefined}
*/
manageEventsBindings
:
function
()
{
if
(
this
.
options
.
disabled
||
this
.
options
.
readOnly
)
this
.
unbindEvents
();
this
.
manageEventsBindings
();
this
.
setDisabledState
();
this
.
calcViewDimensions
();
},
/**
* Set the slider children to variables for easy access
*
* Run only once during initialization
*
* @returns {undefined}
*/
initElemHandles
:
function
()
{
// Assign all slider elements to object properties for easy access
angular
.
forEach
(
this
.
sliderElem
.
children
(),
function
(
elem
,
index
)
{
var
jElem
=
angular
.
element
(
elem
);
switch
(
index
)
{
case
0
:
this
.
fullBar
=
jElem
;
break
;
case
1
:
this
.
selBar
=
jElem
;
break
;
case
2
:
this
.
minH
=
jElem
;
break
;
case
3
:
this
.
maxH
=
jElem
;
break
;
case
4
:
this
.
flrLab
=
jElem
;
break
;
case
5
:
this
.
ceilLab
=
jElem
;
break
;
case
6
:
this
.
minLab
=
jElem
;
break
;
case
7
:
this
.
maxLab
=
jElem
;
break
;
case
8
:
this
.
cmbLab
=
jElem
;
break
;
case
9
:
this
.
ticks
=
jElem
;
break
;
}
else
if
(
!
this
.
options
.
disabled
||
!
this
.
options
.
readOnly
)
this
.
bindEvents
();
},
},
this
);
// Initialize offset cache properties
this
.
selBar
.
rzsp
=
0
;
this
.
minH
.
rzsp
=
0
;
this
.
maxH
.
rzsp
=
0
;
this
.
flrLab
.
rzsp
=
0
;
this
.
ceilLab
.
rzsp
=
0
;
this
.
minLab
.
rzsp
=
0
;
this
.
maxLab
.
rzsp
=
0
;
this
.
cmbLab
.
rzsp
=
0
;
},
/** Update each elements style based on options
*
*/
manageElementsStyle
:
function
()
{
if
(
!
this
.
range
)
this
.
maxH
.
css
(
'display'
,
'none'
);
else
this
.
maxH
.
css
(
'display'
,
null
);
this
.
alwaysHide
(
this
.
flrLab
,
this
.
options
.
showTicksValues
||
this
.
options
.
hideLimitLabels
);
this
.
alwaysHide
(
this
.
ceilLab
,
this
.
options
.
showTicksValues
||
this
.
options
.
hideLimitLabels
);
this
.
alwaysHide
(
this
.
minLab
,
this
.
options
.
showTicksValues
);
this
.
alwaysHide
(
this
.
maxLab
,
this
.
options
.
showTicksValues
||
!
this
.
range
);
this
.
alwaysHide
(
this
.
cmbLab
,
this
.
options
.
showTicksValues
||
!
this
.
range
);
this
.
alwaysHide
(
this
.
selBar
,
!
this
.
range
&&
!
this
.
options
.
showSelectionBar
);
if
(
!
this
.
options
.
showTicks
)
this
.
ticks
.
html
(
''
);
if
(
this
.
options
.
draggableRange
)
this
.
selBar
.
addClass
(
'rz-draggable'
);
else
this
.
selBar
.
removeClass
(
'rz-draggable'
);
},
alwaysHide
:
function
(
el
,
hide
)
{
el
.
rzAlwaysHide
=
hide
;
if
(
hide
)
this
.
hideEl
(
el
);
else
this
.
showEl
(
el
)
},
/**
* Manage the events bindings based on readOnly and disabled options
*
* @returns {undefined}
*/
manageEventsBindings
:
function
()
{
if
(
this
.
options
.
disabled
||
this
.
options
.
readOnly
)
this
.
unbindEvents
();
else
if
(
!
this
.
options
.
disabled
||
!
this
.
options
.
readOnly
)
this
.
bindEvents
();
},
/**
* Set the disabled state based on rzSliderDisabled
*
* @returns {undefined}
*/
setDisabledState
:
function
()
{
if
(
this
.
options
.
disabled
)
{
this
.
sliderElem
.
attr
(
'disabled'
,
'disabled'
);
}
else
{
this
.
sliderElem
.
attr
(
'disabled'
,
null
);
}
},
/**
* Set the disabled state based on rzSliderDisabled
*
* @returns {undefined}
*/
setDisabledState
:
function
()
{
if
(
this
.
options
.
disabled
)
{
this
.
sliderElem
.
attr
(
'disabled'
,
'disabled'
);
}
else
{
this
.
sliderElem
.
attr
(
'disabled'
,
null
);
}
},
/**
* Reset label values
*
* @return {undefined}
*/
resetLabelsValue
:
function
()
{
this
.
minLab
.
rzsv
=
undefined
;
this
.
maxLab
.
rzsv
=
undefined
;
},
/**
* Initialize slider handles positions and labels
*
* Run only once during initialization and every time view port changes size
*
* @returns {undefined}
*/
initHandles
:
function
()
{
this
.
updateLowHandle
(
this
.
valueToOffset
(
this
.
scope
.
rzSliderModel
));
/*
the order here is important since the selection bar should be
updated after the high handle but before the combined label
*/
if
(
this
.
range
)
this
.
updateHighHandle
(
this
.
valueToOffset
(
this
.
scope
.
rzSliderHigh
));
this
.
updateSelectionBar
();
if
(
this
.
range
)
this
.
updateCmbLabel
();
/**
* Reset label values
*
* @return {undefined}
*/
resetLabelsValue
:
function
()
{
this
.
minLab
.
rzsv
=
undefined
;
this
.
maxLab
.
rzsv
=
undefined
;
},
this
.
updateTicksScale
();
},
/**
* Translate value to human readable format
*
* @param {number|string} value
* @param {jqLite} label
* @param {boolean} [useCustomTr]
* @returns {undefined}
/**
* Initialize slider handles positions and labels
*
* Run only once during initialization and every time view port changes size
*
* @returns {undefined}
*/
initHandles
:
function
()
{
this
.
updateLowHandle
(
this
.
valueToOffset
(
this
.
scope
.
rzSliderModel
));
/*
the order here is important since the selection bar should be
updated after the high handle but before the combined label
*/
translateFn
:
function
(
value
,
label
,
useCustomTr
)
{
useCustomTr
=
useCustomTr
===
undefined
?
true
:
useCustomTr
;
if
(
this
.
range
)
this
.
updateHighHandle
(
this
.
valueToOffset
(
this
.
scope
.
rzSliderHigh
));
this
.
updateSelectionBar
();
if
(
this
.
range
)
this
.
updateCmbLabel
();
var
valStr
=
String
((
useCustomTr
?
this
.
customTrFn
(
value
,
this
.
options
.
id
)
:
value
)),
getDimension
=
false
;
this
.
updateTicksScale
();
},
if
(
label
.
rzsv
===
undefined
||
label
.
rzsv
.
length
!==
valStr
.
length
||
(
label
.
rzsv
.
length
>
0
&&
label
.
rzsd
===
0
))
{
getDimension
=
true
;
label
.
rzsv
=
valStr
;
}
/**
* Translate value to human readable format
*
* @param {number|string} value
* @param {jqLite} label
* @param {boolean} [useCustomTr]
* @returns {undefined}
*/
translateFn
:
function
(
value
,
label
,
useCustomTr
)
{
useCustomTr
=
useCustomTr
===
undefined
?
true
:
useCustomTr
;
label
.
text
(
valStr
);
var
valStr
=
String
((
useCustomTr
?
this
.
customTrFn
(
value
,
this
.
options
.
id
)
:
value
)),
getDimension
=
false
;
// Update width only when length of the label have changed
if
(
getDimension
)
{
this
.
getDimension
(
label
);
}
},
if
(
label
.
rzsv
===
undefined
||
label
.
rzsv
.
length
!==
valStr
.
length
||
(
label
.
rzsv
.
length
>
0
&&
label
.
rzsd
===
0
))
{
getDimension
=
true
;
label
.
rzsv
=
valStr
;
}
/**
* Set maximum and minimum values for the slider and ensure the model and high
* value match these limits
* @returns {undefined}
*/
setMinAndMax
:
function
()
{
label
.
text
(
valStr
);
this
.
step
=
+
this
.
options
.
step
;
this
.
precision
=
+
this
.
options
.
precision
;
// Update width only when length of the label have changed
if
(
getDimension
)
{
this
.
getDimension
(
label
);
}
},
this
.
scope
.
rzSliderModel
=
this
.
roundStep
(
this
.
scope
.
rzSliderModel
);
if
(
this
.
range
)
this
.
scope
.
rzSliderHigh
=
this
.
roundStep
(
this
.
scope
.
rzSliderHigh
);
/**
* Set maximum and minimum values for the slider and ensure the model and high
* value match these limits
* @returns {undefined}
*/
setMinAndMax
:
function
()
{
this
.
minValue
=
this
.
roundStep
(
+
this
.
options
.
floor
);
this
.
step
=
+
this
.
options
.
step
;
this
.
precision
=
+
this
.
options
.
precision
;
if
(
this
.
options
.
ceil
!=
null
)
this
.
maxValue
=
this
.
roundStep
(
+
this
.
options
.
ceil
);
else
this
.
maxValue
=
this
.
options
.
ceil
=
this
.
range
?
this
.
scope
.
rzSliderHigh
:
this
.
scope
.
rzSliderModel
;
this
.
scope
.
rzSliderModel
=
this
.
roundStep
(
this
.
scope
.
rzSliderModel
);
if
(
this
.
range
)
this
.
scope
.
rzSliderHigh
=
this
.
roundStep
(
this
.
scope
.
rzSliderHigh
);
this
.
valueRange
=
this
.
maxValue
-
this
.
minValue
;
},
this
.
minValue
=
this
.
roundStep
(
+
this
.
options
.
floor
);
/**
* Adds accessibility atributes
*
* Run only once during initialization
*
* @returns {undefined}
*/
addAccessibility
:
function
()
{
this
.
sliderElem
.
attr
(
"role"
,
"slider"
);
},
/**
* Calculate dimensions that are dependent on view port size
*
* Run once during initialization and every time view port changes size.
*
* @returns {undefined}
*/
calcViewDimensions
:
function
()
{
var
handleWidth
=
this
.
getDimension
(
this
.
minH
);
if
(
this
.
options
.
ceil
!=
null
)
this
.
maxValue
=
this
.
roundStep
(
+
this
.
options
.
ceil
);
else
this
.
maxValue
=
this
.
options
.
ceil
=
this
.
range
?
this
.
scope
.
rzSliderHigh
:
this
.
scope
.
rzSliderModel
;
this
.
handleHalfDim
=
handleWidth
/
2
;
this
.
barDimension
=
this
.
getDimension
(
this
.
fullBar
);
this
.
valueRange
=
this
.
maxValue
-
this
.
minValue
;
},
this
.
maxPos
=
this
.
barDimension
-
handleWidth
;
/**
* Adds accessibility atributes
*
* Run only once during initialization
*
* @returns {undefined}
*/
addAccessibility
:
function
()
{
this
.
sliderElem
.
attr
(
"role"
,
"slider"
);
},
this
.
getDimension
(
this
.
sliderElem
);
this
.
sliderElem
.
rzsp
=
this
.
sliderElem
[
0
].
getBoundingClientRect
()[
this
.
positionProperty
];
/**
* Calculate dimensions that are dependent on view port size
*
* Run once during initialization and every time view port changes size.
*
* @returns {undefined}
*/
calcViewDimensions
:
function
()
{
var
handleWidth
=
this
.
getDimension
(
this
.
minH
);
if
(
this
.
initHasRun
)
{
this
.
updateFloorLab
();
this
.
updateCeilLab
();
this
.
initHandles
();
}
},
this
.
handleHalfDim
=
handleWidth
/
2
;
this
.
barDimension
=
this
.
getDimension
(
this
.
fullBar
);
/**
* Update the ticks position
*
* @returns {undefined}
*/
updateTicksScale
:
function
()
{
if
(
!
this
.
options
.
showTicks
)
return
;
if
(
!
this
.
step
)
return
;
//if step is 0, the following loop will be endless.
var
positions
=
''
,
ticksCount
=
Math
.
round
((
this
.
maxValue
-
this
.
minValue
)
/
this
.
step
)
+
1
;
for
(
var
i
=
0
;
i
<
ticksCount
;
i
++
)
{
var
value
=
this
.
roundStep
(
this
.
minValue
+
i
*
this
.
step
);
var
selectedClass
=
this
.
isTickSelected
(
value
)
?
'selected'
:
''
;
positions
+=
'<li class="tick '
+
selectedClass
+
'">'
;
if
(
this
.
options
.
showTicksValues
)
{
var
tooltip
=
''
;
if
(
this
.
options
.
ticksValuesTooltip
)
{
tooltip
=
'uib-tooltip="'
+
this
.
options
.
ticksValuesTooltip
(
value
)
+
'"'
;
if
(
this
.
options
.
vertical
)
tooltip
+=
' tooltip-placement="right"'
}
positions
+=
'<span '
+
tooltip
+
' class="tick-value">'
+
this
.
getDisplayValue
(
value
)
+
'</span>'
;
}
positions
+=
'</li>'
;
}
this
.
ticks
.
html
(
positions
);
if
(
this
.
options
.
ticksValuesTooltip
)
$compile
(
this
.
ticks
.
contents
())(
this
.
scope
);
},
isTickSelected
:
function
(
value
)
{
if
(
!
this
.
range
&&
this
.
options
.
showSelectionBar
&&
value
<=
this
.
scope
.
rzSliderModel
)
return
true
;
if
(
this
.
range
&&
value
>=
this
.
scope
.
rzSliderModel
&&
value
<=
this
.
scope
.
rzSliderHigh
)
return
true
;
return
false
;
},
/**
* Update position of the ceiling label
*
* @returns {undefined}
*/
updateCeilLab
:
function
()
{
this
.
translateFn
(
this
.
maxValue
,
this
.
ceilLab
);
this
.
setPosition
(
this
.
ceilLab
,
this
.
barDimension
-
this
.
ceilLab
.
rzsd
);
this
.
getDimension
(
this
.
ceilLab
);
},
/**
* Update position of the floor label
*
* @returns {undefined}
*/
updateFloorLab
:
function
()
{
this
.
translateFn
(
this
.
minValue
,
this
.
flrLab
);
this
.
getDimension
(
this
.
flrLab
);
},
/**
* Call the onStart callback if defined
*
* @returns {undefined}
*/
callOnStart
:
function
()
{
if
(
this
.
options
.
onStart
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onStart
(
self
.
options
.
id
);
});
}
},
this
.
maxPos
=
this
.
barDimension
-
handleWidth
;
/**
* Call the onChange callback if defined
*
* @returns {undefined}
*/
callOnChange
:
function
()
{
if
(
this
.
options
.
onChange
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onChange
(
self
.
options
.
id
);
});
}
},
this
.
getDimension
(
this
.
sliderElem
);
this
.
sliderElem
.
rzsp
=
this
.
sliderElem
[
0
].
getBoundingClientRect
()[
this
.
positionProperty
];
/**
* Call the onEnd callback if defined
*
* @returns {undefined}
*/
callOnEnd
:
function
()
{
if
(
this
.
options
.
onEnd
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onEnd
(
self
.
options
.
id
);
});
}
},
if
(
this
.
initHasRun
)
{
this
.
updateFloorLab
();
this
.
updateCeilLab
();
this
.
initHandles
();
}
},
/**
* Update slider handles and label positions
*
* @param {string} which
* @param {number} newOffset
*/
updateHandles
:
function
(
which
,
newOffset
)
{
if
(
which
===
'rzSliderModel'
)
{
this
.
updateLowHandle
(
newOffset
);
this
.
updateSelectionBar
();
this
.
updateTicksScale
();
if
(
this
.
range
)
{
this
.
updateCmbLabel
();
/**
* Update the ticks position
*
* @returns {undefined}
*/
updateTicksScale
:
function
()
{
if
(
!
this
.
options
.
showTicks
)
return
;
if
(
!
this
.
step
)
return
;
//if step is 0, the following loop will be endless.
var
positions
=
''
,
ticksCount
=
Math
.
round
((
this
.
maxValue
-
this
.
minValue
)
/
this
.
step
)
+
1
;
for
(
var
i
=
0
;
i
<
ticksCount
;
i
++
)
{
var
value
=
this
.
roundStep
(
this
.
minValue
+
i
*
this
.
step
);
var
selectedClass
=
this
.
isTickSelected
(
value
)
?
'selected'
:
''
;
positions
+=
'<li class="tick '
+
selectedClass
+
'">'
;
if
(
this
.
options
.
showTicksValues
)
{
var
tooltip
=
''
;
if
(
this
.
options
.
ticksValuesTooltip
)
{
tooltip
=
'uib-tooltip="'
+
this
.
options
.
ticksValuesTooltip
(
value
)
+
'"'
;
if
(
this
.
options
.
vertical
)
tooltip
+=
' tooltip-placement="right"'
}
return
;
positions
+=
'<span '
+
tooltip
+
' class="tick-value">'
+
this
.
getDisplayValue
(
value
)
+
'</span>'
;
}
positions
+=
'</li>'
;
}
this
.
ticks
.
html
(
positions
);
if
(
this
.
options
.
ticksValuesTooltip
)
$compile
(
this
.
ticks
.
contents
())(
this
.
scope
);
},
isTickSelected
:
function
(
value
)
{
if
(
!
this
.
range
&&
this
.
options
.
showSelectionBar
&&
value
<=
this
.
scope
.
rzSliderModel
)
return
true
;
if
(
this
.
range
&&
value
>=
this
.
scope
.
rzSliderModel
&&
value
<=
this
.
scope
.
rzSliderHigh
)
return
true
;
return
false
;
},
if
(
which
===
'rzSliderHigh'
)
{
this
.
updateHighHandle
(
newOffset
);
this
.
updateSelectionBar
();
this
.
updateTicksScale
();
/**
* Update position of the ceiling label
*
* @returns {undefined}
*/
updateCeilLab
:
function
()
{
this
.
translateFn
(
this
.
maxValue
,
this
.
ceilLab
);
this
.
setPosition
(
this
.
ceilLab
,
this
.
barDimension
-
this
.
ceilLab
.
rzsd
);
this
.
getDimension
(
this
.
ceilLab
);
},
if
(
this
.
range
)
{
this
.
updateCmbLabel
();
}
return
;
}
/**
* Update position of the floor label
*
* @returns {undefined}
*/
updateFloorLab
:
function
()
{
this
.
translateFn
(
this
.
minValue
,
this
.
flrLab
);
this
.
getDimension
(
this
.
flrLab
);
},
/**
* Call the onStart callback if defined
*
* @returns {undefined}
*/
callOnStart
:
function
()
{
if
(
this
.
options
.
onStart
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onStart
(
self
.
options
.
id
);
});
}
},
/**
* Call the onChange callback if defined
*
* @returns {undefined}
*/
callOnChange
:
function
()
{
if
(
this
.
options
.
onChange
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onChange
(
self
.
options
.
id
);
});
}
},
/**
* Call the onEnd callback if defined
*
* @returns {undefined}
*/
callOnEnd
:
function
()
{
if
(
this
.
options
.
onEnd
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onEnd
(
self
.
options
.
id
);
});
}
},
// Update both
/**
* Update slider handles and label positions
*
* @param {string} which
* @param {number} newOffset
*/
updateHandles
:
function
(
which
,
newOffset
)
{
if
(
which
===
'rzSliderModel'
)
{
this
.
updateLowHandle
(
newOffset
);
this
.
updateHighHandle
(
newOffset
);
this
.
updateSelectionBar
();
this
.
updateTicksScale
();
this
.
updateCmbLabel
();
},
/**
* Update low slider handle position and label
*
* @param {number} newOffset
* @returns {undefined}
*/
updateLowHandle
:
function
(
newOffset
)
{
this
.
setPosition
(
this
.
minH
,
newOffset
);
this
.
translateFn
(
this
.
scope
.
rzSliderModel
,
this
.
minLab
);
var
pos
=
Math
.
min
(
Math
.
max
(
newOffset
-
this
.
minLab
.
rzsd
/
2
+
this
.
handleHalfDim
,
0
),
this
.
barDimension
-
this
.
ceilLab
.
rzsd
);
this
.
setPosition
(
this
.
minLab
,
pos
);
this
.
shFloorCeil
();
},
/**
* Update high slider handle position and label
*
* @param {number} newOffset
* @returns {undefined}
*/
updateHighHandle
:
function
(
newOffset
)
{
this
.
setPosition
(
this
.
maxH
,
newOffset
);
this
.
translateFn
(
this
.
scope
.
rzSliderHigh
,
this
.
maxLab
);
var
pos
=
Math
.
min
((
newOffset
-
this
.
maxLab
.
rzsd
/
2
+
this
.
handleHalfDim
),
(
this
.
barDimension
-
this
.
ceilLab
.
rzsd
));
this
.
setPosition
(
this
.
maxLab
,
pos
);
this
.
shFloorCeil
();
},
/**
* Show / hide floor / ceiling label
*
* @returns {undefined}
*/
shFloorCeil
:
function
()
{
var
flHidden
=
false
,
clHidden
=
false
;
if
(
this
.
range
)
{
this
.
updateCmbLabel
();
}
return
;
}
if
(
this
.
minLab
.
rzsp
<=
this
.
flrLab
.
rzsp
+
this
.
flrLab
.
rzsd
+
5
)
{
flHidden
=
true
;
this
.
hideEl
(
this
.
flrLab
);
}
else
{
flHidden
=
false
;
this
.
showEl
(
this
.
flrLab
);
if
(
which
===
'rzSliderHigh'
)
{
this
.
updateHighHandle
(
newOffset
);
this
.
updateSelectionBar
();
this
.
updateTicksScale
();
if
(
this
.
range
)
{
this
.
updateCmbLabel
();
}
return
;
}
// Update both
this
.
updateLowHandle
(
newOffset
);
this
.
updateHighHandle
(
newOffset
);
this
.
updateSelectionBar
();
this
.
updateTicksScale
();
this
.
updateCmbLabel
();
},
/**
* Update low slider handle position and label
*
* @param {number} newOffset
* @returns {undefined}
*/
updateLowHandle
:
function
(
newOffset
)
{
this
.
setPosition
(
this
.
minH
,
newOffset
);
this
.
translateFn
(
this
.
scope
.
rzSliderModel
,
this
.
minLab
);
var
pos
=
Math
.
min
(
Math
.
max
(
newOffset
-
this
.
minLab
.
rzsd
/
2
+
this
.
handleHalfDim
,
0
),
this
.
barDimension
-
this
.
ceilLab
.
rzsd
);
this
.
setPosition
(
this
.
minLab
,
pos
);
this
.
shFloorCeil
();
},
/**
* Update high slider handle position and label
*
* @param {number} newOffset
* @returns {undefined}
*/
updateHighHandle
:
function
(
newOffset
)
{
this
.
setPosition
(
this
.
maxH
,
newOffset
);
this
.
translateFn
(
this
.
scope
.
rzSliderHigh
,
this
.
maxLab
);
var
pos
=
Math
.
min
((
newOffset
-
this
.
maxLab
.
rzsd
/
2
+
this
.
handleHalfDim
),
(
this
.
barDimension
-
this
.
ceilLab
.
rzsd
));
this
.
setPosition
(
this
.
maxLab
,
pos
);
this
.
shFloorCeil
();
},
if
(
this
.
minLab
.
rzsp
+
this
.
minLab
.
rzsd
>=
this
.
ceilLab
.
rzsp
-
this
.
handleHalfDim
-
10
)
{
clHidden
=
true
;
/**
* Show / hide floor / ceiling label
*
* @returns {undefined}
*/
shFloorCeil
:
function
()
{
var
flHidden
=
false
,
clHidden
=
false
;
if
(
this
.
minLab
.
rzsp
<=
this
.
flrLab
.
rzsp
+
this
.
flrLab
.
rzsd
+
5
)
{
flHidden
=
true
;
this
.
hideEl
(
this
.
flrLab
);
}
else
{
flHidden
=
false
;
this
.
showEl
(
this
.
flrLab
);
}
if
(
this
.
minLab
.
rzsp
+
this
.
minLab
.
rzsd
>=
this
.
ceilLab
.
rzsp
-
this
.
handleHalfDim
-
10
)
{
clHidden
=
true
;
this
.
hideEl
(
this
.
ceilLab
);
}
else
{
clHidden
=
false
;
this
.
showEl
(
this
.
ceilLab
);
}
if
(
this
.
range
)
{
if
(
this
.
maxLab
.
rzsp
+
this
.
maxLab
.
rzsd
>=
this
.
ceilLab
.
rzsp
-
10
)
{
this
.
hideEl
(
this
.
ceilLab
);
}
else
{
clHidden
=
false
;
}
else
if
(
!
clHidden
)
{
this
.
showEl
(
this
.
ceilLab
);
}
if
(
this
.
range
)
{
if
(
this
.
maxLab
.
rzsp
+
this
.
maxLab
.
rzsd
>=
this
.
ceilLab
.
rzsp
-
10
)
{
this
.
hideEl
(
this
.
ceilLab
);
}
else
if
(
!
clHidden
)
{
this
.
showEl
(
this
.
ceilLab
);
}
// Hide or show floor label
if
(
this
.
maxLab
.
rzsp
<=
this
.
flrLab
.
rzsp
+
this
.
flrLab
.
rzsd
+
this
.
handleHalfDim
)
{
this
.
hideEl
(
this
.
flrLab
);
}
else
if
(
!
flHidden
)
{
this
.
showEl
(
this
.
flrLab
);
}
// Hide or show floor label
if
(
this
.
maxLab
.
rzsp
<=
this
.
flrLab
.
rzsp
+
this
.
flrLab
.
rzsd
+
this
.
handleHalfDim
)
{
this
.
hideEl
(
this
.
flrLab
);
}
else
if
(
!
flHidden
)
{
this
.
showEl
(
this
.
flrLab
);
}
},
}
},
/**
* Update slider selection bar, combined label and range label
*
* @returns {undefined}
*/
updateSelectionBar
:
function
()
{
this
.
setDimension
(
this
.
selBar
,
Math
.
abs
(
this
.
maxH
.
rzsp
-
this
.
minH
.
rzsp
)
+
this
.
handleHalfDim
);
this
.
setPosition
(
this
.
selBar
,
this
.
range
?
this
.
minH
.
rzsp
+
this
.
handleHalfDim
:
0
);
},
/**
* Update combined label position and value
*
* @returns {undefined}
*/
updateCmbLabel
:
function
()
{
var
lowTr
,
highTr
;
if
(
this
.
minLab
.
rzsp
+
this
.
minLab
.
rzsd
+
10
>=
this
.
maxLab
.
rzsp
)
{
lowTr
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderModel
);
highTr
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderHigh
);
this
.
translateFn
(
lowTr
+
' - '
+
highTr
,
this
.
cmbLab
,
false
);
var
pos
=
Math
.
min
(
Math
.
max
((
this
.
selBar
.
rzsp
+
this
.
selBar
.
rzsd
/
2
-
this
.
cmbLab
.
rzsd
/
2
),
0
),
(
this
.
barDimension
-
this
.
cmbLab
.
rzsd
));
this
.
setPosition
(
this
.
cmbLab
,
pos
);
this
.
hideEl
(
this
.
minLab
);
this
.
hideEl
(
this
.
maxLab
);
this
.
showEl
(
this
.
cmbLab
);
}
else
{
this
.
showEl
(
this
.
maxLab
);
this
.
showEl
(
this
.
minLab
);
this
.
hideEl
(
this
.
cmbLab
);
}
},
/**
* Update slider selection bar, combined label and range label
*
* @returns {undefined}
*/
updateSelectionBar
:
function
()
{
this
.
setDimension
(
this
.
selBar
,
Math
.
abs
(
this
.
maxH
.
rzsp
-
this
.
minH
.
rzsp
)
+
this
.
handleHalfDim
);
this
.
setPosition
(
this
.
selBar
,
this
.
range
?
this
.
minH
.
rzsp
+
this
.
handleHalfDim
:
0
);
},
/**
* Return the translated value if a translate function is provided else the original value
* @param value
* @returns {*}
*/
getDisplayValue
:
function
(
value
)
{
return
this
.
customTrFn
(
value
,
this
.
options
.
id
);
},
/**
* Round value to step and precision
*
* @param {number} value
* @returns {number}
*/
roundStep
:
function
(
value
)
{
var
step
=
this
.
step
,
remainder
=
+
((
value
-
this
.
minValue
)
%
step
).
toFixed
(
3
),
steppedValue
=
remainder
>
(
step
/
2
)
?
value
+
step
-
remainder
:
value
-
remainder
;
steppedValue
=
steppedValue
.
toFixed
(
this
.
precision
);
return
+
steppedValue
;
},
/**
* Hide element
*
* @param element
* @returns {jqLite} The jqLite wrapped DOM element
*/
hideEl
:
function
(
element
)
{
return
element
.
css
({
opacity
:
0
});
},
/**
* Update combined label position and value
*
* @returns {undefined}
*/
updateCmbLabel
:
function
()
{
var
lowTr
,
highTr
;
if
(
this
.
minLab
.
rzsp
+
this
.
minLab
.
rzsd
+
10
>=
this
.
maxLab
.
rzsp
)
{
lowTr
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderModel
);
highTr
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderHigh
);
this
.
translateFn
(
lowTr
+
' - '
+
highTr
,
this
.
cmbLab
,
false
);
var
pos
=
Math
.
min
(
Math
.
max
((
this
.
selBar
.
rzsp
+
this
.
selBar
.
rzsd
/
2
-
this
.
cmbLab
.
rzsd
/
2
),
0
),
(
this
.
barDimension
-
this
.
cmbLab
.
rzsd
));
this
.
setPosition
(
this
.
cmbLab
,
pos
);
this
.
hideEl
(
this
.
minLab
);
this
.
hideEl
(
this
.
maxLab
);
this
.
showEl
(
this
.
cmbLab
);
}
else
{
this
.
showEl
(
this
.
maxLab
);
this
.
showEl
(
this
.
minLab
);
this
.
hideEl
(
this
.
cmbLab
);
}
},
/**
* Show element
*
* @param element The jqLite wrapped DOM element
* @returns {jqLite} The jqLite
*/
showEl
:
function
(
element
)
{
if
(
!!
element
.
rzAlwaysHide
)
{
return
element
;
}
/**
* Return the translated value if a translate function is provided else the original value
* @param value
* @returns {*}
*/
getDisplayValue
:
function
(
value
)
{
return
this
.
customTrFn
(
value
,
this
.
options
.
id
);
},
return
element
.
css
({
opacity
:
1
});
},
/**
* Set element left/top offset depending on whether slider is horizontal or vertical
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @param {number} pos
* @returns {number}
*/
setPosition
:
function
(
elem
,
pos
)
{
elem
.
rzsp
=
pos
;
var
css
=
{};
css
[
this
.
positionProperty
]
=
pos
+
'px'
;
elem
.
css
(
css
);
return
pos
;
},
/**
* Get element width/height depending on whether slider is horizontal or vertical
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @returns {number}
*/
getDimension
:
function
(
elem
)
{
var
val
=
elem
[
0
].
getBoundingClientRect
();
if
(
this
.
options
.
vertical
)
elem
.
rzsd
=
(
val
.
bottom
-
val
.
top
)
*
this
.
options
.
scale
;
else
elem
.
rzsd
=
(
val
.
right
-
val
.
left
)
*
this
.
options
.
scale
;
return
elem
.
rzsd
;
},
/**
* Set element width/height depending on whether slider is horizontal or vertical
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @param {number} dim
* @returns {number}
*/
setDimension
:
function
(
elem
,
dim
)
{
elem
.
rzsd
=
dim
;
var
css
=
{};
css
[
this
.
dimensionProperty
]
=
dim
+
'px'
;
elem
.
css
(
css
);
return
dim
;
},
/**
* Translate value to pixel offset
*
* @param {number} val
* @returns {number}
*/
valueToOffset
:
function
(
val
)
{
return
(
this
.
sanitizeOffsetValue
(
val
)
-
this
.
minValue
)
*
this
.
maxPos
/
this
.
valueRange
||
0
;
},
/**
* Ensure that the position rendered is within the slider bounds, even if the value is not
*
* @param {number} val
* @returns {number}
*/
sanitizeOffsetValue
:
function
(
val
)
{
return
Math
.
min
(
Math
.
max
(
val
,
this
.
minValue
),
this
.
maxValue
);
},
/**
* Translate offset to model value
*
* @param {number} offset
* @returns {number}
*/
offsetToValue
:
function
(
offset
)
{
return
(
offset
/
this
.
maxPos
)
*
this
.
valueRange
+
this
.
minValue
;
},
/**
* Round value to step and precision
*
* @param {number} value
* @returns {number}
*/
roundStep
:
function
(
value
)
{
var
step
=
this
.
step
,
remainder
=
+
((
value
-
this
.
minValue
)
%
step
).
toFixed
(
3
),
steppedValue
=
remainder
>
(
step
/
2
)
?
value
+
step
-
remainder
:
value
-
remainder
;
// Events
steppedValue
=
steppedValue
.
toFixed
(
this
.
precision
);
return
+
steppedValue
;
},
/**
* Get the X-coordinate or Y-coordinate of an event
*
* @param {Object} event The event
* @returns {number}
*/
getEventXY
:
function
(
event
)
{
/* http://stackoverflow.com/a/12336075/282882 */
//noinspection JSLint
var
clientXY
=
this
.
options
.
vertical
?
'clientY'
:
'clientX'
;
if
(
clientXY
in
event
)
{
return
event
[
clientXY
];
}
/**
* Hide element
*
* @param element
* @returns {jqLite} The jqLite wrapped DOM element
*/
hideEl
:
function
(
element
)
{
return
element
.
css
({
opacity
:
0
});
},
return
event
.
originalEvent
===
undefined
?
event
.
touches
[
0
][
clientXY
]
:
event
.
originalEvent
.
touches
[
0
][
clientXY
];
},
/**
* Show element
*
* @param element The jqLite wrapped DOM element
* @returns {jqLite} The jqLite
*/
showEl
:
function
(
element
)
{
if
(
!!
element
.
rzAlwaysHide
)
{
return
element
;
}
/**
* Compute the event position depending on whether the slider is horizontal or vertical
* @param event
* @returns {number}
*/
getEventPosition
:
function
(
event
)
{
var
sliderPos
=
this
.
sliderElem
.
rzsp
,
eventPos
=
0
;
if
(
this
.
options
.
vertical
)
eventPos
=
-
this
.
getEventXY
(
event
)
+
sliderPos
;
else
eventPos
=
this
.
getEventXY
(
event
)
-
sliderPos
;
return
(
eventPos
-
this
.
handleHalfDim
)
*
this
.
options
.
scale
;
},
/**
* Get the handle closest to an event.
*
* @param event {Event} The event
* @returns {jqLite} The handle closest to the event.
*/
getNearestHandle
:
function
(
event
)
{
if
(
!
this
.
range
)
{
return
this
.
minH
;
}
var
offset
=
this
.
getEventPosition
(
event
);
return
Math
.
abs
(
offset
-
this
.
minH
.
rzsp
)
<
Math
.
abs
(
offset
-
this
.
maxH
.
rzsp
)
?
this
.
minH
:
this
.
maxH
;
},
/**
* Bind mouse and touch events to slider handles
*
* @returns {undefined}
*/
bindEvents
:
function
()
{
if
(
this
.
options
.
readOnly
||
this
.
options
.
disabled
)
return
;
var
barTracking
,
barStart
,
barMove
;
if
(
this
.
options
.
draggableRange
)
{
barTracking
=
'rzSliderDrag'
;
barStart
=
this
.
onDragStart
;
barMove
=
this
.
onDragMove
;
}
else
{
barTracking
=
'rzSliderModel'
;
barStart
=
this
.
onStart
;
barMove
=
this
.
onMove
;
}
return
element
.
css
({
opacity
:
1
});
},
this
.
minH
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
minH
,
'rzSliderModel'
));
if
(
this
.
range
)
{
this
.
maxH
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
maxH
,
'rzSliderHigh'
));
}
this
.
fullBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
this
.
fullBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
fullBar
));
this
.
selBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
barStart
,
null
,
barTracking
));
this
.
selBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
barMove
,
this
.
selBar
));
this
.
ticks
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
this
.
ticks
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
ticks
));
this
.
minH
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
minH
,
'rzSliderModel'
));
if
(
this
.
range
)
{
this
.
maxH
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
maxH
,
'rzSliderHigh'
));
}
this
.
fullBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
this
.
fullBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
fullBar
));
this
.
selBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
barStart
,
null
,
barTracking
));
this
.
selBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
barMove
,
this
.
selBar
));
this
.
ticks
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
this
.
ticks
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
ticks
));
},
/**
* Unbind mouse and touch events to slider handles
*
* @returns {undefined}
*/
unbindEvents
:
function
()
{
this
.
minH
.
off
();
this
.
maxH
.
off
();
this
.
fullBar
.
off
();
this
.
selBar
.
off
();
this
.
ticks
.
off
();
},
/**
* onStart event handler
*
* @param {?Object} pointer The jqLite wrapped DOM element; if null, the closest handle is used
* @param {?string} ref The name of the handle being changed; if null, the closest handle's value is modified
* @param {Event} event The event
* @returns {undefined}
*/
onStart
:
function
(
pointer
,
ref
,
event
)
{
var
ehMove
,
ehEnd
,
eventNames
=
this
.
getEventNames
(
event
);
/**
* Set element left/top offset depending on whether slider is horizontal or vertical
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @param {number} pos
* @returns {number}
*/
setPosition
:
function
(
elem
,
pos
)
{
elem
.
rzsp
=
pos
;
var
css
=
{};
css
[
this
.
positionProperty
]
=
pos
+
'px'
;
elem
.
css
(
css
);
return
pos
;
},
event
.
stopPropagation
();
event
.
preventDefault
();
/**
* Get element width/height depending on whether slider is horizontal or vertical
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @returns {number}
*/
getDimension
:
function
(
elem
)
{
var
val
=
elem
[
0
].
getBoundingClientRect
();
if
(
this
.
options
.
vertical
)
elem
.
rzsd
=
(
val
.
bottom
-
val
.
top
)
*
this
.
options
.
scale
;
else
elem
.
rzsd
=
(
val
.
right
-
val
.
left
)
*
this
.
options
.
scale
;
return
elem
.
rzsd
;
},
if
(
this
.
tracking
!==
''
)
{
return
;
}
/**
* Set element width/height depending on whether slider is horizontal or vertical
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @param {number} dim
* @returns {number}
*/
setDimension
:
function
(
elem
,
dim
)
{
elem
.
rzsd
=
dim
;
var
css
=
{};
css
[
this
.
dimensionProperty
]
=
dim
+
'px'
;
elem
.
css
(
css
);
return
dim
;
},
// We have to do this in case the HTML where the sliders are on
// have been animated into view.
this
.
calcViewDimensions
();
/**
* Translate value to pixel offset
*
* @param {number} val
* @returns {number}
*/
valueToOffset
:
function
(
val
)
{
return
(
this
.
sanitizeOffsetValue
(
val
)
-
this
.
minValue
)
*
this
.
maxPos
/
this
.
valueRange
||
0
;
},
if
(
pointer
)
{
this
.
tracking
=
ref
;
}
else
{
pointer
=
this
.
getNearestHandle
(
event
);
this
.
tracking
=
pointer
===
this
.
minH
?
'rzSliderModel'
:
'rzSliderHigh'
;
}
/**
* Ensure that the position rendered is within the slider bounds, even if the value is not
*
* @param {number} val
* @returns {number}
*/
sanitizeOffsetValue
:
function
(
val
)
{
return
Math
.
min
(
Math
.
max
(
val
,
this
.
minValue
),
this
.
maxValue
);
},
pointer
.
addClass
(
'rz-active'
);
/**
* Translate offset to model value
*
* @param {number} offset
* @returns {number}
*/
offsetToValue
:
function
(
offset
)
{
return
(
offset
/
this
.
maxPos
)
*
this
.
valueRange
+
this
.
minValue
;
},
ehMove
=
angular
.
bind
(
this
,
this
.
dragging
.
active
?
this
.
onDragMove
:
this
.
onMove
,
pointer
);
ehEnd
=
angular
.
bind
(
this
,
this
.
onEnd
,
ehMove
);
// Events
$document
.
on
(
eventNames
.
moveEvent
,
ehMove
);
$document
.
one
(
eventNames
.
endEvent
,
ehEnd
);
this
.
callOnStart
();
},
/**
* Get the X-coordinate or Y-coordinate of an event
*
* @param {Object} event The event
* @returns {number}
*/
getEventXY
:
function
(
event
)
{
/* http://stackoverflow.com/a/12336075/282882 */
//noinspection JSLint
var
clientXY
=
this
.
options
.
vertical
?
'clientY'
:
'clientX'
;
if
(
clientXY
in
event
)
{
return
event
[
clientXY
];
}
/**
* onMove event handler
*
* @param {jqLite} pointer
* @param {Event} event The event
* @returns {undefined}
*/
onMove
:
function
(
pointer
,
event
)
{
var
newOffset
=
this
.
getEventPosition
(
event
),
newValue
;
if
(
newOffset
<=
0
)
{
if
(
pointer
.
rzsp
===
0
)
return
;
newValue
=
this
.
minValue
;
newOffset
=
0
;
}
else
if
(
newOffset
>=
this
.
maxPos
)
{
if
(
pointer
.
rzsp
===
this
.
maxPos
)
return
;
newValue
=
this
.
maxValue
;
newOffset
=
this
.
maxPos
;
}
else
{
newValue
=
this
.
offsetToValue
(
newOffset
);
newValue
=
this
.
roundStep
(
newValue
);
newOffset
=
this
.
valueToOffset
(
newValue
);
}
this
.
positionTrackingHandle
(
newValue
,
newOffset
);
},
/**
* onDragStart event handler
*
* Handles dragging of the middle bar.
*
* @param {Object} pointer The jqLite wrapped DOM element
* @param {string} ref One of the refLow, refHigh values
* @param {Event} event The event
* @returns {undefined}
*/
onDragStart
:
function
(
pointer
,
ref
,
event
)
{
var
offset
=
this
.
getEventPosition
(
event
);
this
.
dragging
=
{
active
:
true
,
value
:
this
.
offsetToValue
(
offset
),
difference
:
this
.
scope
.
rzSliderHigh
-
this
.
scope
.
rzSliderModel
,
offset
:
offset
,
lowDist
:
offset
-
this
.
minH
.
rzsp
,
highDist
:
this
.
maxH
.
rzsp
-
offset
};
this
.
minH
.
addClass
(
'rz-active'
);
this
.
maxH
.
addClass
(
'rz-active'
);
this
.
onStart
(
pointer
,
ref
,
event
);
},
/**
* onDragMove event handler
*
* Handles dragging of the middle bar.
*
* @param {jqLite} pointer
* @param {Event} event The event
* @returns {undefined}
*/
onDragMove
:
function
(
pointer
,
event
)
{
var
newOffset
=
this
.
getEventPosition
(
event
),
newMinOffset
,
newMaxOffset
,
newMinValue
,
newMaxValue
;
if
(
newOffset
<=
this
.
dragging
.
lowDist
)
{
if
(
pointer
.
rzsp
===
this
.
dragging
.
lowDist
)
{
return
;
}
newMinValue
=
this
.
minValue
;
newMinOffset
=
0
;
newMaxValue
=
this
.
minValue
+
this
.
dragging
.
difference
;
newMaxOffset
=
this
.
valueToOffset
(
newMaxValue
);
}
else
if
(
newOffset
>=
this
.
maxPos
-
this
.
dragging
.
highDist
)
{
if
(
pointer
.
rzsp
===
this
.
dragging
.
highDist
)
{
return
;
}
newMaxValue
=
this
.
maxValue
;
newMaxOffset
=
this
.
maxPos
;
newMinValue
=
this
.
maxValue
-
this
.
dragging
.
difference
;
newMinOffset
=
this
.
valueToOffset
(
newMinValue
);
}
else
{
newMinValue
=
this
.
offsetToValue
(
newOffset
-
this
.
dragging
.
lowDist
);
newMinValue
=
this
.
roundStep
(
newMinValue
);
newMinOffset
=
this
.
valueToOffset
(
newMinValue
);
newMaxValue
=
newMinValue
+
this
.
dragging
.
difference
;
newMaxOffset
=
this
.
valueToOffset
(
newMaxValue
);
}
return
event
.
originalEvent
===
undefined
?
event
.
touches
[
0
][
clientXY
]
:
event
.
originalEvent
.
touches
[
0
][
clientXY
];
},
this
.
positionTrackingBar
(
newMinValue
,
newMaxValue
,
newMinOffset
,
newMaxOffset
);
},
/**
* Compute the event position depending on whether the slider is horizontal or vertical
* @param event
* @returns {number}
*/
getEventPosition
:
function
(
event
)
{
var
sliderPos
=
this
.
sliderElem
.
rzsp
,
eventPos
=
0
;
if
(
this
.
options
.
vertical
)
eventPos
=
-
this
.
getEventXY
(
event
)
+
sliderPos
;
else
eventPos
=
this
.
getEventXY
(
event
)
-
sliderPos
;
return
(
eventPos
-
this
.
handleHalfDim
)
*
this
.
options
.
scale
;
},
/**
* Set the new value and offset for the entire bar
*
* @param {number} newMinValue the new minimum value
* @param {number} newMaxValue the new maximum value
* @param {number} newMinOffset the new minimum offset
* @param {number} newMaxOffset the new maximum offset
*/
positionTrackingBar
:
function
(
newMinValue
,
newMaxValue
,
newMinOffset
,
newMaxOffset
)
{
this
.
scope
.
rzSliderModel
=
newMinValue
;
this
.
scope
.
rzSliderHigh
=
newMaxValue
;
this
.
updateHandles
(
'rzSliderModel'
,
newMinOffset
);
this
.
updateHandles
(
'rzSliderHigh'
,
newMaxOffset
);
this
.
scope
.
$apply
();
this
.
callOnChange
();
},
/**
* Get the handle closest to an event.
*
* @param event {Event} The event
* @returns {jqLite} The handle closest to the event.
*/
getNearestHandle
:
function
(
event
)
{
if
(
!
this
.
range
)
{
return
this
.
minH
;
}
var
offset
=
this
.
getEventPosition
(
event
);
return
Math
.
abs
(
offset
-
this
.
minH
.
rzsp
)
<
Math
.
abs
(
offset
-
this
.
maxH
.
rzsp
)
?
this
.
minH
:
this
.
maxH
;
},
/**
* Set the new value and offset to the current tracking handle
*
* @param {number} newValue new model value
* @param {number} newOffset new offset value
*/
positionTrackingHandle
:
function
(
newValue
,
newOffset
)
{
if
(
this
.
range
)
{
/* This is to check if we need to switch the min and max handles*/
if
(
this
.
tracking
===
'rzSliderModel'
&&
newValue
>=
this
.
scope
.
rzSliderHigh
)
{
this
.
scope
[
this
.
tracking
]
=
this
.
scope
.
rzSliderHigh
;
this
.
updateHandles
(
this
.
tracking
,
this
.
maxH
.
rzsp
);
this
.
tracking
=
'rzSliderHigh'
;
this
.
minH
.
removeClass
(
'rz-active'
);
this
.
maxH
.
addClass
(
'rz-active'
);
/* We need to apply here because we are not sure that we will enter the next block */
this
.
scope
.
$apply
();
this
.
callOnChange
();
}
else
if
(
this
.
tracking
===
'rzSliderHigh'
&&
newValue
<=
this
.
scope
.
rzSliderModel
)
{
this
.
scope
[
this
.
tracking
]
=
this
.
scope
.
rzSliderModel
;
this
.
updateHandles
(
this
.
tracking
,
this
.
minH
.
rzsp
);
this
.
tracking
=
'rzSliderModel'
;
this
.
maxH
.
removeClass
(
'rz-active'
);
this
.
minH
.
addClass
(
'rz-active'
);
/* We need to apply here because we are not sure that we will enter the next block */
this
.
scope
.
$apply
();
this
.
callOnChange
();
}
/**
* Bind mouse and touch events to slider handles
*
* @returns {undefined}
*/
bindEvents
:
function
()
{
if
(
this
.
options
.
readOnly
||
this
.
options
.
disabled
)
return
;
var
barTracking
,
barStart
,
barMove
;
if
(
this
.
options
.
draggableRange
)
{
barTracking
=
'rzSliderDrag'
;
barStart
=
this
.
onDragStart
;
barMove
=
this
.
onDragMove
;
}
else
{
barTracking
=
'rzSliderModel'
;
barStart
=
this
.
onStart
;
barMove
=
this
.
onMove
;
}
this
.
minH
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
minH
,
'rzSliderModel'
));
if
(
this
.
range
)
{
this
.
maxH
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
maxH
,
'rzSliderHigh'
));
}
this
.
fullBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
this
.
fullBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
fullBar
));
this
.
selBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
barStart
,
null
,
barTracking
));
this
.
selBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
barMove
,
this
.
selBar
));
this
.
ticks
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
this
.
ticks
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
ticks
));
this
.
minH
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
minH
,
'rzSliderModel'
));
if
(
this
.
range
)
{
this
.
maxH
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
maxH
,
'rzSliderHigh'
));
}
this
.
fullBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
this
.
fullBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
fullBar
));
this
.
selBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
barStart
,
null
,
barTracking
));
this
.
selBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
barMove
,
this
.
selBar
));
this
.
ticks
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
this
.
ticks
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
ticks
));
},
/**
* Unbind mouse and touch events to slider handles
*
* @returns {undefined}
*/
unbindEvents
:
function
()
{
this
.
minH
.
off
();
this
.
maxH
.
off
();
this
.
fullBar
.
off
();
this
.
selBar
.
off
();
this
.
ticks
.
off
();
},
/**
* onStart event handler
*
* @param {?Object} pointer The jqLite wrapped DOM element; if null, the closest handle is used
* @param {?string} ref The name of the handle being changed; if null, the closest handle's value is modified
* @param {Event} event The event
* @returns {undefined}
*/
onStart
:
function
(
pointer
,
ref
,
event
)
{
var
ehMove
,
ehEnd
,
eventNames
=
this
.
getEventNames
(
event
);
event
.
stopPropagation
();
event
.
preventDefault
();
if
(
this
.
tracking
!==
''
)
{
return
;
}
// We have to do this in case the HTML where the sliders are on
// have been animated into view.
this
.
calcViewDimensions
();
if
(
pointer
)
{
this
.
tracking
=
ref
;
}
else
{
pointer
=
this
.
getNearestHandle
(
event
);
this
.
tracking
=
pointer
===
this
.
minH
?
'rzSliderModel'
:
'rzSliderHigh'
;
}
pointer
.
addClass
(
'rz-active'
);
ehMove
=
angular
.
bind
(
this
,
this
.
dragging
.
active
?
this
.
onDragMove
:
this
.
onMove
,
pointer
);
ehEnd
=
angular
.
bind
(
this
,
this
.
onEnd
,
ehMove
);
$document
.
on
(
eventNames
.
moveEvent
,
ehMove
);
$document
.
one
(
eventNames
.
endEvent
,
ehEnd
);
this
.
callOnStart
();
},
/**
* onMove event handler
*
* @param {jqLite} pointer
* @param {Event} event The event
* @returns {undefined}
*/
onMove
:
function
(
pointer
,
event
)
{
var
newOffset
=
this
.
getEventPosition
(
event
),
newValue
;
if
(
newOffset
<=
0
)
{
if
(
pointer
.
rzsp
===
0
)
return
;
newValue
=
this
.
minValue
;
newOffset
=
0
;
}
else
if
(
newOffset
>=
this
.
maxPos
)
{
if
(
pointer
.
rzsp
===
this
.
maxPos
)
return
;
newValue
=
this
.
maxValue
;
newOffset
=
this
.
maxPos
;
}
else
{
newValue
=
this
.
offsetToValue
(
newOffset
);
newValue
=
this
.
roundStep
(
newValue
);
newOffset
=
this
.
valueToOffset
(
newValue
);
}
this
.
positionTrackingHandle
(
newValue
,
newOffset
);
},
/**
* onDragStart event handler
*
* Handles dragging of the middle bar.
*
* @param {Object} pointer The jqLite wrapped DOM element
* @param {string} ref One of the refLow, refHigh values
* @param {Event} event The event
* @returns {undefined}
*/
onDragStart
:
function
(
pointer
,
ref
,
event
)
{
var
offset
=
this
.
getEventPosition
(
event
);
this
.
dragging
=
{
active
:
true
,
value
:
this
.
offsetToValue
(
offset
),
difference
:
this
.
scope
.
rzSliderHigh
-
this
.
scope
.
rzSliderModel
,
offset
:
offset
,
lowDist
:
offset
-
this
.
minH
.
rzsp
,
highDist
:
this
.
maxH
.
rzsp
-
offset
};
this
.
minH
.
addClass
(
'rz-active'
);
this
.
maxH
.
addClass
(
'rz-active'
);
this
.
onStart
(
pointer
,
ref
,
event
);
},
/**
* onDragMove event handler
*
* Handles dragging of the middle bar.
*
* @param {jqLite} pointer
* @param {Event} event The event
* @returns {undefined}
*/
onDragMove
:
function
(
pointer
,
event
)
{
var
newOffset
=
this
.
getEventPosition
(
event
),
newMinOffset
,
newMaxOffset
,
newMinValue
,
newMaxValue
;
if
(
newOffset
<=
this
.
dragging
.
lowDist
)
{
if
(
pointer
.
rzsp
===
this
.
dragging
.
lowDist
)
{
return
;
}
newMinValue
=
this
.
minValue
;
newMinOffset
=
0
;
newMaxValue
=
this
.
minValue
+
this
.
dragging
.
difference
;
newMaxOffset
=
this
.
valueToOffset
(
newMaxValue
);
}
else
if
(
newOffset
>=
this
.
maxPos
-
this
.
dragging
.
highDist
)
{
if
(
pointer
.
rzsp
===
this
.
dragging
.
highDist
)
{
return
;
}
newMaxValue
=
this
.
maxValue
;
newMaxOffset
=
this
.
maxPos
;
newMinValue
=
this
.
maxValue
-
this
.
dragging
.
difference
;
newMinOffset
=
this
.
valueToOffset
(
newMinValue
);
}
else
{
newMinValue
=
this
.
offsetToValue
(
newOffset
-
this
.
dragging
.
lowDist
);
newMinValue
=
this
.
roundStep
(
newMinValue
);
newMinOffset
=
this
.
valueToOffset
(
newMinValue
);
newMaxValue
=
newMinValue
+
this
.
dragging
.
difference
;
newMaxOffset
=
this
.
valueToOffset
(
newMaxValue
);
}
this
.
positionTrackingBar
(
newMinValue
,
newMaxValue
,
newMinOffset
,
newMaxOffset
);
},
/**
* Set the new value and offset for the entire bar
*
* @param {number} newMinValue the new minimum value
* @param {number} newMaxValue the new maximum value
* @param {number} newMinOffset the new minimum offset
* @param {number} newMaxOffset the new maximum offset
*/
positionTrackingBar
:
function
(
newMinValue
,
newMaxValue
,
newMinOffset
,
newMaxOffset
)
{
this
.
scope
.
rzSliderModel
=
newMinValue
;
this
.
scope
.
rzSliderHigh
=
newMaxValue
;
this
.
updateHandles
(
'rzSliderModel'
,
newMinOffset
);
this
.
updateHandles
(
'rzSliderHigh'
,
newMaxOffset
);
this
.
scope
.
$apply
();
this
.
callOnChange
();
},
if
(
this
.
scope
[
this
.
tracking
]
!==
newValue
)
{
this
.
scope
[
this
.
tracking
]
=
newValue
;
this
.
updateHandles
(
this
.
tracking
,
newOffset
);
/**
* Set the new value and offset to the current tracking handle
*
* @param {number} newValue new model value
* @param {number} newOffset new offset value
*/
positionTrackingHandle
:
function
(
newValue
,
newOffset
)
{
if
(
this
.
range
)
{
/* This is to check if we need to switch the min and max handles*/
if
(
this
.
tracking
===
'rzSliderModel'
&&
newValue
>=
this
.
scope
.
rzSliderHigh
)
{
this
.
scope
[
this
.
tracking
]
=
this
.
scope
.
rzSliderHigh
;
this
.
updateHandles
(
this
.
tracking
,
this
.
maxH
.
rzsp
);
this
.
tracking
=
'rzSliderHigh'
;
this
.
minH
.
removeClass
(
'rz-active'
);
this
.
maxH
.
addClass
(
'rz-active'
);
/* We need to apply here because we are not sure that we will enter the next block */
this
.
scope
.
$apply
();
this
.
callOnChange
();
}
else
if
(
this
.
tracking
===
'rzSliderHigh'
&&
newValue
<=
this
.
scope
.
rzSliderModel
)
{
this
.
scope
[
this
.
tracking
]
=
this
.
scope
.
rzSliderModel
;
this
.
updateHandles
(
this
.
tracking
,
this
.
minH
.
rzsp
);
this
.
tracking
=
'rzSliderModel'
;
this
.
maxH
.
removeClass
(
'rz-active'
);
this
.
minH
.
addClass
(
'rz-active'
);
/* We need to apply here because we are not sure that we will enter the next block */
this
.
scope
.
$apply
();
this
.
callOnChange
();
}
},
/**
* onEnd event handler
*
* @param {Event} event The event
* @param {Function} ehMove The the bound move event handler
* @returns {undefined}
*/
onEnd
:
function
(
ehMove
,
event
)
{
var
moveEventName
=
this
.
getEventNames
(
event
).
moveEvent
;
}
this
.
minH
.
removeClass
(
'rz-active'
);
this
.
maxH
.
removeClass
(
'rz-active'
);
if
(
this
.
scope
[
this
.
tracking
]
!==
newValue
)
{
this
.
scope
[
this
.
tracking
]
=
newValue
;
this
.
updateHandles
(
this
.
tracking
,
newOffset
);
this
.
scope
.
$apply
();
this
.
callOnChange
();
}
},
/**
* onEnd event handler
*
* @param {Event} event The event
* @param {Function} ehMove The the bound move event handler
* @returns {undefined}
*/
onEnd
:
function
(
ehMove
,
event
)
{
var
moveEventName
=
this
.
getEventNames
(
event
).
moveEvent
;
$document
.
off
(
moveEventName
,
ehMove
);
this
.
minH
.
removeClass
(
'rz-active'
);
this
.
maxH
.
removeClass
(
'rz-active'
);
this
.
scope
.
$emit
(
'slideEnded'
);
this
.
tracking
=
''
;
$document
.
off
(
moveEventName
,
ehMove
);
this
.
dragging
.
active
=
false
;
this
.
callOnEnd
();
},
this
.
scope
.
$emit
(
'slideEnded'
);
this
.
tracking
=
''
;
/**
* Get event names for move and event end
*
* @param {Event} event The event
*
* @return {{moveEvent: string, endEvent: string}}
*/
getEventNames
:
function
(
event
)
{
var
eventNames
=
{
moveEvent
:
''
,
endEvent
:
''
};
this
.
dragging
.
active
=
false
;
this
.
callOnEnd
();
},
if
(
event
.
touches
||
(
event
.
originalEvent
!==
undefined
&&
event
.
originalEvent
.
touches
))
{
eventNames
.
moveEvent
=
'touchmove'
;
eventNames
.
endEvent
=
'touchend'
;
}
else
{
eventNames
.
moveEvent
=
'mousemove'
;
eventNames
.
endEvent
=
'mouseup'
;
}
/**
* Get event names for move and event end
*
* @param {Event} event The event
*
* @return {{moveEvent: string, endEvent: string}}
*/
getEventNames
:
function
(
event
)
{
var
eventNames
=
{
moveEvent
:
''
,
endEvent
:
''
};
return
eventNames
;
if
(
event
.
touches
||
(
event
.
originalEvent
!==
undefined
&&
event
.
originalEvent
.
touches
))
{
eventNames
.
moveEvent
=
'touchmove'
;
eventNames
.
endEvent
=
'touchend'
;
}
else
{
eventNames
.
moveEvent
=
'mousemove'
;
eventNames
.
endEvent
=
'mouseup'
;
}
};
return
Slider
;
})
return
eventNames
;
}
};
.
directive
(
'rzslider'
,
function
(
RzSlider
)
{
'use strict'
;
return
Slider
;
})
return
{
restrict
:
'E'
,
scope
:
{
rzSliderModel
:
'=?'
,
rzSliderHigh
:
'=?'
,
rzSliderOptions
:
'=?'
,
rzSliderTplUrl
:
'@'
},
/**
* Return template URL
*
* @param {jqLite} elem
* @param {Object} attrs
* @return {string}
*/
templateUrl
:
function
(
elem
,
attrs
)
{
//noinspection JSUnresolvedVariable
return
attrs
.
rzSliderTplUrl
||
'rzSliderTpl.html'
;
},
.
directive
(
'rzslider'
,
function
(
RzSlider
)
{
'use strict'
;
link
:
function
(
scope
,
elem
)
{
return
new
RzSlider
(
scope
,
elem
);
}
};
});
return
{
restrict
:
'E'
,
scope
:
{
rzSliderModel
:
'=?'
,
rzSliderHigh
:
'=?'
,
rzSliderOptions
:
'=?'
,
rzSliderTplUrl
:
'@'
},
/**
* Return template URL
*
* @param {jqLite} elem
* @param {Object} attrs
* @return {string}
*/
templateUrl
:
function
(
elem
,
attrs
)
{
//noinspection JSUnresolvedVariable
return
attrs
.
rzSliderTplUrl
||
'rzSliderTpl.html'
;
},
link
:
function
(
scope
,
elem
)
{
return
new
RzSlider
(
scope
,
elem
);
}
};
});
// IDE assist
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment