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
d03ac54c
Commit
d03ac54c
authored
Nov 11, 2015
by
Valentin Hervieu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Apply editorconfig formatting
parent
a7c7f0e3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
2447 additions
and
2455 deletions
+2447
-2455
Gruntfile.js
Gruntfile.js
+119
-119
rzslider.js
dist/rzslider.js
+1164
-1168
rzslider.js
src/rzslider.js
+1164
-1168
No files found.
Gruntfile.js
View file @
d03ac54c
module
.
exports
=
function
(
grunt
)
{
// Project configuration.
grunt
.
initConfig
({
// Project configuration.
grunt
.
initConfig
({
pkg
:
grunt
.
file
.
readJSON
(
'package.json'
),
pkg
:
grunt
.
file
.
readJSON
(
'package.json'
),
minBanner
:
'/*! <%= pkg.name %> - v<%= pkg.version %> - '
+
'(c) <%= pkg.author %>, <%= pkg.repository.url %> - '
+
'<%= grunt.template.today("yyyy-mm-dd") %> */
\
n'
,
minBanner
:
'/*! <%= pkg.name %> - v<%= pkg.version %> - '
+
'(c) <%= pkg.author %>, <%= pkg.repository.url %> - '
+
'<%= grunt.template.today("yyyy-mm-dd") %> */
\
n'
,
recess
:
{
options
:
{
compile
:
true
},
recess
:
{
options
:
{
compile
:
true
},
slider
:
{
src
:
[
'src/rzslider.less'
],
dest
:
'dist/rzslider.css'
},
slider
:
{
src
:
[
'src/rzslider.less'
],
dest
:
'dist/rzslider.css'
},
min
:
{
options
:
{
compress
:
true
,
banner
:
'<%= minBanner %>'
},
src
:
[
'dist/rzslider.css'
],
dest
:
'dist/rzslider.min.css'
}
min
:
{
options
:
{
compress
:
true
,
banner
:
'<%= minBanner %>'
},
src
:
[
'dist/rzslider.css'
],
dest
:
'dist/rzslider.min.css'
}
},
uglify
:
{
options
:
{
report
:
'min'
,
banner
:
'<%= minBanner %>'
},
rzslider
:
{
files
:
{
'dist/rzslider.min.js'
:
[
'dist/rzslider.js'
]
}
}
},
uglify
:
{
options
:
{
report
:
'min'
,
banner
:
'<%= minBanner %>'
},
rzslider
:
{
files
:
{
'dist/rzslider.min.js'
:
[
'dist/rzslider.js'
]
}
}
},
ngtemplates
:
{
app
:
{
src
:
'src/**.html'
,
dest
:
'temp/templates.js'
,
options
:
{
htmlmin
:
{
collapseBooleanAttributes
:
true
,
collapseWhitespace
:
true
,
removeAttributeQuotes
:
true
,
removeComments
:
true
,
// Only if you don't use comment directives!
removeEmptyAttributes
:
true
,
removeRedundantAttributes
:
true
,
removeScriptTypeAttributes
:
true
,
removeStyleLinkTypeAttributes
:
true
},
module
:
'rzModule'
,
url
:
function
(
url
)
{
return
url
.
replace
(
'src/'
,
''
);
},
bootstrap
:
function
(
module
,
script
)
{
return
'module.run(function($templateCache) {
\
n'
+
script
+
'
\
n});'
;
}
}
}
},
ngtemplates
:
{
app
:
{
src
:
'src/**.html'
,
dest
:
'temp/templates.js'
,
options
:
{
htmlmin
:
{
collapseBooleanAttributes
:
true
,
collapseWhitespace
:
true
,
removeAttributeQuotes
:
true
,
removeComments
:
true
,
// Only if you don't use comment directives!
removeEmptyAttributes
:
true
,
removeRedundantAttributes
:
true
,
removeScriptTypeAttributes
:
true
,
removeStyleLinkTypeAttributes
:
true
},
module
:
'rzModule'
,
url
:
function
(
url
)
{
return
url
.
replace
(
'src/'
,
''
);
},
bootstrap
:
function
(
module
,
script
)
{
return
'module.run(function($templateCache) {
\
n'
+
script
+
'
\
n});'
;
}
}
}
},
replace
:
{
dist
:
{
options
:
{
patterns
:
[
{
match
:
/
\/\*
templateReplacement
\*\/
/
,
replacement
:
'<%= grunt.file.read("temp/templates.js") %>'
}
]
},
files
:
[
{
expand
:
true
,
flatten
:
true
,
src
:
[
'src/rzslider.js'
],
dest
:
'dist/'
}
]
}
replace
:
{
dist
:
{
options
:
{
patterns
:
[{
match
:
/
\/\*
templateReplacement
\*\/
/
,
replacement
:
'<%= grunt.file.read("temp/templates.js") %>'
}]
},
files
:
[{
expand
:
true
,
flatten
:
true
,
src
:
[
'src/rzslider.js'
],
dest
:
'dist/'
}]
}
},
ngAnnotate
:
{
options
:
{
singleQuotes
:
true
,
},
rzslider
:
{
files
:
[{
'dist/rzslider.js'
:
'dist/rzslider.js'
},
{
expand
:
true
,
src
:
[
'dist/rzslider.js'
]
}
]
}
},
watch
:
{
all
:
{
files
:
[
'dist/*'
,
'demo/*'
],
options
:
{
livereload
:
true
}
},
js
:
{
files
:
[
'src/*js'
,
'src/*.html'
],
tasks
:
[
'js'
]
},
less
:
{
files
:
[
'src/*.less'
],
tasks
:
[
'css'
]
}
},
serve
:
{
options
:
{
port
:
9000
}
ngAnnotate
:
{
options
:
{
singleQuotes
:
true
,
},
rzslider
:
{
files
:
[{
'dist/rzslider.js'
:
'dist/rzslider.js'
},
{
expand
:
true
,
src
:
[
'dist/rzslider.js'
]
}]
}
},
watch
:
{
all
:
{
files
:
[
'dist/*'
,
'demo/*'
],
options
:
{
livereload
:
true
}
},
js
:
{
files
:
[
'src/*js'
,
'src/*.html'
],
tasks
:
[
'js'
]
},
less
:
{
files
:
[
'src/*.less'
],
tasks
:
[
'css'
]
}
},
serve
:
{
options
:
{
port
:
9000
}
}
});
});
grunt
.
loadNpmTasks
(
'grunt-contrib-uglify'
);
grunt
.
loadNpmTasks
(
'grunt-recess'
);
grunt
.
loadNpmTasks
(
'grunt-angular-templates'
);
grunt
.
loadNpmTasks
(
'grunt-replace'
);
grunt
.
loadNpmTasks
(
'grunt-ng-annotate'
);
grunt
.
loadNpmTasks
(
'grunt-contrib-watch'
);
grunt
.
loadNpmTasks
(
'grunt-serve'
);
grunt
.
loadNpmTasks
(
'grunt-contrib-uglify'
);
grunt
.
loadNpmTasks
(
'grunt-recess'
);
grunt
.
loadNpmTasks
(
'grunt-angular-templates'
);
grunt
.
loadNpmTasks
(
'grunt-replace'
);
grunt
.
loadNpmTasks
(
'grunt-ng-annotate'
);
grunt
.
loadNpmTasks
(
'grunt-contrib-watch'
);
grunt
.
loadNpmTasks
(
'grunt-serve'
);
grunt
.
registerTask
(
'default'
,
[
'css'
,
'js'
]);
grunt
.
registerTask
(
'default'
,
[
'css'
,
'js'
]);
grunt
.
registerTask
(
'css'
,
[
'recess'
]);
grunt
.
registerTask
(
'js'
,
[
'ngtemplates'
,
'replace'
,
'ngAnnotate'
,
'uglify'
]);
grunt
.
registerTask
(
'css'
,
[
'recess'
]);
grunt
.
registerTask
(
'js'
,
[
'ngtemplates'
,
'replace'
,
'ngAnnotate'
,
'uglify'
]);
};
dist/rzslider.js
View file @
d03ac54c
...
...
@@ -31,53 +31,53 @@
'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
,
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
(
'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
,
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
.
getOptions
=
function
(
options
)
{
return
angular
.
extend
({},
defaultOptions
,
globalOptions
,
options
);
};
factory
.
getOptions
=
function
(
options
)
{
return
angular
.
extend
({},
defaultOptions
,
globalOptions
,
options
);
};
return
factory
;
})
return
factory
;
})
.
value
(
'rzThrottle'
,
.
value
(
'rzThrottle'
,
/**
* rzThrottle
*
...
...
@@ -124,1242 +124,1238 @@
};
})
.
factory
(
'RzSlider'
,
[
'$timeout'
,
'$document'
,
'$window'
,
'$compile'
,
'RzSliderOptions'
,
'rzThrottle'
,
function
(
$timeout
,
$document
,
$window
,
$compile
,
RzSliderOptions
,
rzThrottle
)
{
'use strict'
;
.
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
)
{
/**
*
Slider
*
The slider's scope
*
* @param {ngScope} scope The AngularJS scope
* @param {Element} sliderElem The slider directive element wrapped in jqLite
* @constructor
* @type {ngScope}
*/
var
Slider
=
function
(
scope
,
sliderElem
)
{
/**
* The slider's scope
*
* @type {ngScope}
*/
this
.
scope
=
scope
;
this
.
scope
=
scope
;
/**
* Slider element wrapped in jqLite
*
* @type {jqLite}
*/
this
.
sliderElem
=
sliderElem
;
/**
* Slider element wrapped in jqLite
*
* @type {jqLite}
*/
this
.
sliderElem
=
sliderElem
;
/**
* Slider type
*
* @type {boolean} Set to true for range slider
*/
this
.
range
=
this
.
scope
.
rzSliderModel
!==
undefined
&&
this
.
scope
.
rzSliderHigh
!==
undefined
;
/**
* Slider type
*
* @type {boolean} Set to true for range slider
*/
this
.
range
=
this
.
scope
.
rzSliderModel
!==
undefined
&&
this
.
scope
.
rzSliderHigh
!==
undefined
;
/**
* Values recorded when first dragging the bar
*
* @type {Object}
*/
this
.
dragging
=
{
active
:
false
,
value
:
0
,
difference
:
0
,
offset
:
0
,
lowDist
:
0
,
highDist
:
0
};
/**
* 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 of the slider handles
*
* @type {number}
*/
this
.
handleHalfWidth
=
0
;
/**
* Half of the width of the slider handles
*
* @type {number}
*/
this
.
handleHalfWidth
=
0
;
/**
* Maximum left the slider handle can have
*
* @type {number}
*/
this
.
maxLeft
=
0
;
/**
* Maximum left the slider handle can have
*
* @type {number}
*/
this
.
maxLeft
=
0
;
/**
* Precision
*
* @type {number}
*/
this
.
precision
=
0
;
/**
* Precision
*
* @type {number}
*/
this
.
precision
=
0
;
/**
* Step
*
* @type {number}
*/
this
.
step
=
0
;
/**
* Step
*
* @type {number}
*/
this
.
step
=
0
;
/**
* The name of the handle we are currently tracking
*
* @type {string}
*/
this
.
tracking
=
''
;
/**
* The name of the handle we are currently tracking
*
* @type {string}
*/
this
.
tracking
=
''
;
/**
* Minimum value (floor) of the model
*
* @type {number}
*/
this
.
minValue
=
0
;
/**
* Minimum value (floor) of the model
*
* @type {number}
*/
this
.
minValue
=
0
;
/**
* Maximum value (ceiling) of the model
*
* @type {number}
*/
this
.
maxValue
=
0
;
/**
* Maximum value (ceiling) of the model
*
* @type {number}
*/
this
.
maxValue
=
0
;
/**
* The delta between min and max value
*
* @type {number}
*/
this
.
valueRange
=
0
;
/**
* The delta between min and max value
*
* @type {number}
*/
this
.
valueRange
=
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
();
};
/**
* 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
=
{
// 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
();
});
// Recalculate slider view dimensions
this
.
scope
.
$on
(
'reCalcViewDimensions'
,
calcDimFn
);
// Recalculate stuff if view port dimensions have changed
angular
.
element
(
$window
).
on
(
'resize'
,
calcDimFn
);
this
.
initHasRun
=
true
;
// Watch for changes to the model
thrLow
=
rzThrottle
(
function
()
{
self
.
setMinAndMax
();
self
.
updateLowHandle
(
self
.
valueToOffset
(
self
.
scope
.
rzSliderModel
));
self
.
updateSelectionBar
();
self
.
updateTicksScale
();
if
(
self
.
range
)
{
self
.
updateCmbLabel
();
}
/**
* Initialize slider
*
* @returns {undefined}
*/
init
:
function
()
{
var
thrLow
,
thrHigh
,
calcDimFn
=
angular
.
bind
(
this
,
this
.
calcViewDimensions
),
self
=
this
;
this
.
applyOptions
();
this
.
initElemHandles
();
th
is
.
manageElementsStyle
();
this
.
addAccessibility
();
this
.
manageEventsBindings
();
this
.
setDisabledState
();
this
.
calcViewDimensions
();
this
.
setMinAndMax
(
);
},
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
();
th
rLow
();
if
(
self
.
range
)
{
thrHigh
();
}
self
.
resetSlider
();
}
);
$timeout
(
function
()
{
self
.
updateCeilLab
();
self
.
updateFloorLab
();
self
.
initHandles
()
;
self
.
bindEvents
();
});
// Watchers
this
.
scope
.
$watch
(
'rzSliderModel'
,
function
(
newValue
,
oldValue
)
{
if
(
newValue
===
oldValue
)
return
;
thrLow
();
});
// Recalculate slider view dimensions
this
.
scope
.
$on
(
'reCalcViewDimensions'
,
calcDimFn
);
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
();
}
});
// Recalculate stuff if view port dimensions have changed
angular
.
element
(
$window
).
on
(
'resize'
,
calcDimFn
);
this
.
scope
.
$watch
(
'rzSliderOptions'
,
function
(
newValue
,
oldValue
)
{
if
(
newValue
===
oldValue
)
return
;
self
.
applyOptions
();
self
.
resetSlider
();
},
true
);
this
.
initHasRun
=
true
;
this
.
scope
.
$on
(
'$destroy'
,
function
()
{
self
.
unbindEvents
();
angular
.
element
(
$window
).
off
(
'resize'
,
calcDimFn
);
});
},
// Watch for changes to the model
/**
* Read the user options and apply them to the slider model
*/
applyOptions
:
function
()
{
this
.
options
=
RzSliderOptions
.
getOptions
(
this
.
scope
.
rzSliderOptions
);
thrLow
=
rzThrottle
(
function
()
{
self
.
setMinAndMax
();
self
.
updateLowHandle
(
self
.
valueToOffset
(
self
.
scope
.
rzSliderModel
));
self
.
updateSelectionBar
();
self
.
updateTicksScale
();
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
(
self
.
range
)
{
self
.
updateCmbLabel
();
}
/**
* Resets slider
*
* @returns {undefined}
*/
resetSlider
:
function
()
{
this
.
manageElementsStyle
();
this
.
setMinAndMax
();
this
.
updateCeilLab
();
this
.
updateFloorLab
();
this
.
unbindEvents
();
this
.
manageEventsBindings
();
this
.
setDisabledState
();
this
.
calcViewDimensions
();
},
},
self
.
options
.
interval
);
/**
* 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
;
}
thrHigh
=
rzThrottle
(
function
()
{
self
.
setMinAndMax
();
self
.
updateHighHandle
(
self
.
valueToOffset
(
self
.
scope
.
rzSliderHigh
));
self
.
updateSelectionBar
();
self
.
updateTicksScale
();
self
.
updateCmbLabel
();
},
self
.
options
.
interval
);
},
this
);
this
.
scope
.
$on
(
'rzSliderForceRender'
,
function
()
{
self
.
resetLabelsValue
();
thrLow
();
if
(
self
.
range
)
{
thrHigh
();
}
self
.
resetSlider
();
});
// Initialize offset cache properties
this
.
selBar
.
rzsl
=
0
;
this
.
minH
.
rzsl
=
0
;
this
.
maxH
.
rzsl
=
0
;
this
.
flrLab
.
rzsl
=
0
;
this
.
ceilLab
.
rzsl
=
0
;
this
.
minLab
.
rzsl
=
0
;
this
.
maxLab
.
rzsl
=
0
;
this
.
cmbLab
.
rzsl
=
0
;
},
// Watchers
this
.
scope
.
$watch
(
'rzSliderModel'
,
function
(
newValue
,
oldValue
)
{
if
(
newValue
===
oldValue
)
return
;
thrLow
();
});
/** 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
)
},
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
();
}
});
/**
* 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
();
},
this
.
scope
.
$watch
(
'rzSliderOptions'
,
function
(
newValue
,
oldValue
)
{
if
(
newValue
===
oldValue
)
return
;
self
.
applyOptions
();
self
.
resetSlider
();
},
true
);
/**
* 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
);
}
},
this
.
scope
.
$on
(
'$destroy'
,
function
()
{
self
.
unbindEvents
();
angular
.
element
(
$window
).
off
(
'resize'
,
calcDimFn
);
});
},
/**
* Reset label values
*
* @return {undefined}
*/
resetLabelsValue
:
function
()
{
this
.
minLab
.
rzsv
=
undefined
;
this
.
maxLab
.
rzsv
=
undefined
;
},
/**
* 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
);
};
},
/**
* Resets slider
*
* @returns {undefined}
*/
resetSlider
:
function
()
{
this
.
manageElementsStyle
();
this
.
setMinAndMax
();
this
.
updateCeilLab
();
this
.
updateFloorLab
();
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
;
}
/**
* 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
));
},
this
);
// Initialize offset cache properties
this
.
selBar
.
rzsl
=
0
;
this
.
minH
.
rzsl
=
0
;
this
.
maxH
.
rzsl
=
0
;
this
.
flrLab
.
rzsl
=
0
;
this
.
ceilLab
.
rzsl
=
0
;
this
.
minLab
.
rzsl
=
0
;
this
.
maxLab
.
rzsl
=
0
;
this
.
cmbLab
.
rzsl
=
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}
/*
the order here is important since the selection bar should be
updated after the high handle but before the combined label
*/
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
);
}
},
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
;
},
/**
* 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
();
this
.
updateTicksScale
();
},
this
.
updateTicksScale
();
},
/**
* 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
;
/**
* 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
;
var
valStr
=
String
((
useCustomTr
?
this
.
customTrFn
(
value
,
this
.
options
.
id
)
:
value
)),
getWidth
=
false
;
var
valStr
=
String
((
useCustomTr
?
this
.
customTrFn
(
value
,
this
.
options
.
id
)
:
value
)),
getWidth
=
false
;
if
(
label
.
rzsv
===
undefined
||
label
.
rzsv
.
length
!==
valStr
.
length
||
(
label
.
rzsv
.
length
>
0
&&
label
.
rzsw
===
0
))
{
getWidth
=
true
;
label
.
rzsv
=
valStr
;
}
if
(
label
.
rzsv
===
undefined
||
label
.
rzsv
.
length
!==
valStr
.
length
||
(
label
.
rzsv
.
length
>
0
&&
label
.
rzsw
===
0
))
{
getWidth
=
true
;
label
.
rzsv
=
valStr
;
}
label
.
text
(
valStr
);
label
.
text
(
valStr
);
// Update width only when length of the label have changed
if
(
getWidth
)
{
this
.
getWidth
(
label
);
}
},
// Update width only when length of the label have changed
if
(
getWidth
)
{
this
.
getWidth
(
label
);
}
},
/**
* Set maximum and minimum values for the slider and ensure the model and high
* value match these limits
* @returns {undefined}
*/
setMinAndMax
:
function
()
{
/**
* Set maximum and minimum values for the slider and ensure the model and high
* value match these limits
* @returns {undefined}
*/
setMinAndMax
:
function
()
{
this
.
step
=
+
this
.
options
.
step
;
this
.
precision
=
+
this
.
options
.
precision
;
this
.
step
=
+
this
.
options
.
step
;
this
.
precision
=
+
this
.
options
.
precision
;
this
.
scope
.
rzSliderModel
=
this
.
roundStep
(
this
.
scope
.
rzSliderModel
);
if
(
this
.
range
)
this
.
scope
.
rzSliderHigh
=
this
.
roundStep
(
this
.
scope
.
rzSliderHigh
);
this
.
scope
.
rzSliderModel
=
this
.
roundStep
(
this
.
scope
.
rzSliderModel
);
if
(
this
.
range
)
this
.
scope
.
rzSliderHigh
=
this
.
roundStep
(
this
.
scope
.
rzSliderHigh
);
this
.
minValue
=
this
.
roundStep
(
+
this
.
options
.
floor
);
this
.
minValue
=
this
.
roundStep
(
+
this
.
options
.
floor
);
if
(
this
.
options
.
ceil
)
this
.
maxValue
=
this
.
roundStep
(
+
this
.
options
.
ceil
);
else
this
.
maxValue
=
this
.
options
.
ceil
=
this
.
range
?
this
.
scope
.
rzSliderHigh
:
this
.
scope
.
rzSliderModel
;
if
(
this
.
options
.
ceil
)
this
.
maxValue
=
this
.
roundStep
(
+
this
.
options
.
ceil
);
else
this
.
maxValue
=
this
.
options
.
ceil
=
this
.
range
?
this
.
scope
.
rzSliderHigh
:
this
.
scope
.
rzSliderModel
;
this
.
valueRange
=
this
.
maxValue
-
this
.
minValue
;
},
this
.
valueRange
=
this
.
maxValue
-
this
.
minValue
;
},
/**
* 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
.
getWidth
(
this
.
minH
);
/**
* Adds accessibility atributes
*
* Run only once during initialization
*
* @returns {undefined}
*/
addAccessibility
:
function
()
{
this
.
sliderElem
.
attr
(
"role"
,
"slider"
);
},
this
.
handleHalfWidth
=
handleWidth
/
2
;
this
.
barWidth
=
this
.
getWidth
(
this
.
fullBar
);
/**
* 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
.
getWidth
(
this
.
minH
);
this
.
maxLeft
=
this
.
barWidth
-
handleWidth
;
this
.
handleHalfWidth
=
handleWidth
/
2
;
this
.
barWidth
=
this
.
getWidth
(
this
.
fullBar
);
this
.
getWidth
(
this
.
sliderElem
);
this
.
sliderElem
.
rzsl
=
this
.
sliderElem
[
0
].
getBoundingClientRect
().
left
;
this
.
maxLeft
=
this
.
barWidth
-
handleWidth
;
if
(
this
.
initHasRun
)
{
this
.
updateFloorLab
();
this
.
updateCeilLab
();
this
.
initHandles
();
}
},
this
.
getWidth
(
this
.
sliderElem
);
this
.
sliderElem
.
rzsl
=
this
.
sliderElem
[
0
].
getBoundingClientRect
().
left
;
/**
* 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
)
+
'"'
;
}
positions
+=
'<span '
+
tooltip
+
' class="tick-value">'
+
this
.
getDisplayValue
(
value
)
+
'</span>'
;
if
(
this
.
initHasRun
)
{
this
.
updateFloorLab
();
this
.
updateCeilLab
();
this
.
initHandles
();
}
},
/**
* 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
)
+
'"'
;
}
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
.
setLeft
(
this
.
ceilLab
,
this
.
barWidth
-
this
.
ceilLab
.
rzsw
);
this
.
getWidth
(
this
.
ceilLab
);
},
/**
* Update position of the floor label
*
* @returns {undefined}
*/
updateFloorLab
:
function
()
{
this
.
translateFn
(
this
.
minValue
,
this
.
flrLab
);
this
.
getWidth
(
this
.
flrLab
);
},
/**
* Call the onStart callback if defined
*
* @returns {undefined}
*/
callOnStart
:
function
()
{
if
(
this
.
options
.
onStart
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onStart
();
});
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
;
},
/**
* Call the onChange callback if defined
*
* @returns {undefined}
*/
callOnChange
:
function
()
{
if
(
this
.
options
.
onChange
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onChange
();
});
}
},
/**
* Update position of the ceiling label
*
* @returns {undefined}
*/
updateCeilLab
:
function
()
{
this
.
translateFn
(
this
.
maxValue
,
this
.
ceilLab
);
this
.
setLeft
(
this
.
ceilLab
,
this
.
barWidth
-
this
.
ceilLab
.
rzsw
);
this
.
getWidth
(
this
.
ceilLab
);
},
/**
* Call the onEnd callback if defined
*
* @returns {undefined}
*/
callOnEnd
:
function
()
{
if
(
this
.
options
.
onEnd
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onEnd
();
});
}
},
/**
* Update position of the floor label
*
* @returns {undefined}
*/
updateFloorLab
:
function
()
{
this
.
translateFn
(
this
.
minValue
,
this
.
flrLab
);
this
.
getWidth
(
this
.
flrLab
);
},
/**
* 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
();
}
return
;
}
/**
* Call the onStart callback if defined
*
* @returns {undefined}
*/
callOnStart
:
function
()
{
if
(
this
.
options
.
onStart
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onStart
();
});
}
},
if
(
which
===
'rzSliderHigh'
)
{
this
.
updateHighHandle
(
newOffset
);
this
.
updateSelectionBar
();
this
.
updateTicksScale
();
/**
* Call the onChange callback if defined
*
* @returns {undefined}
*/
callOnChange
:
function
()
{
if
(
this
.
options
.
onChange
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onChange
();
});
}
},
if
(
this
.
range
)
{
this
.
updateCmbLabel
();
}
return
;
}
/**
* Call the onEnd callback if defined
*
* @returns {undefined}
*/
callOnEnd
:
function
()
{
if
(
this
.
options
.
onEnd
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onEnd
();
});
}
},
// 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
.
setLeft
(
this
.
minH
,
newOffset
);
this
.
translateFn
(
this
.
scope
.
rzSliderModel
,
this
.
minLab
);
this
.
setLeft
(
this
.
minLab
,
newOffset
-
this
.
minLab
.
rzsw
/
2
+
this
.
handleHalfWidth
);
this
.
shFloorCeil
();
},
/**
* Update high slider handle position and label
*
* @param {number} newOffset
* @returns {undefined}
*/
updateHighHandle
:
function
(
newOffset
)
{
this
.
setLeft
(
this
.
maxH
,
newOffset
);
this
.
translateFn
(
this
.
scope
.
rzSliderHigh
,
this
.
maxLab
);
this
.
setLeft
(
this
.
maxLab
,
newOffset
-
this
.
maxLab
.
rzsw
/
2
+
this
.
handleHalfWidth
);
this
.
shFloorCeil
();
},
/**
* Show / hide floor / ceiling label
*
* @returns {undefined}
*/
shFloorCeil
:
function
()
{
var
flHidden
=
false
,
clHidden
=
false
;
if
(
this
.
minLab
.
rzsl
<=
this
.
flrLab
.
rzsl
+
this
.
flrLab
.
rzsw
+
5
)
{
flHidden
=
true
;
this
.
hideEl
(
this
.
flrLab
);
if
(
this
.
range
)
{
this
.
updateCmbLabel
();
}
else
{
flHidden
=
false
;
this
.
showEl
(
this
.
flrLab
);
return
;
}
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
.
setLeft
(
this
.
minH
,
newOffset
);
this
.
translateFn
(
this
.
scope
.
rzSliderModel
,
this
.
minLab
);
this
.
setLeft
(
this
.
minLab
,
newOffset
-
this
.
minLab
.
rzsw
/
2
+
this
.
handleHalfWidth
);
this
.
shFloorCeil
();
},
/**
* Update high slider handle position and label
*
* @param {number} newOffset
* @returns {undefined}
*/
updateHighHandle
:
function
(
newOffset
)
{
this
.
setLeft
(
this
.
maxH
,
newOffset
);
this
.
translateFn
(
this
.
scope
.
rzSliderHigh
,
this
.
maxLab
);
this
.
setLeft
(
this
.
maxLab
,
newOffset
-
this
.
maxLab
.
rzsw
/
2
+
this
.
handleHalfWidth
);
this
.
shFloorCeil
();
},
/**
* Show / hide floor / ceiling label
*
* @returns {undefined}
*/
shFloorCeil
:
function
()
{
var
flHidden
=
false
,
clHidden
=
false
;
if
(
this
.
minLab
.
rzsl
<=
this
.
flrLab
.
rzsl
+
this
.
flrLab
.
rzsw
+
5
)
{
flHidden
=
true
;
this
.
hideEl
(
this
.
flrLab
);
}
else
{
flHidden
=
false
;
this
.
showEl
(
this
.
flrLab
);
}
if
(
this
.
minLab
.
rzsl
+
this
.
minLab
.
rzsw
>=
this
.
ceilLab
.
rzsl
-
this
.
handleHalfWidth
-
10
)
{
clHidden
=
true
;
this
.
hideEl
(
this
.
ceilLab
);
}
else
{
clHidden
=
false
;
this
.
showEl
(
this
.
ceilLab
);
}
if
(
this
.
minLab
.
rzsl
+
this
.
minLab
.
rzsw
>=
this
.
ceilLab
.
rzsl
-
this
.
handleHalfWidth
-
10
)
{
clHidden
=
true
;
if
(
this
.
range
)
{
if
(
this
.
maxLab
.
rzsl
+
this
.
maxLab
.
rzsw
>=
this
.
ceilLab
.
rzsl
-
10
)
{
this
.
hideEl
(
this
.
ceilLab
);
}
else
{
clHidden
=
false
;
}
else
if
(
!
clHidden
)
{
this
.
showEl
(
this
.
ceilLab
);
}
if
(
this
.
range
)
{
if
(
this
.
maxLab
.
rzsl
+
this
.
maxLab
.
rzsw
>=
this
.
ceilLab
.
rzsl
-
10
)
{
this
.
hideEl
(
this
.
ceilLab
);
}
else
if
(
!
clHidden
)
{
this
.
showEl
(
this
.
ceilLab
);
}
// Hide or show floor label
if
(
this
.
maxLab
.
rzsl
<=
this
.
flrLab
.
rzsl
+
this
.
flrLab
.
rzsw
+
this
.
handleHalfWidth
)
{
this
.
hideEl
(
this
.
flrLab
);
}
else
if
(
!
flHidden
)
{
this
.
showEl
(
this
.
flrLab
);
}
// Hide or show floor label
if
(
this
.
maxLab
.
rzsl
<=
this
.
flrLab
.
rzsl
+
this
.
flrLab
.
rzsw
+
this
.
handleHalfWidth
)
{
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
.
setWidth
(
this
.
selBar
,
Math
.
abs
(
this
.
maxH
.
rzsl
-
this
.
minH
.
rzsl
)
+
this
.
handleHalfWidth
);
this
.
setLeft
(
this
.
selBar
,
this
.
range
?
this
.
minH
.
rzsl
+
this
.
handleHalfWidth
:
0
);
},
/**
* Update combined label position and value
*
* @returns {undefined}
*/
updateCmbLabel
:
function
()
{
var
lowTr
,
highTr
;
if
(
this
.
minLab
.
rzsl
+
this
.
minLab
.
rzsw
+
10
>=
this
.
maxLab
.
rzsl
)
{
lowTr
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderModel
);
highTr
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderHigh
);
this
.
translateFn
(
lowTr
+
' - '
+
highTr
,
this
.
cmbLab
,
false
);
this
.
setLeft
(
this
.
cmbLab
,
this
.
selBar
.
rzsl
+
this
.
selBar
.
rzsw
/
2
-
this
.
cmbLab
.
rzsw
/
2
);
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
.
setWidth
(
this
.
selBar
,
Math
.
abs
(
this
.
maxH
.
rzsl
-
this
.
minH
.
rzsl
)
+
this
.
handleHalfWidth
);
this
.
setLeft
(
this
.
selBar
,
this
.
range
?
this
.
minH
.
rzsl
+
this
.
handleHalfWidth
:
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
});
},
/**
* Show element
*
* @param element The jqLite wrapped DOM element
* @returns {jqLite} The jqLite
*/
showEl
:
function
(
element
)
{
if
(
!!
element
.
rzAlwaysHide
)
{
return
element
;
}
/**
* Update combined label position and value
*
* @returns {undefined}
*/
updateCmbLabel
:
function
()
{
var
lowTr
,
highTr
;
if
(
this
.
minLab
.
rzsl
+
this
.
minLab
.
rzsw
+
10
>=
this
.
maxLab
.
rzsl
)
{
lowTr
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderModel
);
highTr
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderHigh
);
this
.
translateFn
(
lowTr
+
' - '
+
highTr
,
this
.
cmbLab
,
false
);
this
.
setLeft
(
this
.
cmbLab
,
this
.
selBar
.
rzsl
+
this
.
selBar
.
rzsw
/
2
-
this
.
cmbLab
.
rzsw
/
2
);
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
);
}
},
return
element
.
css
({
opacity
:
1
});
},
/**
* 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
);
},
/**
* Set element left offset
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @param {number} left
* @returns {number}
*/
setLeft
:
function
(
elem
,
left
)
{
elem
.
rzsl
=
left
;
elem
.
css
({
left
:
left
+
'px'
});
return
left
;
},
/**
* Get element width
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @returns {number}
*/
getWidth
:
function
(
elem
)
{
var
val
=
elem
[
0
].
getBoundingClientRect
();
elem
.
rzsw
=
(
val
.
right
-
val
.
left
)
*
this
.
options
.
scale
;
return
elem
.
rzsw
;
},
/**
* Set element width
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @param {number} width
* @returns {number}
*/
setWidth
:
function
(
elem
,
width
)
{
elem
.
rzsw
=
width
;
elem
.
css
({
width
:
width
+
'px'
});
return
width
;
},
/**
* Translate value to pixel offset
*
* @param {number} val
* @returns {number}
*/
valueToOffset
:
function
(
val
)
{
return
(
this
.
sanitizeOffsetValue
(
val
)
-
this
.
minValue
)
*
this
.
maxLeft
/
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
.
maxLeft
)
*
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 of an event
*
* @param {Object} event The event
* @returns {number}
*/
getEventX
:
function
(
event
)
{
/* http://stackoverflow.com/a/12336075/282882 */
//noinspection JSLint
if
(
'clientX'
in
event
)
{
return
event
.
clientX
;
}
/**
* 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
].
clientX
:
event
.
originalEvent
.
touches
[
0
].
clientX
;
},
/**
* Show element
*
* @param element The jqLite wrapped DOM element
* @returns {jqLite} The jqLite
*/
showEl
:
function
(
element
)
{
if
(
!!
element
.
rzAlwaysHide
)
{
return
element
;
}
/**
* 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
.
getEventX
(
event
)
-
this
.
sliderElem
.
rzsl
-
this
.
handleHalfWidth
)
*
this
.
options
.
scale
;
return
Math
.
abs
(
offset
-
this
.
minH
.
rzsl
)
<
Math
.
abs
(
offset
-
this
.
maxH
.
rzsl
)
?
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 offset
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @param {number} left
* @returns {number}
*/
setLeft
:
function
(
elem
,
left
)
{
elem
.
rzsl
=
left
;
elem
.
css
({
left
:
left
+
'px'
});
return
left
;
},
event
.
stopPropagation
();
event
.
preventDefault
();
/**
* Get element width
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @returns {number}
*/
getWidth
:
function
(
elem
)
{
var
val
=
elem
[
0
].
getBoundingClientRect
();
elem
.
rzsw
=
(
val
.
right
-
val
.
left
)
*
this
.
options
.
scale
;
return
elem
.
rzsw
;
},
if
(
this
.
tracking
!==
''
)
{
return
;
}
/**
* Set element width
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @param {number} width
* @returns {number}
*/
setWidth
:
function
(
elem
,
width
)
{
elem
.
rzsw
=
width
;
elem
.
css
({
width
:
width
+
'px'
});
return
width
;
},
// 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
.
maxLeft
/
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
.
maxLeft
)
*
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 of an event
*
* @param {Object} event The event
* @returns {number}
*/
getEventX
:
function
(
event
)
{
/* http://stackoverflow.com/a/12336075/282882 */
//noinspection JSLint
if
(
'clientX'
in
event
)
{
return
event
.
clientX
;
}
/**
* onMove event handler
*
* @param {jqLite} pointer
* @param {Event} event The event
* @returns {undefined}
*/
onMove
:
function
(
pointer
,
event
)
{
var
eventX
=
this
.
getEventX
(
event
),
sliderLO
,
newOffset
,
newValue
;
sliderLO
=
this
.
sliderElem
.
rzsl
;
newOffset
=
(
eventX
-
sliderLO
-
this
.
handleHalfWidth
)
*
this
.
options
.
scale
;
if
(
newOffset
<=
0
)
{
if
(
pointer
.
rzsl
===
0
)
return
;
newValue
=
this
.
minValue
;
newOffset
=
0
;
}
else
if
(
newOffset
>=
this
.
maxLeft
)
{
if
(
pointer
.
rzsl
===
this
.
maxLeft
)
return
;
newValue
=
this
.
maxValue
;
newOffset
=
this
.
maxLeft
;
}
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
.
getEventX
(
event
)
-
this
.
sliderElem
.
rzsl
-
this
.
handleHalfWidth
;
this
.
dragging
=
{
active
:
true
,
value
:
this
.
offsetToValue
(
offset
),
difference
:
this
.
scope
.
rzSliderHigh
-
this
.
scope
.
rzSliderModel
,
offset
:
offset
,
lowDist
:
offset
-
this
.
minH
.
rzsl
,
highDist
:
this
.
maxH
.
rzsl
-
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
.
getEventX
(
event
)
-
this
.
sliderElem
.
rzsl
-
this
.
handleHalfWidth
,
newMinOffset
,
newMaxOffset
,
newMinValue
,
newMaxValue
;
if
(
newOffset
<=
this
.
dragging
.
lowDist
)
{
if
(
pointer
.
rzsl
===
this
.
dragging
.
lowDist
)
{
return
;
}
newMinValue
=
this
.
minValue
;
newMinOffset
=
0
;
newMaxValue
=
this
.
minValue
+
this
.
dragging
.
difference
;
newMaxOffset
=
this
.
valueToOffset
(
newMaxValue
);
}
else
if
(
newOffset
>=
this
.
maxLeft
-
this
.
dragging
.
highDist
)
{
if
(
pointer
.
rzsl
===
this
.
dragging
.
highDist
)
{
return
;
}
newMaxValue
=
this
.
maxValue
;
newMaxOffset
=
this
.
maxLeft
;
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
].
clientX
:
event
.
originalEvent
.
touches
[
0
].
clientX
;
},
this
.
positionTrackingBar
(
newMinValue
,
newMaxValue
,
newMinOffset
,
newMaxOffset
);
},
/**
* 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
.
getEventX
(
event
)
-
this
.
sliderElem
.
rzsl
-
this
.
handleHalfWidth
)
*
this
.
options
.
scale
;
return
Math
.
abs
(
offset
-
this
.
minH
.
rzsl
)
<
Math
.
abs
(
offset
-
this
.
maxH
.
rzsl
)
?
this
.
minH
:
this
.
maxH
;
},
/**
* 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
();
},
/**
* 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
;
}
/**
* 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
.
rzsl
);
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
.
rzsl
);
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
();
}
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
eventX
=
this
.
getEventX
(
event
),
sliderLO
,
newOffset
,
newValue
;
sliderLO
=
this
.
sliderElem
.
rzsl
;
newOffset
=
(
eventX
-
sliderLO
-
this
.
handleHalfWidth
)
*
this
.
options
.
scale
;
if
(
newOffset
<=
0
)
{
if
(
pointer
.
rzsl
===
0
)
return
;
newValue
=
this
.
minValue
;
newOffset
=
0
;
}
else
if
(
newOffset
>=
this
.
maxLeft
)
{
if
(
pointer
.
rzsl
===
this
.
maxLeft
)
return
;
newValue
=
this
.
maxValue
;
newOffset
=
this
.
maxLeft
;
}
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
.
getEventX
(
event
)
-
this
.
sliderElem
.
rzsl
-
this
.
handleHalfWidth
;
this
.
dragging
=
{
active
:
true
,
value
:
this
.
offsetToValue
(
offset
),
difference
:
this
.
scope
.
rzSliderHigh
-
this
.
scope
.
rzSliderModel
,
offset
:
offset
,
lowDist
:
offset
-
this
.
minH
.
rzsl
,
highDist
:
this
.
maxH
.
rzsl
-
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
.
getEventX
(
event
)
-
this
.
sliderElem
.
rzsl
-
this
.
handleHalfWidth
,
newMinOffset
,
newMaxOffset
,
newMinValue
,
newMaxValue
;
if
(
newOffset
<=
this
.
dragging
.
lowDist
)
{
if
(
pointer
.
rzsl
===
this
.
dragging
.
lowDist
)
{
return
;
}
newMinValue
=
this
.
minValue
;
newMinOffset
=
0
;
newMaxValue
=
this
.
minValue
+
this
.
dragging
.
difference
;
newMaxOffset
=
this
.
valueToOffset
(
newMaxValue
);
}
else
if
(
newOffset
>=
this
.
maxLeft
-
this
.
dragging
.
highDist
)
{
if
(
pointer
.
rzsl
===
this
.
dragging
.
highDist
)
{
return
;
}
newMaxValue
=
this
.
maxValue
;
newMaxOffset
=
this
.
maxLeft
;
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
.
rzsl
);
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
.
rzsl
);
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
();
}
},
$document
.
off
(
moveEventName
,
ehMove
);
/**
* 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
.
scope
.
$emit
(
'slideEnded
'
);
this
.
tracking
=
''
;
this
.
minH
.
removeClass
(
'rz-active
'
);
this
.
maxH
.
removeClass
(
'rz-active'
)
;
this
.
dragging
.
active
=
false
;
this
.
callOnEnd
();
},
$document
.
off
(
moveEventName
,
ehMove
);
/**
* 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
.
scope
.
$emit
(
'slideEnded'
);
this
.
tracking
=
''
;
if
(
event
.
touches
||
(
event
.
originalEvent
!==
undefined
&&
event
.
originalEvent
.
touches
))
{
eventNames
.
moveEvent
=
'touchmove'
;
eventNames
.
endEvent
=
'touchend'
;
}
else
{
eventNames
.
moveEvent
=
'mousemove'
;
eventNames
.
endEvent
=
'mouseup'
;
}
this
.
dragging
.
active
=
false
;
this
.
callOnEnd
();
},
return
eventNames
;
/**
* 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
:
''
};
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
:
'@'
},
// IDE assist
/**
* 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
/**
* @name ngScope
...
...
src/rzslider.js
View file @
d03ac54c
...
...
@@ -31,53 +31,53 @@
'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
,
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
(
'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
,
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
.
getOptions
=
function
(
options
)
{
return
angular
.
extend
({},
defaultOptions
,
globalOptions
,
options
);
};
factory
.
getOptions
=
function
(
options
)
{
return
angular
.
extend
({},
defaultOptions
,
globalOptions
,
options
);
};
return
factory
;
})
return
factory
;
})
.
value
(
'rzThrottle'
,
.
value
(
'rzThrottle'
,
/**
* rzThrottle
*
...
...
@@ -124,1242 +124,1238 @@
};
})
.
factory
(
'RzSlider'
,
function
(
$timeout
,
$document
,
$window
,
$compile
,
RzSliderOptions
,
rzThrottle
)
{
'use strict'
;
.
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
)
{
/**
*
Slider
*
The slider's scope
*
* @param {ngScope} scope The AngularJS scope
* @param {Element} sliderElem The slider directive element wrapped in jqLite
* @constructor
* @type {ngScope}
*/
var
Slider
=
function
(
scope
,
sliderElem
)
{
/**
* The slider's scope
*
* @type {ngScope}
*/
this
.
scope
=
scope
;
this
.
scope
=
scope
;
/**
* Slider element wrapped in jqLite
*
* @type {jqLite}
*/
this
.
sliderElem
=
sliderElem
;
/**
* Slider element wrapped in jqLite
*
* @type {jqLite}
*/
this
.
sliderElem
=
sliderElem
;
/**
* Slider type
*
* @type {boolean} Set to true for range slider
*/
this
.
range
=
this
.
scope
.
rzSliderModel
!==
undefined
&&
this
.
scope
.
rzSliderHigh
!==
undefined
;
/**
* Slider type
*
* @type {boolean} Set to true for range slider
*/
this
.
range
=
this
.
scope
.
rzSliderModel
!==
undefined
&&
this
.
scope
.
rzSliderHigh
!==
undefined
;
/**
* Values recorded when first dragging the bar
*
* @type {Object}
*/
this
.
dragging
=
{
active
:
false
,
value
:
0
,
difference
:
0
,
offset
:
0
,
lowDist
:
0
,
highDist
:
0
};
/**
* 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 of the slider handles
*
* @type {number}
*/
this
.
handleHalfWidth
=
0
;
/**
* Half of the width of the slider handles
*
* @type {number}
*/
this
.
handleHalfWidth
=
0
;
/**
* Maximum left the slider handle can have
*
* @type {number}
*/
this
.
maxLeft
=
0
;
/**
* Maximum left the slider handle can have
*
* @type {number}
*/
this
.
maxLeft
=
0
;
/**
* Precision
*
* @type {number}
*/
this
.
precision
=
0
;
/**
* Precision
*
* @type {number}
*/
this
.
precision
=
0
;
/**
* Step
*
* @type {number}
*/
this
.
step
=
0
;
/**
* Step
*
* @type {number}
*/
this
.
step
=
0
;
/**
* The name of the handle we are currently tracking
*
* @type {string}
*/
this
.
tracking
=
''
;
/**
* The name of the handle we are currently tracking
*
* @type {string}
*/
this
.
tracking
=
''
;
/**
* Minimum value (floor) of the model
*
* @type {number}
*/
this
.
minValue
=
0
;
/**
* Minimum value (floor) of the model
*
* @type {number}
*/
this
.
minValue
=
0
;
/**
* Maximum value (ceiling) of the model
*
* @type {number}
*/
this
.
maxValue
=
0
;
/**
* Maximum value (ceiling) of the model
*
* @type {number}
*/
this
.
maxValue
=
0
;
/**
* The delta between min and max value
*
* @type {number}
*/
this
.
valueRange
=
0
;
/**
* The delta between min and max value
*
* @type {number}
*/
this
.
valueRange
=
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
();
};
/**
* 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
=
{
// 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
();
});
// Recalculate slider view dimensions
this
.
scope
.
$on
(
'reCalcViewDimensions'
,
calcDimFn
);
// Recalculate stuff if view port dimensions have changed
angular
.
element
(
$window
).
on
(
'resize'
,
calcDimFn
);
this
.
initHasRun
=
true
;
// Watch for changes to the model
thrLow
=
rzThrottle
(
function
()
{
self
.
setMinAndMax
();
self
.
updateLowHandle
(
self
.
valueToOffset
(
self
.
scope
.
rzSliderModel
));
self
.
updateSelectionBar
();
self
.
updateTicksScale
();
if
(
self
.
range
)
{
self
.
updateCmbLabel
();
}
/**
* Initialize slider
*
* @returns {undefined}
*/
init
:
function
()
{
var
thrLow
,
thrHigh
,
calcDimFn
=
angular
.
bind
(
this
,
this
.
calcViewDimensions
),
self
=
this
;
this
.
applyOptions
();
this
.
initElemHandles
();
th
is
.
manageElementsStyle
();
this
.
addAccessibility
();
this
.
manageEventsBindings
();
this
.
setDisabledState
();
this
.
calcViewDimensions
();
this
.
setMinAndMax
(
);
},
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
();
th
rLow
();
if
(
self
.
range
)
{
thrHigh
();
}
self
.
resetSlider
();
}
);
$timeout
(
function
()
{
self
.
updateCeilLab
();
self
.
updateFloorLab
();
self
.
initHandles
()
;
self
.
bindEvents
();
});
// Watchers
this
.
scope
.
$watch
(
'rzSliderModel'
,
function
(
newValue
,
oldValue
)
{
if
(
newValue
===
oldValue
)
return
;
thrLow
();
});
// Recalculate slider view dimensions
this
.
scope
.
$on
(
'reCalcViewDimensions'
,
calcDimFn
);
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
();
}
});
// Recalculate stuff if view port dimensions have changed
angular
.
element
(
$window
).
on
(
'resize'
,
calcDimFn
);
this
.
scope
.
$watch
(
'rzSliderOptions'
,
function
(
newValue
,
oldValue
)
{
if
(
newValue
===
oldValue
)
return
;
self
.
applyOptions
();
self
.
resetSlider
();
},
true
);
this
.
initHasRun
=
true
;
this
.
scope
.
$on
(
'$destroy'
,
function
()
{
self
.
unbindEvents
();
angular
.
element
(
$window
).
off
(
'resize'
,
calcDimFn
);
});
},
// Watch for changes to the model
/**
* Read the user options and apply them to the slider model
*/
applyOptions
:
function
()
{
this
.
options
=
RzSliderOptions
.
getOptions
(
this
.
scope
.
rzSliderOptions
);
thrLow
=
rzThrottle
(
function
()
{
self
.
setMinAndMax
();
self
.
updateLowHandle
(
self
.
valueToOffset
(
self
.
scope
.
rzSliderModel
));
self
.
updateSelectionBar
();
self
.
updateTicksScale
();
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
(
self
.
range
)
{
self
.
updateCmbLabel
();
}
/**
* Resets slider
*
* @returns {undefined}
*/
resetSlider
:
function
()
{
this
.
manageElementsStyle
();
this
.
setMinAndMax
();
this
.
updateCeilLab
();
this
.
updateFloorLab
();
this
.
unbindEvents
();
this
.
manageEventsBindings
();
this
.
setDisabledState
();
this
.
calcViewDimensions
();
},
},
self
.
options
.
interval
);
/**
* 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
;
}
thrHigh
=
rzThrottle
(
function
()
{
self
.
setMinAndMax
();
self
.
updateHighHandle
(
self
.
valueToOffset
(
self
.
scope
.
rzSliderHigh
));
self
.
updateSelectionBar
();
self
.
updateTicksScale
();
self
.
updateCmbLabel
();
},
self
.
options
.
interval
);
},
this
);
this
.
scope
.
$on
(
'rzSliderForceRender'
,
function
()
{
self
.
resetLabelsValue
();
thrLow
();
if
(
self
.
range
)
{
thrHigh
();
}
self
.
resetSlider
();
});
// Initialize offset cache properties
this
.
selBar
.
rzsl
=
0
;
this
.
minH
.
rzsl
=
0
;
this
.
maxH
.
rzsl
=
0
;
this
.
flrLab
.
rzsl
=
0
;
this
.
ceilLab
.
rzsl
=
0
;
this
.
minLab
.
rzsl
=
0
;
this
.
maxLab
.
rzsl
=
0
;
this
.
cmbLab
.
rzsl
=
0
;
},
// Watchers
this
.
scope
.
$watch
(
'rzSliderModel'
,
function
(
newValue
,
oldValue
)
{
if
(
newValue
===
oldValue
)
return
;
thrLow
();
});
/** 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
)
},
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
();
}
});
/**
* 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
();
},
this
.
scope
.
$watch
(
'rzSliderOptions'
,
function
(
newValue
,
oldValue
)
{
if
(
newValue
===
oldValue
)
return
;
self
.
applyOptions
();
self
.
resetSlider
();
},
true
);
/**
* 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
);
}
},
this
.
scope
.
$on
(
'$destroy'
,
function
()
{
self
.
unbindEvents
();
angular
.
element
(
$window
).
off
(
'resize'
,
calcDimFn
);
});
},
/**
* Reset label values
*
* @return {undefined}
*/
resetLabelsValue
:
function
()
{
this
.
minLab
.
rzsv
=
undefined
;
this
.
maxLab
.
rzsv
=
undefined
;
},
/**
* 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
);
};
},
/**
* Resets slider
*
* @returns {undefined}
*/
resetSlider
:
function
()
{
this
.
manageElementsStyle
();
this
.
setMinAndMax
();
this
.
updateCeilLab
();
this
.
updateFloorLab
();
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
;
}
/**
* 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
));
},
this
);
// Initialize offset cache properties
this
.
selBar
.
rzsl
=
0
;
this
.
minH
.
rzsl
=
0
;
this
.
maxH
.
rzsl
=
0
;
this
.
flrLab
.
rzsl
=
0
;
this
.
ceilLab
.
rzsl
=
0
;
this
.
minLab
.
rzsl
=
0
;
this
.
maxLab
.
rzsl
=
0
;
this
.
cmbLab
.
rzsl
=
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}
/*
the order here is important since the selection bar should be
updated after the high handle but before the combined label
*/
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
);
}
},
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
;
},
/**
* 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
();
this
.
updateTicksScale
();
},
this
.
updateTicksScale
();
},
/**
* 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
;
/**
* 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
;
var
valStr
=
String
((
useCustomTr
?
this
.
customTrFn
(
value
,
this
.
options
.
id
)
:
value
)),
getWidth
=
false
;
var
valStr
=
String
((
useCustomTr
?
this
.
customTrFn
(
value
,
this
.
options
.
id
)
:
value
)),
getWidth
=
false
;
if
(
label
.
rzsv
===
undefined
||
label
.
rzsv
.
length
!==
valStr
.
length
||
(
label
.
rzsv
.
length
>
0
&&
label
.
rzsw
===
0
))
{
getWidth
=
true
;
label
.
rzsv
=
valStr
;
}
if
(
label
.
rzsv
===
undefined
||
label
.
rzsv
.
length
!==
valStr
.
length
||
(
label
.
rzsv
.
length
>
0
&&
label
.
rzsw
===
0
))
{
getWidth
=
true
;
label
.
rzsv
=
valStr
;
}
label
.
text
(
valStr
);
label
.
text
(
valStr
);
// Update width only when length of the label have changed
if
(
getWidth
)
{
this
.
getWidth
(
label
);
}
},
// Update width only when length of the label have changed
if
(
getWidth
)
{
this
.
getWidth
(
label
);
}
},
/**
* Set maximum and minimum values for the slider and ensure the model and high
* value match these limits
* @returns {undefined}
*/
setMinAndMax
:
function
()
{
/**
* Set maximum and minimum values for the slider and ensure the model and high
* value match these limits
* @returns {undefined}
*/
setMinAndMax
:
function
()
{
this
.
step
=
+
this
.
options
.
step
;
this
.
precision
=
+
this
.
options
.
precision
;
this
.
step
=
+
this
.
options
.
step
;
this
.
precision
=
+
this
.
options
.
precision
;
this
.
scope
.
rzSliderModel
=
this
.
roundStep
(
this
.
scope
.
rzSliderModel
);
if
(
this
.
range
)
this
.
scope
.
rzSliderHigh
=
this
.
roundStep
(
this
.
scope
.
rzSliderHigh
);
this
.
scope
.
rzSliderModel
=
this
.
roundStep
(
this
.
scope
.
rzSliderModel
);
if
(
this
.
range
)
this
.
scope
.
rzSliderHigh
=
this
.
roundStep
(
this
.
scope
.
rzSliderHigh
);
this
.
minValue
=
this
.
roundStep
(
+
this
.
options
.
floor
);
this
.
minValue
=
this
.
roundStep
(
+
this
.
options
.
floor
);
if
(
this
.
options
.
ceil
)
this
.
maxValue
=
this
.
roundStep
(
+
this
.
options
.
ceil
);
else
this
.
maxValue
=
this
.
options
.
ceil
=
this
.
range
?
this
.
scope
.
rzSliderHigh
:
this
.
scope
.
rzSliderModel
;
if
(
this
.
options
.
ceil
)
this
.
maxValue
=
this
.
roundStep
(
+
this
.
options
.
ceil
);
else
this
.
maxValue
=
this
.
options
.
ceil
=
this
.
range
?
this
.
scope
.
rzSliderHigh
:
this
.
scope
.
rzSliderModel
;
this
.
valueRange
=
this
.
maxValue
-
this
.
minValue
;
},
this
.
valueRange
=
this
.
maxValue
-
this
.
minValue
;
},
/**
* 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
.
getWidth
(
this
.
minH
);
/**
* Adds accessibility atributes
*
* Run only once during initialization
*
* @returns {undefined}
*/
addAccessibility
:
function
()
{
this
.
sliderElem
.
attr
(
"role"
,
"slider"
);
},
this
.
handleHalfWidth
=
handleWidth
/
2
;
this
.
barWidth
=
this
.
getWidth
(
this
.
fullBar
);
/**
* 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
.
getWidth
(
this
.
minH
);
this
.
maxLeft
=
this
.
barWidth
-
handleWidth
;
this
.
handleHalfWidth
=
handleWidth
/
2
;
this
.
barWidth
=
this
.
getWidth
(
this
.
fullBar
);
this
.
getWidth
(
this
.
sliderElem
);
this
.
sliderElem
.
rzsl
=
this
.
sliderElem
[
0
].
getBoundingClientRect
().
left
;
this
.
maxLeft
=
this
.
barWidth
-
handleWidth
;
if
(
this
.
initHasRun
)
{
this
.
updateFloorLab
();
this
.
updateCeilLab
();
this
.
initHandles
();
}
},
this
.
getWidth
(
this
.
sliderElem
);
this
.
sliderElem
.
rzsl
=
this
.
sliderElem
[
0
].
getBoundingClientRect
().
left
;
/**
* 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
)
+
'"'
;
}
positions
+=
'<span '
+
tooltip
+
' class="tick-value">'
+
this
.
getDisplayValue
(
value
)
+
'</span>'
;
if
(
this
.
initHasRun
)
{
this
.
updateFloorLab
();
this
.
updateCeilLab
();
this
.
initHandles
();
}
},
/**
* 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
)
+
'"'
;
}
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
.
setLeft
(
this
.
ceilLab
,
this
.
barWidth
-
this
.
ceilLab
.
rzsw
);
this
.
getWidth
(
this
.
ceilLab
);
},
/**
* Update position of the floor label
*
* @returns {undefined}
*/
updateFloorLab
:
function
()
{
this
.
translateFn
(
this
.
minValue
,
this
.
flrLab
);
this
.
getWidth
(
this
.
flrLab
);
},
/**
* Call the onStart callback if defined
*
* @returns {undefined}
*/
callOnStart
:
function
()
{
if
(
this
.
options
.
onStart
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onStart
();
});
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
;
},
/**
* Call the onChange callback if defined
*
* @returns {undefined}
*/
callOnChange
:
function
()
{
if
(
this
.
options
.
onChange
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onChange
();
});
}
},
/**
* Update position of the ceiling label
*
* @returns {undefined}
*/
updateCeilLab
:
function
()
{
this
.
translateFn
(
this
.
maxValue
,
this
.
ceilLab
);
this
.
setLeft
(
this
.
ceilLab
,
this
.
barWidth
-
this
.
ceilLab
.
rzsw
);
this
.
getWidth
(
this
.
ceilLab
);
},
/**
* Call the onEnd callback if defined
*
* @returns {undefined}
*/
callOnEnd
:
function
()
{
if
(
this
.
options
.
onEnd
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onEnd
();
});
}
},
/**
* Update position of the floor label
*
* @returns {undefined}
*/
updateFloorLab
:
function
()
{
this
.
translateFn
(
this
.
minValue
,
this
.
flrLab
);
this
.
getWidth
(
this
.
flrLab
);
},
/**
* 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
();
}
return
;
}
/**
* Call the onStart callback if defined
*
* @returns {undefined}
*/
callOnStart
:
function
()
{
if
(
this
.
options
.
onStart
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onStart
();
});
}
},
if
(
which
===
'rzSliderHigh'
)
{
this
.
updateHighHandle
(
newOffset
);
this
.
updateSelectionBar
();
this
.
updateTicksScale
();
/**
* Call the onChange callback if defined
*
* @returns {undefined}
*/
callOnChange
:
function
()
{
if
(
this
.
options
.
onChange
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onChange
();
});
}
},
if
(
this
.
range
)
{
this
.
updateCmbLabel
();
}
return
;
}
/**
* Call the onEnd callback if defined
*
* @returns {undefined}
*/
callOnEnd
:
function
()
{
if
(
this
.
options
.
onEnd
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onEnd
();
});
}
},
// 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
.
setLeft
(
this
.
minH
,
newOffset
);
this
.
translateFn
(
this
.
scope
.
rzSliderModel
,
this
.
minLab
);
this
.
setLeft
(
this
.
minLab
,
newOffset
-
this
.
minLab
.
rzsw
/
2
+
this
.
handleHalfWidth
);
this
.
shFloorCeil
();
},
/**
* Update high slider handle position and label
*
* @param {number} newOffset
* @returns {undefined}
*/
updateHighHandle
:
function
(
newOffset
)
{
this
.
setLeft
(
this
.
maxH
,
newOffset
);
this
.
translateFn
(
this
.
scope
.
rzSliderHigh
,
this
.
maxLab
);
this
.
setLeft
(
this
.
maxLab
,
newOffset
-
this
.
maxLab
.
rzsw
/
2
+
this
.
handleHalfWidth
);
this
.
shFloorCeil
();
},
/**
* Show / hide floor / ceiling label
*
* @returns {undefined}
*/
shFloorCeil
:
function
()
{
var
flHidden
=
false
,
clHidden
=
false
;
if
(
this
.
minLab
.
rzsl
<=
this
.
flrLab
.
rzsl
+
this
.
flrLab
.
rzsw
+
5
)
{
flHidden
=
true
;
this
.
hideEl
(
this
.
flrLab
);
if
(
this
.
range
)
{
this
.
updateCmbLabel
();
}
else
{
flHidden
=
false
;
this
.
showEl
(
this
.
flrLab
);
return
;
}
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
.
setLeft
(
this
.
minH
,
newOffset
);
this
.
translateFn
(
this
.
scope
.
rzSliderModel
,
this
.
minLab
);
this
.
setLeft
(
this
.
minLab
,
newOffset
-
this
.
minLab
.
rzsw
/
2
+
this
.
handleHalfWidth
);
this
.
shFloorCeil
();
},
/**
* Update high slider handle position and label
*
* @param {number} newOffset
* @returns {undefined}
*/
updateHighHandle
:
function
(
newOffset
)
{
this
.
setLeft
(
this
.
maxH
,
newOffset
);
this
.
translateFn
(
this
.
scope
.
rzSliderHigh
,
this
.
maxLab
);
this
.
setLeft
(
this
.
maxLab
,
newOffset
-
this
.
maxLab
.
rzsw
/
2
+
this
.
handleHalfWidth
);
this
.
shFloorCeil
();
},
/**
* Show / hide floor / ceiling label
*
* @returns {undefined}
*/
shFloorCeil
:
function
()
{
var
flHidden
=
false
,
clHidden
=
false
;
if
(
this
.
minLab
.
rzsl
<=
this
.
flrLab
.
rzsl
+
this
.
flrLab
.
rzsw
+
5
)
{
flHidden
=
true
;
this
.
hideEl
(
this
.
flrLab
);
}
else
{
flHidden
=
false
;
this
.
showEl
(
this
.
flrLab
);
}
if
(
this
.
minLab
.
rzsl
+
this
.
minLab
.
rzsw
>=
this
.
ceilLab
.
rzsl
-
this
.
handleHalfWidth
-
10
)
{
clHidden
=
true
;
if
(
this
.
minLab
.
rzsl
+
this
.
minLab
.
rzsw
>=
this
.
ceilLab
.
rzsl
-
this
.
handleHalfWidth
-
10
)
{
clHidden
=
true
;
this
.
hideEl
(
this
.
ceilLab
);
}
else
{
clHidden
=
false
;
this
.
showEl
(
this
.
ceilLab
);
}
if
(
this
.
range
)
{
if
(
this
.
maxLab
.
rzsl
+
this
.
maxLab
.
rzsw
>=
this
.
ceilLab
.
rzsl
-
10
)
{
this
.
hideEl
(
this
.
ceilLab
);
}
else
{
clHidden
=
false
;
}
else
if
(
!
clHidden
)
{
this
.
showEl
(
this
.
ceilLab
);
}
if
(
this
.
range
)
{
if
(
this
.
maxLab
.
rzsl
+
this
.
maxLab
.
rzsw
>=
this
.
ceilLab
.
rzsl
-
10
)
{
this
.
hideEl
(
this
.
ceilLab
);
}
else
if
(
!
clHidden
)
{
this
.
showEl
(
this
.
ceilLab
);
}
// Hide or show floor label
if
(
this
.
maxLab
.
rzsl
<=
this
.
flrLab
.
rzsl
+
this
.
flrLab
.
rzsw
+
this
.
handleHalfWidth
)
{
this
.
hideEl
(
this
.
flrLab
);
}
else
if
(
!
flHidden
)
{
this
.
showEl
(
this
.
flrLab
);
}
// Hide or show floor label
if
(
this
.
maxLab
.
rzsl
<=
this
.
flrLab
.
rzsl
+
this
.
flrLab
.
rzsw
+
this
.
handleHalfWidth
)
{
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
.
setWidth
(
this
.
selBar
,
Math
.
abs
(
this
.
maxH
.
rzsl
-
this
.
minH
.
rzsl
)
+
this
.
handleHalfWidth
);
this
.
setLeft
(
this
.
selBar
,
this
.
range
?
this
.
minH
.
rzsl
+
this
.
handleHalfWidth
:
0
);
},
/**
* Update combined label position and value
*
* @returns {undefined}
*/
updateCmbLabel
:
function
()
{
var
lowTr
,
highTr
;
if
(
this
.
minLab
.
rzsl
+
this
.
minLab
.
rzsw
+
10
>=
this
.
maxLab
.
rzsl
)
{
lowTr
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderModel
);
highTr
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderHigh
);
this
.
translateFn
(
lowTr
+
' - '
+
highTr
,
this
.
cmbLab
,
false
);
this
.
setLeft
(
this
.
cmbLab
,
this
.
selBar
.
rzsl
+
this
.
selBar
.
rzsw
/
2
-
this
.
cmbLab
.
rzsw
/
2
);
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
.
setWidth
(
this
.
selBar
,
Math
.
abs
(
this
.
maxH
.
rzsl
-
this
.
minH
.
rzsl
)
+
this
.
handleHalfWidth
);
this
.
setLeft
(
this
.
selBar
,
this
.
range
?
this
.
minH
.
rzsl
+
this
.
handleHalfWidth
:
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
});
},
/**
* Show element
*
* @param element The jqLite wrapped DOM element
* @returns {jqLite} The jqLite
*/
showEl
:
function
(
element
)
{
if
(
!!
element
.
rzAlwaysHide
)
{
return
element
;
}
/**
* Update combined label position and value
*
* @returns {undefined}
*/
updateCmbLabel
:
function
()
{
var
lowTr
,
highTr
;
if
(
this
.
minLab
.
rzsl
+
this
.
minLab
.
rzsw
+
10
>=
this
.
maxLab
.
rzsl
)
{
lowTr
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderModel
);
highTr
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderHigh
);
this
.
translateFn
(
lowTr
+
' - '
+
highTr
,
this
.
cmbLab
,
false
);
this
.
setLeft
(
this
.
cmbLab
,
this
.
selBar
.
rzsl
+
this
.
selBar
.
rzsw
/
2
-
this
.
cmbLab
.
rzsw
/
2
);
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
);
}
},
return
element
.
css
({
opacity
:
1
});
},
/**
* 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
);
},
/**
* Set element left offset
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @param {number} left
* @returns {number}
*/
setLeft
:
function
(
elem
,
left
)
{
elem
.
rzsl
=
left
;
elem
.
css
({
left
:
left
+
'px'
});
return
left
;
},
/**
* Get element width
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @returns {number}
*/
getWidth
:
function
(
elem
)
{
var
val
=
elem
[
0
].
getBoundingClientRect
();
elem
.
rzsw
=
(
val
.
right
-
val
.
left
)
*
this
.
options
.
scale
;
return
elem
.
rzsw
;
},
/**
* Set element width
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @param {number} width
* @returns {number}
*/
setWidth
:
function
(
elem
,
width
)
{
elem
.
rzsw
=
width
;
elem
.
css
({
width
:
width
+
'px'
});
return
width
;
},
/**
* Translate value to pixel offset
*
* @param {number} val
* @returns {number}
*/
valueToOffset
:
function
(
val
)
{
return
(
this
.
sanitizeOffsetValue
(
val
)
-
this
.
minValue
)
*
this
.
maxLeft
/
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
.
maxLeft
)
*
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 of an event
*
* @param {Object} event The event
* @returns {number}
*/
getEventX
:
function
(
event
)
{
/* http://stackoverflow.com/a/12336075/282882 */
//noinspection JSLint
if
(
'clientX'
in
event
)
{
return
event
.
clientX
;
}
/**
* 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
].
clientX
:
event
.
originalEvent
.
touches
[
0
].
clientX
;
},
/**
* Show element
*
* @param element The jqLite wrapped DOM element
* @returns {jqLite} The jqLite
*/
showEl
:
function
(
element
)
{
if
(
!!
element
.
rzAlwaysHide
)
{
return
element
;
}
/**
* 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
.
getEventX
(
event
)
-
this
.
sliderElem
.
rzsl
-
this
.
handleHalfWidth
)
*
this
.
options
.
scale
;
return
Math
.
abs
(
offset
-
this
.
minH
.
rzsl
)
<
Math
.
abs
(
offset
-
this
.
maxH
.
rzsl
)
?
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 offset
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @param {number} left
* @returns {number}
*/
setLeft
:
function
(
elem
,
left
)
{
elem
.
rzsl
=
left
;
elem
.
css
({
left
:
left
+
'px'
});
return
left
;
},
event
.
stopPropagation
();
event
.
preventDefault
();
/**
* Get element width
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @returns {number}
*/
getWidth
:
function
(
elem
)
{
var
val
=
elem
[
0
].
getBoundingClientRect
();
elem
.
rzsw
=
(
val
.
right
-
val
.
left
)
*
this
.
options
.
scale
;
return
elem
.
rzsw
;
},
if
(
this
.
tracking
!==
''
)
{
return
;
}
/**
* Set element width
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @param {number} width
* @returns {number}
*/
setWidth
:
function
(
elem
,
width
)
{
elem
.
rzsw
=
width
;
elem
.
css
({
width
:
width
+
'px'
});
return
width
;
},
// 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
.
maxLeft
/
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
.
maxLeft
)
*
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 of an event
*
* @param {Object} event The event
* @returns {number}
*/
getEventX
:
function
(
event
)
{
/* http://stackoverflow.com/a/12336075/282882 */
//noinspection JSLint
if
(
'clientX'
in
event
)
{
return
event
.
clientX
;
}
/**
* onMove event handler
*
* @param {jqLite} pointer
* @param {Event} event The event
* @returns {undefined}
*/
onMove
:
function
(
pointer
,
event
)
{
var
eventX
=
this
.
getEventX
(
event
),
sliderLO
,
newOffset
,
newValue
;
sliderLO
=
this
.
sliderElem
.
rzsl
;
newOffset
=
(
eventX
-
sliderLO
-
this
.
handleHalfWidth
)
*
this
.
options
.
scale
;
if
(
newOffset
<=
0
)
{
if
(
pointer
.
rzsl
===
0
)
return
;
newValue
=
this
.
minValue
;
newOffset
=
0
;
}
else
if
(
newOffset
>=
this
.
maxLeft
)
{
if
(
pointer
.
rzsl
===
this
.
maxLeft
)
return
;
newValue
=
this
.
maxValue
;
newOffset
=
this
.
maxLeft
;
}
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
.
getEventX
(
event
)
-
this
.
sliderElem
.
rzsl
-
this
.
handleHalfWidth
;
this
.
dragging
=
{
active
:
true
,
value
:
this
.
offsetToValue
(
offset
),
difference
:
this
.
scope
.
rzSliderHigh
-
this
.
scope
.
rzSliderModel
,
offset
:
offset
,
lowDist
:
offset
-
this
.
minH
.
rzsl
,
highDist
:
this
.
maxH
.
rzsl
-
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
.
getEventX
(
event
)
-
this
.
sliderElem
.
rzsl
-
this
.
handleHalfWidth
,
newMinOffset
,
newMaxOffset
,
newMinValue
,
newMaxValue
;
if
(
newOffset
<=
this
.
dragging
.
lowDist
)
{
if
(
pointer
.
rzsl
===
this
.
dragging
.
lowDist
)
{
return
;
}
newMinValue
=
this
.
minValue
;
newMinOffset
=
0
;
newMaxValue
=
this
.
minValue
+
this
.
dragging
.
difference
;
newMaxOffset
=
this
.
valueToOffset
(
newMaxValue
);
}
else
if
(
newOffset
>=
this
.
maxLeft
-
this
.
dragging
.
highDist
)
{
if
(
pointer
.
rzsl
===
this
.
dragging
.
highDist
)
{
return
;
}
newMaxValue
=
this
.
maxValue
;
newMaxOffset
=
this
.
maxLeft
;
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
].
clientX
:
event
.
originalEvent
.
touches
[
0
].
clientX
;
},
this
.
positionTrackingBar
(
newMinValue
,
newMaxValue
,
newMinOffset
,
newMaxOffset
);
},
/**
* 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
.
getEventX
(
event
)
-
this
.
sliderElem
.
rzsl
-
this
.
handleHalfWidth
)
*
this
.
options
.
scale
;
return
Math
.
abs
(
offset
-
this
.
minH
.
rzsl
)
<
Math
.
abs
(
offset
-
this
.
maxH
.
rzsl
)
?
this
.
minH
:
this
.
maxH
;
},
/**
* 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
();
},
/**
* 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
;
}
/**
* 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
.
rzsl
);
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
.
rzsl
);
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
();
}
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
eventX
=
this
.
getEventX
(
event
),
sliderLO
,
newOffset
,
newValue
;
sliderLO
=
this
.
sliderElem
.
rzsl
;
newOffset
=
(
eventX
-
sliderLO
-
this
.
handleHalfWidth
)
*
this
.
options
.
scale
;
if
(
newOffset
<=
0
)
{
if
(
pointer
.
rzsl
===
0
)
return
;
newValue
=
this
.
minValue
;
newOffset
=
0
;
}
else
if
(
newOffset
>=
this
.
maxLeft
)
{
if
(
pointer
.
rzsl
===
this
.
maxLeft
)
return
;
newValue
=
this
.
maxValue
;
newOffset
=
this
.
maxLeft
;
}
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
.
getEventX
(
event
)
-
this
.
sliderElem
.
rzsl
-
this
.
handleHalfWidth
;
this
.
dragging
=
{
active
:
true
,
value
:
this
.
offsetToValue
(
offset
),
difference
:
this
.
scope
.
rzSliderHigh
-
this
.
scope
.
rzSliderModel
,
offset
:
offset
,
lowDist
:
offset
-
this
.
minH
.
rzsl
,
highDist
:
this
.
maxH
.
rzsl
-
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
.
getEventX
(
event
)
-
this
.
sliderElem
.
rzsl
-
this
.
handleHalfWidth
,
newMinOffset
,
newMaxOffset
,
newMinValue
,
newMaxValue
;
if
(
newOffset
<=
this
.
dragging
.
lowDist
)
{
if
(
pointer
.
rzsl
===
this
.
dragging
.
lowDist
)
{
return
;
}
newMinValue
=
this
.
minValue
;
newMinOffset
=
0
;
newMaxValue
=
this
.
minValue
+
this
.
dragging
.
difference
;
newMaxOffset
=
this
.
valueToOffset
(
newMaxValue
);
}
else
if
(
newOffset
>=
this
.
maxLeft
-
this
.
dragging
.
highDist
)
{
if
(
pointer
.
rzsl
===
this
.
dragging
.
highDist
)
{
return
;
}
newMaxValue
=
this
.
maxValue
;
newMaxOffset
=
this
.
maxLeft
;
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
.
rzsl
);
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
.
rzsl
);
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
();
}
},
$document
.
off
(
moveEventName
,
ehMove
);
/**
* 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
.
scope
.
$emit
(
'slideEnded
'
);
this
.
tracking
=
''
;
this
.
minH
.
removeClass
(
'rz-active
'
);
this
.
maxH
.
removeClass
(
'rz-active'
)
;
this
.
dragging
.
active
=
false
;
this
.
callOnEnd
();
},
$document
.
off
(
moveEventName
,
ehMove
);
/**
* 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
.
scope
.
$emit
(
'slideEnded'
);
this
.
tracking
=
''
;
if
(
event
.
touches
||
(
event
.
originalEvent
!==
undefined
&&
event
.
originalEvent
.
touches
))
{
eventNames
.
moveEvent
=
'touchmove'
;
eventNames
.
endEvent
=
'touchend'
;
}
else
{
eventNames
.
moveEvent
=
'mousemove'
;
eventNames
.
endEvent
=
'mouseup'
;
}
this
.
dragging
.
active
=
false
;
this
.
callOnEnd
();
},
return
eventNames
;
/**
* 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
:
''
};
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
:
'@'
},
// IDE assist
/**
* 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
/**
* @name ngScope
...
...
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