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
)
{
module
.
exports
=
function
(
grunt
)
{
// Project configuration.
// Project configuration.
grunt
.
initConfig
({
grunt
.
initConfig
({
pkg
:
grunt
.
file
.
readJSON
(
'package.json'
),
pkg
:
grunt
.
file
.
readJSON
(
'package.json'
),
minBanner
:
'/*! <%= pkg.name %> - v<%= pkg.version %> - '
+
minBanner
:
'/*! <%= pkg.name %> - v<%= pkg.version %> - '
+
'(c) <%= pkg.author %>, <%= pkg.repository.url %> - '
+
'(c) <%= pkg.author %>, <%= pkg.repository.url %> - '
+
'<%= grunt.template.today("yyyy-mm-dd") %> */
\
n'
,
'<%= grunt.template.today("yyyy-mm-dd") %> */
\
n'
,
recess
:
{
recess
:
{
options
:
{
options
:
{
compile
:
true
compile
:
true
},
},
slider
:
{
slider
:
{
src
:
[
'src/rzslider.less'
],
src
:
[
'src/rzslider.less'
],
dest
:
'dist/rzslider.css'
dest
:
'dist/rzslider.css'
},
},
min
:
{
min
:
{
options
:
{
options
:
{
compress
:
true
,
compress
:
true
,
banner
:
'<%= minBanner %>'
banner
:
'<%= minBanner %>'
},
src
:
[
'dist/rzslider.css'
],
dest
:
'dist/rzslider.min.css'
}
},
},
src
:
[
'dist/rzslider.css'
],
dest
:
'dist/rzslider.min.css'
}
},
uglify
:
{
uglify
:
{
options
:
{
options
:
{
report
:
'min'
,
report
:
'min'
,
banner
:
'<%= minBanner %>'
banner
:
'<%= minBanner %>'
},
},
rzslider
:
{
rzslider
:
{
files
:
{
files
:
{
'dist/rzslider.min.js'
:
[
'dist/rzslider.min.js'
:
[
'dist/rzslider.js'
'dist/rzslider.js'
]
]
}
}
}
}
},
},
ngtemplates
:
{
ngtemplates
:
{
app
:
{
app
:
{
src
:
'src/**.html'
,
src
:
'src/**.html'
,
dest
:
'temp/templates.js'
,
dest
:
'temp/templates.js'
,
options
:
{
options
:
{
htmlmin
:
{
htmlmin
:
{
collapseBooleanAttributes
:
true
,
collapseBooleanAttributes
:
true
,
collapseWhitespace
:
true
,
collapseWhitespace
:
true
,
removeAttributeQuotes
:
true
,
removeAttributeQuotes
:
true
,
removeComments
:
true
,
// Only if you don't use comment directives!
removeComments
:
true
,
// Only if you don't use comment directives!
removeEmptyAttributes
:
true
,
removeEmptyAttributes
:
true
,
removeRedundantAttributes
:
true
,
removeRedundantAttributes
:
true
,
removeScriptTypeAttributes
:
true
,
removeScriptTypeAttributes
:
true
,
removeStyleLinkTypeAttributes
:
true
removeStyleLinkTypeAttributes
:
true
},
},
module
:
'rzModule'
,
module
:
'rzModule'
,
url
:
function
(
url
)
{
url
:
function
(
url
)
{
return
url
.
replace
(
'src/'
,
''
);
return
url
.
replace
(
'src/'
,
''
);
},
},
bootstrap
:
function
(
module
,
script
)
{
bootstrap
:
function
(
module
,
script
)
{
return
'module.run(function($templateCache) {
\
n'
+
script
+
'
\
n});'
;
return
'module.run(function($templateCache) {
\
n'
+
script
+
'
\
n});'
;
}
}
}
}
}
}
},
},
replace
:
{
replace
:
{
dist
:
{
dist
:
{
options
:
{
options
:
{
patterns
:
[
patterns
:
[{
{
match
:
/
\/\*
templateReplacement
\*\/
/
,
match
:
/
\/\*
templateReplacement
\*\/
/
,
replacement
:
'<%= grunt.file.read("temp/templates.js") %>'
replacement
:
'<%= grunt.file.read("temp/templates.js") %>'
}]
}
]
},
files
:
[
{
expand
:
true
,
flatten
:
true
,
src
:
[
'src/rzslider.js'
],
dest
:
'dist/'
}
]
}
},
},
files
:
[{
expand
:
true
,
flatten
:
true
,
src
:
[
'src/rzslider.js'
],
dest
:
'dist/'
}]
}
},
ngAnnotate
:
{
ngAnnotate
:
{
options
:
{
options
:
{
singleQuotes
:
true
,
singleQuotes
:
true
,
},
},
rzslider
:
{
rzslider
:
{
files
:
[{
files
:
[{
'dist/rzslider.js'
:
'dist/rzslider.js'
'dist/rzslider.js'
:
'dist/rzslider.js'
},
{
},
{
expand
:
true
,
expand
:
true
,
src
:
[
'dist/rzslider.js'
]
src
:
[
'dist/rzslider.js'
]
}
}]
]
}
}
},
},
watch
:
{
watch
:
{
all
:
{
all
:
{
files
:
[
'dist/*'
,
'demo/*'
],
files
:
[
'dist/*'
,
'demo/*'
],
options
:
{
options
:
{
livereload
:
true
livereload
:
true
}
},
js
:
{
files
:
[
'src/*js'
,
'src/*.html'
],
tasks
:
[
'js'
]
},
less
:
{
files
:
[
'src/*.less'
],
tasks
:
[
'css'
]
}
},
serve
:
{
options
:
{
port
:
9000
}
}
}
},
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-contrib-uglify'
);
grunt
.
loadNpmTasks
(
'grunt-recess'
);
grunt
.
loadNpmTasks
(
'grunt-recess'
);
grunt
.
loadNpmTasks
(
'grunt-angular-templates'
);
grunt
.
loadNpmTasks
(
'grunt-angular-templates'
);
grunt
.
loadNpmTasks
(
'grunt-replace'
);
grunt
.
loadNpmTasks
(
'grunt-replace'
);
grunt
.
loadNpmTasks
(
'grunt-ng-annotate'
);
grunt
.
loadNpmTasks
(
'grunt-ng-annotate'
);
grunt
.
loadNpmTasks
(
'grunt-contrib-watch'
);
grunt
.
loadNpmTasks
(
'grunt-contrib-watch'
);
grunt
.
loadNpmTasks
(
'grunt-serve'
);
grunt
.
loadNpmTasks
(
'grunt-serve'
);
grunt
.
registerTask
(
'default'
,
[
'css'
,
'js'
]);
grunt
.
registerTask
(
'default'
,
[
'css'
,
'js'
]);
grunt
.
registerTask
(
'css'
,
[
'recess'
]);
grunt
.
registerTask
(
'css'
,
[
'recess'
]);
grunt
.
registerTask
(
'js'
,
[
'ngtemplates'
,
'replace'
,
'ngAnnotate'
,
'uglify'
]);
grunt
.
registerTask
(
'js'
,
[
'ngtemplates'
,
'replace'
,
'ngAnnotate'
,
'uglify'
]);
};
};
dist/rzslider.js
View file @
d03ac54c
...
@@ -31,53 +31,53 @@
...
@@ -31,53 +31,53 @@
'use strict'
;
'use strict'
;
var
module
=
angular
.
module
(
'rzModule'
,
[])
var
module
=
angular
.
module
(
'rzModule'
,
[])
.
factory
(
'RzSliderOptions'
,
function
()
{
.
factory
(
'RzSliderOptions'
,
function
()
{
var
defaultOptions
=
{
var
defaultOptions
=
{
floor
:
0
,
floor
:
0
,
ceil
:
null
,
//defaults to rz-slider-model
ceil
:
null
,
//defaults to rz-slider-model
step
:
1
,
step
:
1
,
precision
:
0
,
precision
:
0
,
id
:
null
,
id
:
null
,
translate
:
null
,
translate
:
null
,
stepsArray
:
null
,
stepsArray
:
null
,
draggableRange
:
false
,
draggableRange
:
false
,
showSelectionBar
:
false
,
showSelectionBar
:
false
,
hideLimitLabels
:
false
,
hideLimitLabels
:
false
,
readOnly
:
false
,
readOnly
:
false
,
disabled
:
false
,
disabled
:
false
,
interval
:
350
,
interval
:
350
,
showTicks
:
false
,
showTicks
:
false
,
showTicksValues
:
false
,
showTicksValues
:
false
,
ticksValuesTooltip
:
null
,
ticksValuesTooltip
:
null
,
scale
:
1
,
scale
:
1
,
onStart
:
null
,
onStart
:
null
,
onChange
:
null
,
onChange
:
null
,
onEnd
:
null
onEnd
:
null
};
};
var
globalOptions
=
{};
var
globalOptions
=
{};
var
factory
=
{};
var
factory
=
{};
/**
/**
* `options({})` allows global configuration of all sliders in the
* `options({})` allows global configuration of all sliders in the
* application.
* application.
*
*
* var app = angular.module( 'App', ['rzModule'], function( RzSliderOptions ) {
* var app = angular.module( 'App', ['rzModule'], function( RzSliderOptions ) {
* // show ticks for all sliders
* // show ticks for all sliders
* RzSliderOptions.options( { showTicks: true } );
* RzSliderOptions.options( { showTicks: true } );
* });
* });
*/
*/
factory
.
options
=
function
(
value
)
{
factory
.
options
=
function
(
value
)
{
angular
.
extend
(
globalOptions
,
value
);
angular
.
extend
(
globalOptions
,
value
);
};
};
factory
.
getOptions
=
function
(
options
)
{
factory
.
getOptions
=
function
(
options
)
{
return
angular
.
extend
({},
defaultOptions
,
globalOptions
,
options
);
return
angular
.
extend
({},
defaultOptions
,
globalOptions
,
options
);
};
};
return
factory
;
return
factory
;
})
})
.
value
(
'rzThrottle'
,
.
value
(
'rzThrottle'
,
/**
/**
* rzThrottle
* rzThrottle
*
*
...
@@ -124,1242 +124,1238 @@
...
@@ -124,1242 +124,1238 @@
};
};
})
})
.
factory
(
'RzSlider'
,
[
'$timeout'
,
'$document'
,
'$window'
,
'$compile'
,
'RzSliderOptions'
,
'rzThrottle'
,
function
(
$timeout
,
$document
,
$window
,
$compile
,
RzSliderOptions
,
rzThrottle
)
{
.
factory
(
'RzSlider'
,
[
'$timeout'
,
'$document'
,
'$window'
,
'$compile'
,
'RzSliderOptions'
,
'rzThrottle'
,
function
(
$timeout
,
$document
,
$window
,
$compile
,
RzSliderOptions
,
rzThrottle
)
{
'use strict'
;
'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
* @type {ngScope}
* @param {Element} sliderElem The slider directive element wrapped in jqLite
* @constructor
*/
*/
var
Slider
=
function
(
scope
,
sliderElem
)
{
this
.
scope
=
scope
;
/**
* The slider's scope
*
* @type {ngScope}
*/
this
.
scope
=
scope
;
/**
/**
* Slider element wrapped in jqLite
* Slider element wrapped in jqLite
*
*
* @type {jqLite}
* @type {jqLite}
*/
*/
this
.
sliderElem
=
sliderElem
;
this
.
sliderElem
=
sliderElem
;
/**
/**
* Slider type
* Slider type
*
*
* @type {boolean} Set to true for range slider
* @type {boolean} Set to true for range slider
*/
*/
this
.
range
=
this
.
scope
.
rzSliderModel
!==
undefined
&&
this
.
scope
.
rzSliderHigh
!==
undefined
;
this
.
range
=
this
.
scope
.
rzSliderModel
!==
undefined
&&
this
.
scope
.
rzSliderHigh
!==
undefined
;
/**
/**
* Values recorded when first dragging the bar
* Values recorded when first dragging the bar
*
*
* @type {Object}
* @type {Object}
*/
*/
this
.
dragging
=
{
this
.
dragging
=
{
active
:
false
,
active
:
false
,
value
:
0
,
value
:
0
,
difference
:
0
,
difference
:
0
,
offset
:
0
,
offset
:
0
,
lowDist
:
0
,
lowDist
:
0
,
highDist
:
0
highDist
:
0
};
};
/**
/**
* Half of the width of the slider handles
* Half of the width of the slider handles
*
*
* @type {number}
* @type {number}
*/
*/
this
.
handleHalfWidth
=
0
;
this
.
handleHalfWidth
=
0
;
/**
/**
* Maximum left the slider handle can have
* Maximum left the slider handle can have
*
*
* @type {number}
* @type {number}
*/
*/
this
.
maxLeft
=
0
;
this
.
maxLeft
=
0
;
/**
/**
* Precision
* Precision
*
*
* @type {number}
* @type {number}
*/
*/
this
.
precision
=
0
;
this
.
precision
=
0
;
/**
/**
* Step
* Step
*
*
* @type {number}
* @type {number}
*/
*/
this
.
step
=
0
;
this
.
step
=
0
;
/**
/**
* The name of the handle we are currently tracking
* The name of the handle we are currently tracking
*
*
* @type {string}
* @type {string}
*/
*/
this
.
tracking
=
''
;
this
.
tracking
=
''
;
/**
/**
* Minimum value (floor) of the model
* Minimum value (floor) of the model
*
*
* @type {number}
* @type {number}
*/
*/
this
.
minValue
=
0
;
this
.
minValue
=
0
;
/**
/**
* Maximum value (ceiling) of the model
* Maximum value (ceiling) of the model
*
*
* @type {number}
* @type {number}
*/
*/
this
.
maxValue
=
0
;
this
.
maxValue
=
0
;
/**
/**
* The delta between min and max value
* The delta between min and max value
*
*
* @type {number}
* @type {number}
*/
*/
this
.
valueRange
=
0
;
this
.
valueRange
=
0
;
/**
/**
* Set to true if init method already executed
* Set to true if init method already executed
*
*
* @type {boolean}
* @type {boolean}
*/
*/
this
.
initHasRun
=
false
;
this
.
initHasRun
=
false
;
// Slider DOM elements wrapped in jqLite
// Slider DOM elements wrapped in jqLite
this
.
fullBar
=
null
;
// The whole slider bar
this
.
fullBar
=
null
;
// The whole slider bar
this
.
selBar
=
null
;
// Highlight between two handles
this
.
selBar
=
null
;
// Highlight between two handles
this
.
minH
=
null
;
// Left slider handle
this
.
minH
=
null
;
// Left slider handle
this
.
maxH
=
null
;
// Right slider handle
this
.
maxH
=
null
;
// Right slider handle
this
.
flrLab
=
null
;
// Floor label
this
.
flrLab
=
null
;
// Floor label
this
.
ceilLab
=
null
;
// Ceiling label
this
.
ceilLab
=
null
;
// Ceiling label
this
.
minLab
=
null
;
// Label above the low value
this
.
minLab
=
null
;
// Label above the low value
this
.
maxLab
=
null
;
// Label above the high value
this
.
maxLab
=
null
;
// Label above the high value
this
.
cmbLab
=
null
;
// Combined label
this
.
cmbLab
=
null
;
// Combined label
this
.
ticks
=
null
;
// The ticks
this
.
ticks
=
null
;
// The ticks
// Initialize slider
// Initialize slider
this
.
init
();
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
();
}
/**
},
self
.
options
.
interval
);
* Initialize slider
*
thrHigh
=
rzThrottle
(
function
()
{
* @returns {undefined}
self
.
setMinAndMax
();
*/
self
.
updateHighHandle
(
self
.
valueToOffset
(
self
.
scope
.
rzSliderHigh
));
init
:
function
()
{
self
.
updateSelectionBar
();
var
thrLow
,
thrHigh
,
self
.
updateTicksScale
();
calcDimFn
=
angular
.
bind
(
this
,
this
.
calcViewDimensions
),
self
.
updateCmbLabel
();
self
=
this
;
},
self
.
options
.
interval
)
;
this
.
applyOptions
();
this
.
scope
.
$on
(
'rzSliderForceRender'
,
function
()
{
this
.
initElemHandles
();
self
.
resetLabelsValue
();
th
is
.
manageElementsStyle
();
th
rLow
();
this
.
addAccessibility
();
if
(
self
.
range
)
{
this
.
manageEventsBindings
();
thrHigh
();
this
.
setDisabledState
();
}
this
.
calcViewDimensions
();
self
.
resetSlider
();
this
.
setMinAndMax
(
);
}
);
$timeout
(
function
()
{
// Watchers
self
.
updateCeilLab
();
this
.
scope
.
$watch
(
'rzSliderModel'
,
function
(
newValue
,
oldValue
)
{
self
.
updateFloorLab
();
if
(
newValue
===
oldValue
)
self
.
initHandles
()
;
return
;
self
.
bindEvents
();
thrLow
();
});
});
// Recalculate slider view dimensions
this
.
scope
.
$watch
(
'rzSliderHigh'
,
function
(
newValue
,
oldValue
)
{
this
.
scope
.
$on
(
'reCalcViewDimensions'
,
calcDimFn
);
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
this
.
scope
.
$watch
(
'rzSliderOptions'
,
function
(
newValue
,
oldValue
)
{
angular
.
element
(
$window
).
on
(
'resize'
,
calcDimFn
);
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
()
{
if
(
this
.
options
.
step
<=
0
)
self
.
setMinAndMax
();
this
.
options
.
step
=
1
;
self
.
updateLowHandle
(
self
.
valueToOffset
(
self
.
scope
.
rzSliderModel
));
this
.
range
=
this
.
scope
.
rzSliderModel
!==
undefined
&&
this
.
scope
.
rzSliderHigh
!==
undefined
;
self
.
updateSelectionBar
();
this
.
options
.
draggableRange
=
this
.
range
&&
this
.
options
.
draggableRange
;
self
.
updateTicksScale
();
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
()
{
},
this
);
self
.
setMinAndMax
();
self
.
updateHighHandle
(
self
.
valueToOffset
(
self
.
scope
.
rzSliderHigh
));
self
.
updateSelectionBar
();
self
.
updateTicksScale
();
self
.
updateCmbLabel
();
},
self
.
options
.
interval
);
this
.
scope
.
$on
(
'rzSliderForceRender'
,
function
()
{
// Initialize offset cache properties
self
.
resetLabelsValue
();
this
.
selBar
.
rzsl
=
0
;
thrLow
();
this
.
minH
.
rzsl
=
0
;
if
(
self
.
range
)
{
this
.
maxH
.
rzsl
=
0
;
thrHigh
();
this
.
flrLab
.
rzsl
=
0
;
}
this
.
ceilLab
.
rzsl
=
0
;
self
.
resetSlider
();
this
.
minLab
.
rzsl
=
0
;
});
this
.
maxLab
.
rzsl
=
0
;
this
.
cmbLab
.
rzsl
=
0
;
},
// Watchers
/** Update each elements style based on options
this
.
scope
.
$watch
(
'rzSliderModel'
,
function
(
newValue
,
oldValue
)
{
*
if
(
newValue
===
oldValue
)
*/
return
;
manageElementsStyle
:
function
()
{
thrLow
();
});
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
)
* Manage the events bindings based on readOnly and disabled options
return
;
*
if
(
newValue
!=
null
)
* @returns {undefined}
thrHigh
();
*/
if
(
self
.
range
&&
newValue
==
null
||
!
self
.
range
&&
newValue
!=
null
)
{
manageEventsBindings
:
function
()
{
self
.
applyOptions
();
if
(
this
.
options
.
disabled
||
this
.
options
.
readOnly
)
self
.
resetSlider
();
this
.
unbindEvents
();
}
else
if
(
!
this
.
options
.
disabled
||
!
this
.
options
.
readOnly
)
});
this
.
bindEvents
();
},
this
.
scope
.
$watch
(
'rzSliderOptions'
,
function
(
newValue
,
oldValue
)
{
/**
if
(
newValue
===
oldValue
)
* Set the disabled state based on rzSliderDisabled
return
;
*
self
.
applyOptions
();
* @returns {undefined}
self
.
resetSlider
();
*/
},
true
);
setDisabledState
:
function
()
{
if
(
this
.
options
.
disabled
)
{
this
.
sliderElem
.
attr
(
'disabled'
,
'disabled'
);
}
else
{
this
.
sliderElem
.
attr
(
'disabled'
,
null
);
}
},
this
.
scope
.
$on
(
'$destroy'
,
function
()
{
/**
self
.
unbindEvents
();
* Reset label values
angular
.
element
(
$window
).
off
(
'resize'
,
calcDimFn
);
*
});
* @return {undefined}
},
*/
resetLabelsValue
:
function
()
{
this
.
minLab
.
rzsv
=
undefined
;
this
.
maxLab
.
rzsv
=
undefined
;
},
/**
/**
* Read the user options and apply them to the slider model
* Initialize slider handles positions and labels
*/
*
applyOptions
:
function
()
{
* Run only once during initialization and every time view port changes size
this
.
options
=
RzSliderOptions
.
getOptions
(
this
.
scope
.
rzSliderOptions
);
*
* @returns {undefined}
if
(
this
.
options
.
step
<=
0
)
*/
this
.
options
.
step
=
1
;
initHandles
:
function
()
{
this
.
range
=
this
.
scope
.
rzSliderModel
!==
undefined
&&
this
.
scope
.
rzSliderHigh
!==
undefined
;
this
.
updateLowHandle
(
this
.
valueToOffset
(
this
.
scope
.
rzSliderModel
));
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
;
}
},
this
);
/*
the order here is important since the selection bar should be
// Initialize offset cache properties
updated after the high handle but before the combined label
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}
*/
*/
manageEventsBindings
:
function
()
{
if
(
this
.
range
)
if
(
this
.
options
.
disabled
||
this
.
options
.
readOnly
)
this
.
updateHighHandle
(
this
.
valueToOffset
(
this
.
scope
.
rzSliderHigh
));
this
.
unbindEvents
();
this
.
updateSelectionBar
();
else
if
(
!
this
.
options
.
disabled
||
!
this
.
options
.
readOnly
)
if
(
this
.
range
)
this
.
bindEvents
();
this
.
updateCmbLabel
();
},
/**
* 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
.
updateTicksScale
();
* 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
();
/**
},
* Translate value to human readable format
*
/**
* @param {number|string} value
* Translate value to human readable format
* @param {jqLite} label
*
* @param {boolean} [useCustomTr]
* @param {number|string} value
* @returns {undefined}
* @param {jqLite} label
*/
* @param {boolean} [useCustomTr]
translateFn
:
function
(
value
,
label
,
useCustomTr
)
{
* @returns {undefined}
useCustomTr
=
useCustomTr
===
undefined
?
true
:
useCustomTr
;
*/
translateFn
:
function
(
value
,
label
,
useCustomTr
)
{
useCustomTr
=
useCustomTr
===
undefined
?
true
:
useCustomTr
;
var
valStr
=
String
((
useCustomTr
?
this
.
customTrFn
(
value
,
this
.
options
.
id
)
:
value
)),
var
valStr
=
String
((
useCustomTr
?
this
.
customTrFn
(
value
,
this
.
options
.
id
)
:
value
)),
getWidth
=
false
;
getWidth
=
false
;
if
(
label
.
rzsv
===
undefined
||
label
.
rzsv
.
length
!==
valStr
.
length
||
(
label
.
rzsv
.
length
>
0
&&
label
.
rzsw
===
0
))
{
if
(
label
.
rzsv
===
undefined
||
label
.
rzsv
.
length
!==
valStr
.
length
||
(
label
.
rzsv
.
length
>
0
&&
label
.
rzsw
===
0
))
{
getWidth
=
true
;
getWidth
=
true
;
label
.
rzsv
=
valStr
;
label
.
rzsv
=
valStr
;
}
}
label
.
text
(
valStr
);
label
.
text
(
valStr
);
// Update width only when length of the label have changed
// Update width only when length of the label have changed
if
(
getWidth
)
{
if
(
getWidth
)
{
this
.
getWidth
(
label
);
this
.
getWidth
(
label
);
}
}
},
},
/**
/**
* Set maximum and minimum values for the slider and ensure the model and high
* Set maximum and minimum values for the slider and ensure the model and high
* value match these limits
* value match these limits
* @returns {undefined}
* @returns {undefined}
*/
*/
setMinAndMax
:
function
()
{
setMinAndMax
:
function
()
{
this
.
step
=
+
this
.
options
.
step
;
this
.
step
=
+
this
.
options
.
step
;
this
.
precision
=
+
this
.
options
.
precision
;
this
.
precision
=
+
this
.
options
.
precision
;
this
.
scope
.
rzSliderModel
=
this
.
roundStep
(
this
.
scope
.
rzSliderModel
);
this
.
scope
.
rzSliderModel
=
this
.
roundStep
(
this
.
scope
.
rzSliderModel
);
if
(
this
.
range
)
if
(
this
.
range
)
this
.
scope
.
rzSliderHigh
=
this
.
roundStep
(
this
.
scope
.
rzSliderHigh
);
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
)
if
(
this
.
options
.
ceil
)
this
.
maxValue
=
this
.
roundStep
(
+
this
.
options
.
ceil
);
this
.
maxValue
=
this
.
roundStep
(
+
this
.
options
.
ceil
);
else
else
this
.
maxValue
=
this
.
options
.
ceil
=
this
.
range
?
this
.
scope
.
rzSliderHigh
:
this
.
scope
.
rzSliderModel
;
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
* Adds accessibility atributes
*
*
* Run only once during initialization
* Run only once during initialization
*
*
* @returns {undefined}
* @returns {undefined}
*/
*/
addAccessibility
:
function
()
{
addAccessibility
:
function
()
{
this
.
sliderElem
.
attr
(
"role"
,
"slider"
);
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
);
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
.
maxLeft
=
this
.
barWidth
-
handleWidth
;
this
.
sliderElem
.
rzsl
=
this
.
sliderElem
[
0
].
getBoundingClientRect
().
left
;
if
(
this
.
initHasRun
)
{
this
.
getWidth
(
this
.
sliderElem
);
this
.
updateFloorLab
();
this
.
sliderElem
.
rzsl
=
this
.
sliderElem
[
0
].
getBoundingClientRect
().
left
;
this
.
updateCeilLab
();
this
.
initHandles
();
}
},
/**
if
(
this
.
initHasRun
)
{
* Update the ticks position
this
.
updateFloorLab
();
*
this
.
updateCeilLab
();
* @returns {undefined}
this
.
initHandles
();
*/
}
updateTicksScale
:
function
()
{
},
if
(
!
this
.
options
.
showTicks
)
return
;
if
(
!
this
.
step
)
return
;
//if step is 0, the following loop will be endless.
/**
* Update the ticks position
var
positions
=
''
,
*
ticksCount
=
Math
.
round
((
this
.
maxValue
-
this
.
minValue
)
/
this
.
step
)
+
1
;
* @returns {undefined}
for
(
var
i
=
0
;
i
<
ticksCount
;
i
++
)
{
*/
var
value
=
this
.
roundStep
(
this
.
minValue
+
i
*
this
.
step
);
updateTicksScale
:
function
()
{
var
selectedClass
=
this
.
isTickSelected
(
value
)
?
'selected'
:
''
;
if
(
!
this
.
options
.
showTicks
)
return
;
positions
+=
'<li class="tick '
+
selectedClass
+
'">'
;
if
(
!
this
.
step
)
return
;
//if step is 0, the following loop will be endless.
if
(
this
.
options
.
showTicksValues
)
{
var
tooltip
=
''
;
var
positions
=
''
,
if
(
this
.
options
.
ticksValuesTooltip
)
{
ticksCount
=
Math
.
round
((
this
.
maxValue
-
this
.
minValue
)
/
this
.
step
)
+
1
;
tooltip
=
'uib-tooltip="'
+
this
.
options
.
ticksValuesTooltip
(
value
)
+
'"'
;
for
(
var
i
=
0
;
i
<
ticksCount
;
i
++
)
{
}
var
value
=
this
.
roundStep
(
this
.
minValue
+
i
*
this
.
step
);
positions
+=
'<span '
+
tooltip
+
' class="tick-value">'
+
this
.
getDisplayValue
(
value
)
+
'</span>'
;
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>'
;
positions
+=
'<span '
+
tooltip
+
' class="tick-value">'
+
this
.
getDisplayValue
(
value
)
+
'</span>'
;
}
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
+=
'</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
* Update position of the ceiling label
*
*
* @returns {undefined}
* @returns {undefined}
*/
*/
callOnChange
:
function
()
{
updateCeilLab
:
function
()
{
if
(
this
.
options
.
onChange
)
{
this
.
translateFn
(
this
.
maxValue
,
this
.
ceilLab
);
var
self
=
this
;
this
.
setLeft
(
this
.
ceilLab
,
this
.
barWidth
-
this
.
ceilLab
.
rzsw
);
$timeout
(
function
()
{
this
.
getWidth
(
this
.
ceilLab
);
self
.
options
.
onChange
();
},
});
}
},
/**
/**
* Call the onEnd callback if defined
* Update position of the floor label
*
*
* @returns {undefined}
* @returns {undefined}
*/
*/
callOnEnd
:
function
()
{
updateFloorLab
:
function
()
{
if
(
this
.
options
.
onEnd
)
{
this
.
translateFn
(
this
.
minValue
,
this
.
flrLab
);
var
self
=
this
;
this
.
getWidth
(
this
.
flrLab
);
$timeout
(
function
()
{
},
self
.
options
.
onEnd
();
});
}
},
/**
/**
* Update slider handles and label positions
* Call the onStart callback if defined
*
*
* @param {string} which
* @returns {undefined}
* @param {number} newOffset
*/
*/
callOnStart
:
function
()
{
updateHandles
:
function
(
which
,
newOffset
)
{
if
(
this
.
options
.
onStart
)
{
if
(
which
===
'rzSliderModel'
)
{
var
self
=
this
;
this
.
updateLowHandle
(
newOffset
);
$timeout
(
function
()
{
this
.
updateSelectionBar
();
self
.
options
.
onStart
();
this
.
updateTicksScale
();
});
}
if
(
this
.
range
)
{
},
this
.
updateCmbLabel
();
}
return
;
}
if
(
which
===
'rzSliderHigh'
)
{
/**
this
.
updateHighHandle
(
newOffset
);
* Call the onChange callback if defined
this
.
updateSelectionBar
();
*
this
.
updateTicksScale
();
* @returns {undefined}
*/
callOnChange
:
function
()
{
if
(
this
.
options
.
onChange
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onChange
();
});
}
},
if
(
this
.
range
)
{
/**
this
.
updateCmbLabel
();
* Call the onEnd callback if defined
}
*
return
;
* @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
.
updateLowHandle
(
newOffset
);
this
.
updateHighHandle
(
newOffset
);
this
.
updateSelectionBar
();
this
.
updateSelectionBar
();
this
.
updateTicksScale
();
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
)
{
if
(
this
.
range
)
{
flHidden
=
true
;
this
.
updateCmbLabel
();
this
.
hideEl
(
this
.
flrLab
);
}
}
else
{
return
;
flHidden
=
false
;
}
this
.
showEl
(
this
.
flrLab
);
if
(
which
===
'rzSliderHigh'
)
{
this
.
updateHighHandle
(
newOffset
);
this
.
updateSelectionBar
();
this
.
updateTicksScale
();
if
(
this
.
range
)
{
this
.
updateCmbLabel
();
}
}
return
;
}
// Update both
this
.
updateLowHandle
(
newOffset
);
this
.
updateHighHandle
(
newOffset
);
this
.
updateSelectionBar
();
this
.
updateTicksScale
();
this
.
updateCmbLabel
();
},
/**
* Update low slider handle position and label
*
* @param {number} newOffset
* @returns {undefined}
*/
updateLowHandle
:
function
(
newOffset
)
{
this
.
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
)
{
if
(
this
.
range
)
{
clHidden
=
true
;
if
(
this
.
maxLab
.
rzsl
+
this
.
maxLab
.
rzsw
>=
this
.
ceilLab
.
rzsl
-
10
)
{
this
.
hideEl
(
this
.
ceilLab
);
this
.
hideEl
(
this
.
ceilLab
);
}
}
else
if
(
!
clHidden
)
{
else
{
clHidden
=
false
;
this
.
showEl
(
this
.
ceilLab
);
this
.
showEl
(
this
.
ceilLab
);
}
}
if
(
this
.
range
)
{
// Hide or show floor label
if
(
this
.
maxLab
.
rzsl
+
this
.
maxLab
.
rzsw
>=
this
.
ceilLab
.
rzsl
-
10
)
{
if
(
this
.
maxLab
.
rzsl
<=
this
.
flrLab
.
rzsl
+
this
.
flrLab
.
rzsw
+
this
.
handleHalfWidth
)
{
this
.
hideEl
(
this
.
ceilLab
);
this
.
hideEl
(
this
.
flrLab
);
}
}
else
if
(
!
flHidden
)
{
else
if
(
!
clHidden
)
{
this
.
showEl
(
this
.
flrLab
);
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
);
}
}
}
},
}
},
/**
/**
* Update slider selection bar, combined label and range label
* Update slider selection bar, combined label and range label
*
*
* @returns {undefined}
* @returns {undefined}
*/
*/
updateSelectionBar
:
function
()
{
updateSelectionBar
:
function
()
{
this
.
setWidth
(
this
.
selBar
,
Math
.
abs
(
this
.
maxH
.
rzsl
-
this
.
minH
.
rzsl
)
+
this
.
handleHalfWidth
);
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
);
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
);
}
},
/**
/**
* Return the translated value if a translate function is provided else the original value
* Update combined label position and value
* @param value
*
* @returns {*}
* @returns {undefined}
*/
*/
getDisplayValue
:
function
(
value
)
{
updateCmbLabel
:
function
()
{
return
this
.
customTrFn
(
value
,
this
.
options
.
id
);
var
lowTr
,
highTr
;
},
if
(
this
.
minLab
.
rzsl
+
this
.
minLab
.
rzsw
+
10
>=
this
.
maxLab
.
rzsl
)
{
/**
lowTr
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderModel
);
* Round value to step and precision
highTr
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderHigh
);
*
* @param {number} value
this
.
translateFn
(
lowTr
+
' - '
+
highTr
,
this
.
cmbLab
,
false
);
* @returns {number}
this
.
setLeft
(
this
.
cmbLab
,
this
.
selBar
.
rzsl
+
this
.
selBar
.
rzsw
/
2
-
this
.
cmbLab
.
rzsw
/
2
);
*/
this
.
hideEl
(
this
.
minLab
);
roundStep
:
function
(
value
)
{
this
.
hideEl
(
this
.
maxLab
);
var
step
=
this
.
step
,
this
.
showEl
(
this
.
cmbLab
);
remainder
=
+
((
value
-
this
.
minValue
)
%
step
).
toFixed
(
3
),
}
else
{
steppedValue
=
remainder
>
(
step
/
2
)
?
value
+
step
-
remainder
:
value
-
remainder
;
this
.
showEl
(
this
.
maxLab
);
this
.
showEl
(
this
.
minLab
);
steppedValue
=
steppedValue
.
toFixed
(
this
.
precision
);
this
.
hideEl
(
this
.
cmbLab
);
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
;
}
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
* Round value to step and precision
*
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @param {number} value
* @param {number} left
* @returns {number}
* @returns {number}
*/
*/
roundStep
:
function
(
value
)
{
setLeft
:
function
(
elem
,
left
)
{
var
step
=
this
.
step
,
elem
.
rzsl
=
left
;
remainder
=
+
((
value
-
this
.
minValue
)
%
step
).
toFixed
(
3
),
elem
.
css
({
left
:
left
+
'px'
});
steppedValue
=
remainder
>
(
step
/
2
)
?
value
+
step
-
remainder
:
value
-
remainder
;
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
;
},
// Events
steppedValue
=
steppedValue
.
toFixed
(
this
.
precision
);
return
+
steppedValue
;
},
/**
/**
* Get the X-coordinate of an event
* Hide element
*
*
* @param {Object} event The event
* @param element
* @returns {number}
* @returns {jqLite} The jqLite wrapped DOM element
*/
*/
getEventX
:
function
(
event
)
{
hideEl
:
function
(
element
)
{
/* http://stackoverflow.com/a/12336075/282882 */
return
element
.
css
({
//noinspection JSLint
opacity
:
0
if
(
'clientX'
in
event
)
{
});
return
event
.
clientX
;
},
}
return
event
.
originalEvent
===
undefined
?
/**
event
.
touches
[
0
].
clientX
* Show element
:
event
.
originalEvent
.
touches
[
0
].
clientX
;
*
},
* @param element The jqLite wrapped DOM element
* @returns {jqLite} The jqLite
*/
showEl
:
function
(
element
)
{
if
(
!!
element
.
rzAlwaysHide
)
{
return
element
;
}
/**
return
element
.
css
({
* Get the handle closest to an event.
opacity
:
1
*
});
* @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
;
}
this
.
minH
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
minH
,
'rzSliderModel'
));
/**
if
(
this
.
range
)
{
* Set element left offset
this
.
maxH
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
maxH
,
'rzSliderHigh'
));
*
}
* @param {jqLite} elem The jqLite wrapped DOM element
this
.
fullBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
* @param {number} left
this
.
fullBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
fullBar
));
* @returns {number}
this
.
selBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
barStart
,
null
,
barTracking
));
*/
this
.
selBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
barMove
,
this
.
selBar
));
setLeft
:
function
(
elem
,
left
)
{
this
.
ticks
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
elem
.
rzsl
=
left
;
this
.
ticks
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
ticks
));
elem
.
css
({
left
:
left
+
'px'
this
.
minH
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
minH
,
'rzSliderModel'
));
});
if
(
this
.
range
)
{
return
left
;
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
();
* 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.
* Translate value to pixel offset
this
.
calcViewDimensions
();
*
* @param {number} val
* @returns {number}
*/
valueToOffset
:
function
(
val
)
{
return
(
this
.
sanitizeOffsetValue
(
val
)
-
this
.
minValue
)
*
this
.
maxLeft
/
this
.
valueRange
||
0
;
},
if
(
pointer
)
{
/**
this
.
tracking
=
ref
;
* Ensure that the position rendered is within the slider bounds, even if the value is not
}
*
else
{
* @param {number} val
pointer
=
this
.
getNearestHandle
(
event
);
* @returns {number}
this
.
tracking
=
pointer
===
this
.
minH
?
'rzSliderModel'
:
'rzSliderHigh'
;
*/
}
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
);
// Events
ehEnd
=
angular
.
bind
(
this
,
this
.
onEnd
,
ehMove
);
$document
.
on
(
eventNames
.
moveEvent
,
ehMove
);
/**
$document
.
one
(
eventNames
.
endEvent
,
ehEnd
);
* Get the X-coordinate of an event
this
.
callOnStart
();
*
},
* @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
;
}
/**
return
event
.
originalEvent
===
undefined
?
* onMove event handler
event
.
touches
[
0
].
clientX
:
event
.
originalEvent
.
touches
[
0
].
clientX
;
*
},
* @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
);
/**
},
* 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
* Bind mouse and touch events to slider handles
*
*
* @param {number} newMinValue the new minimum value
* @returns {undefined}
* @param {number} newMaxValue the new maximum value
*/
* @param {number} newMinOffset the new minimum offset
bindEvents
:
function
()
{
* @param {number} newMaxOffset the new maximum offset
if
(
this
.
options
.
readOnly
||
this
.
options
.
disabled
)
return
;
*/
var
barTracking
,
barStart
,
barMove
;
positionTrackingBar
:
function
(
newMinValue
,
newMaxValue
,
newMinOffset
,
newMaxOffset
)
{
this
.
scope
.
rzSliderModel
=
newMinValue
;
if
(
this
.
options
.
draggableRange
)
{
this
.
scope
.
rzSliderHigh
=
newMaxValue
;
barTracking
=
'rzSliderDrag'
;
this
.
updateHandles
(
'rzSliderModel'
,
newMinOffset
);
barStart
=
this
.
onDragStart
;
this
.
updateHandles
(
'rzSliderHigh'
,
newMaxOffset
);
barMove
=
this
.
onDragMove
;
this
.
scope
.
$apply
();
}
else
{
this
.
callOnChange
();
barTracking
=
'rzSliderModel'
;
},
barStart
=
this
.
onStart
;
barMove
=
this
.
onMove
;
}
/**
this
.
minH
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
minH
,
'rzSliderModel'
));
* Set the new value and offset to the current tracking handle
if
(
this
.
range
)
{
*
this
.
maxH
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
maxH
,
'rzSliderHigh'
));
* @param {number} newValue new model value
}
* @param {number} newOffset new offset value
this
.
fullBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
*/
this
.
fullBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
fullBar
));
positionTrackingHandle
:
function
(
newValue
,
newOffset
)
{
this
.
selBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
barStart
,
null
,
barTracking
));
if
(
this
.
range
)
{
this
.
selBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
barMove
,
this
.
selBar
));
/* This is to check if we need to switch the min and max handles*/
this
.
ticks
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
if
(
this
.
tracking
===
'rzSliderModel'
&&
newValue
>=
this
.
scope
.
rzSliderHigh
)
{
this
.
ticks
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
ticks
));
this
.
scope
[
this
.
tracking
]
=
this
.
scope
.
rzSliderHigh
;
this
.
updateHandles
(
this
.
tracking
,
this
.
maxH
.
rzsl
);
this
.
minH
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
minH
,
'rzSliderModel'
));
this
.
tracking
=
'rzSliderHigh'
;
if
(
this
.
range
)
{
this
.
minH
.
removeClass
(
'rz-active'
);
this
.
maxH
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
maxH
,
'rzSliderHigh'
));
this
.
maxH
.
addClass
(
'rz-active'
);
}
/* We need to apply here because we are not sure that we will enter the next block */
this
.
fullBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
this
.
scope
.
$apply
();
this
.
fullBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
fullBar
));
this
.
callOnChange
();
this
.
selBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
barStart
,
null
,
barTracking
));
}
this
.
selBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
barMove
,
this
.
selBar
));
else
if
(
this
.
tracking
===
'rzSliderHigh'
&&
newValue
<=
this
.
scope
.
rzSliderModel
)
{
this
.
ticks
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
this
.
scope
[
this
.
tracking
]
=
this
.
scope
.
rzSliderModel
;
this
.
ticks
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
ticks
));
this
.
updateHandles
(
this
.
tracking
,
this
.
minH
.
rzsl
);
},
this
.
tracking
=
'rzSliderModel'
;
this
.
maxH
.
removeClass
(
'rz-active'
);
/**
this
.
minH
.
addClass
(
'rz-active'
);
* Unbind mouse and touch events to slider handles
/* We need to apply here because we are not sure that we will enter the next block */
*
this
.
scope
.
$apply
();
* @returns {undefined}
this
.
callOnChange
();
*/
}
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
;
* Set the new value and offset to the current tracking handle
this
.
updateHandles
(
this
.
tracking
,
newOffset
);
*
* @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
.
scope
.
$apply
();
this
.
callOnChange
();
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'
);
if
(
this
.
scope
[
this
.
tracking
]
!==
newValue
)
{
this
.
maxH
.
removeClass
(
'rz-active'
);
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
.
minH
.
removeClass
(
'rz-active
'
);
this
.
tracking
=
''
;
this
.
maxH
.
removeClass
(
'rz-active'
)
;
this
.
dragging
.
active
=
false
;
$document
.
off
(
moveEventName
,
ehMove
);
this
.
callOnEnd
();
},
/**
this
.
scope
.
$emit
(
'slideEnded'
);
* Get event names for move and event end
this
.
tracking
=
''
;
*
* @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
))
{
this
.
dragging
.
active
=
false
;
eventNames
.
moveEvent
=
'touchmove'
;
this
.
callOnEnd
();
eventNames
.
endEvent
=
'touchend'
;
},
}
else
{
eventNames
.
moveEvent
=
'mousemove'
;
eventNames
.
endEvent
=
'mouseup'
;
}
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
)
{
return
Slider
;
'use strict'
;
}])
return
{
.
directive
(
'rzslider'
,
[
'RzSlider'
,
function
(
RzSlider
)
{
restrict
:
'E'
,
'use strict'
;
scope
:
{
rzSliderModel
:
'=?'
,
rzSliderHigh
:
'=?'
,
rzSliderOptions
:
'=?'
,
rzSliderTplUrl
:
'@'
},
/**
* Return template URL
*
* @param {jqLite} elem
* @param {Object} attrs
* @return {string}
*/
templateUrl
:
function
(
elem
,
attrs
)
{
//noinspection JSUnresolvedVariable
return
attrs
.
rzSliderTplUrl
||
'rzSliderTpl.html'
;
},
link
:
function
(
scope
,
elem
)
{
return
{
return
new
RzSlider
(
scope
,
elem
);
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
* @name ngScope
...
...
src/rzslider.js
View file @
d03ac54c
...
@@ -31,53 +31,53 @@
...
@@ -31,53 +31,53 @@
'use strict'
;
'use strict'
;
var
module
=
angular
.
module
(
'rzModule'
,
[])
var
module
=
angular
.
module
(
'rzModule'
,
[])
.
factory
(
'RzSliderOptions'
,
function
()
{
.
factory
(
'RzSliderOptions'
,
function
()
{
var
defaultOptions
=
{
var
defaultOptions
=
{
floor
:
0
,
floor
:
0
,
ceil
:
null
,
//defaults to rz-slider-model
ceil
:
null
,
//defaults to rz-slider-model
step
:
1
,
step
:
1
,
precision
:
0
,
precision
:
0
,
id
:
null
,
id
:
null
,
translate
:
null
,
translate
:
null
,
stepsArray
:
null
,
stepsArray
:
null
,
draggableRange
:
false
,
draggableRange
:
false
,
showSelectionBar
:
false
,
showSelectionBar
:
false
,
hideLimitLabels
:
false
,
hideLimitLabels
:
false
,
readOnly
:
false
,
readOnly
:
false
,
disabled
:
false
,
disabled
:
false
,
interval
:
350
,
interval
:
350
,
showTicks
:
false
,
showTicks
:
false
,
showTicksValues
:
false
,
showTicksValues
:
false
,
ticksValuesTooltip
:
null
,
ticksValuesTooltip
:
null
,
scale
:
1
,
scale
:
1
,
onStart
:
null
,
onStart
:
null
,
onChange
:
null
,
onChange
:
null
,
onEnd
:
null
onEnd
:
null
};
};
var
globalOptions
=
{};
var
globalOptions
=
{};
var
factory
=
{};
var
factory
=
{};
/**
/**
* `options({})` allows global configuration of all sliders in the
* `options({})` allows global configuration of all sliders in the
* application.
* application.
*
*
* var app = angular.module( 'App', ['rzModule'], function( RzSliderOptions ) {
* var app = angular.module( 'App', ['rzModule'], function( RzSliderOptions ) {
* // show ticks for all sliders
* // show ticks for all sliders
* RzSliderOptions.options( { showTicks: true } );
* RzSliderOptions.options( { showTicks: true } );
* });
* });
*/
*/
factory
.
options
=
function
(
value
)
{
factory
.
options
=
function
(
value
)
{
angular
.
extend
(
globalOptions
,
value
);
angular
.
extend
(
globalOptions
,
value
);
};
};
factory
.
getOptions
=
function
(
options
)
{
factory
.
getOptions
=
function
(
options
)
{
return
angular
.
extend
({},
defaultOptions
,
globalOptions
,
options
);
return
angular
.
extend
({},
defaultOptions
,
globalOptions
,
options
);
};
};
return
factory
;
return
factory
;
})
})
.
value
(
'rzThrottle'
,
.
value
(
'rzThrottle'
,
/**
/**
* rzThrottle
* rzThrottle
*
*
...
@@ -124,1242 +124,1238 @@
...
@@ -124,1242 +124,1238 @@
};
};
})
})
.
factory
(
'RzSlider'
,
function
(
$timeout
,
$document
,
$window
,
$compile
,
RzSliderOptions
,
rzThrottle
)
{
.
factory
(
'RzSlider'
,
function
(
$timeout
,
$document
,
$window
,
$compile
,
RzSliderOptions
,
rzThrottle
)
{
'use strict'
;
'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
* @type {ngScope}
* @param {Element} sliderElem The slider directive element wrapped in jqLite
* @constructor
*/
*/
var
Slider
=
function
(
scope
,
sliderElem
)
{
this
.
scope
=
scope
;
/**
* The slider's scope
*
* @type {ngScope}
*/
this
.
scope
=
scope
;
/**
/**
* Slider element wrapped in jqLite
* Slider element wrapped in jqLite
*
*
* @type {jqLite}
* @type {jqLite}
*/
*/
this
.
sliderElem
=
sliderElem
;
this
.
sliderElem
=
sliderElem
;
/**
/**
* Slider type
* Slider type
*
*
* @type {boolean} Set to true for range slider
* @type {boolean} Set to true for range slider
*/
*/
this
.
range
=
this
.
scope
.
rzSliderModel
!==
undefined
&&
this
.
scope
.
rzSliderHigh
!==
undefined
;
this
.
range
=
this
.
scope
.
rzSliderModel
!==
undefined
&&
this
.
scope
.
rzSliderHigh
!==
undefined
;
/**
/**
* Values recorded when first dragging the bar
* Values recorded when first dragging the bar
*
*
* @type {Object}
* @type {Object}
*/
*/
this
.
dragging
=
{
this
.
dragging
=
{
active
:
false
,
active
:
false
,
value
:
0
,
value
:
0
,
difference
:
0
,
difference
:
0
,
offset
:
0
,
offset
:
0
,
lowDist
:
0
,
lowDist
:
0
,
highDist
:
0
highDist
:
0
};
};
/**
/**
* Half of the width of the slider handles
* Half of the width of the slider handles
*
*
* @type {number}
* @type {number}
*/
*/
this
.
handleHalfWidth
=
0
;
this
.
handleHalfWidth
=
0
;
/**
/**
* Maximum left the slider handle can have
* Maximum left the slider handle can have
*
*
* @type {number}
* @type {number}
*/
*/
this
.
maxLeft
=
0
;
this
.
maxLeft
=
0
;
/**
/**
* Precision
* Precision
*
*
* @type {number}
* @type {number}
*/
*/
this
.
precision
=
0
;
this
.
precision
=
0
;
/**
/**
* Step
* Step
*
*
* @type {number}
* @type {number}
*/
*/
this
.
step
=
0
;
this
.
step
=
0
;
/**
/**
* The name of the handle we are currently tracking
* The name of the handle we are currently tracking
*
*
* @type {string}
* @type {string}
*/
*/
this
.
tracking
=
''
;
this
.
tracking
=
''
;
/**
/**
* Minimum value (floor) of the model
* Minimum value (floor) of the model
*
*
* @type {number}
* @type {number}
*/
*/
this
.
minValue
=
0
;
this
.
minValue
=
0
;
/**
/**
* Maximum value (ceiling) of the model
* Maximum value (ceiling) of the model
*
*
* @type {number}
* @type {number}
*/
*/
this
.
maxValue
=
0
;
this
.
maxValue
=
0
;
/**
/**
* The delta between min and max value
* The delta between min and max value
*
*
* @type {number}
* @type {number}
*/
*/
this
.
valueRange
=
0
;
this
.
valueRange
=
0
;
/**
/**
* Set to true if init method already executed
* Set to true if init method already executed
*
*
* @type {boolean}
* @type {boolean}
*/
*/
this
.
initHasRun
=
false
;
this
.
initHasRun
=
false
;
// Slider DOM elements wrapped in jqLite
// Slider DOM elements wrapped in jqLite
this
.
fullBar
=
null
;
// The whole slider bar
this
.
fullBar
=
null
;
// The whole slider bar
this
.
selBar
=
null
;
// Highlight between two handles
this
.
selBar
=
null
;
// Highlight between two handles
this
.
minH
=
null
;
// Left slider handle
this
.
minH
=
null
;
// Left slider handle
this
.
maxH
=
null
;
// Right slider handle
this
.
maxH
=
null
;
// Right slider handle
this
.
flrLab
=
null
;
// Floor label
this
.
flrLab
=
null
;
// Floor label
this
.
ceilLab
=
null
;
// Ceiling label
this
.
ceilLab
=
null
;
// Ceiling label
this
.
minLab
=
null
;
// Label above the low value
this
.
minLab
=
null
;
// Label above the low value
this
.
maxLab
=
null
;
// Label above the high value
this
.
maxLab
=
null
;
// Label above the high value
this
.
cmbLab
=
null
;
// Combined label
this
.
cmbLab
=
null
;
// Combined label
this
.
ticks
=
null
;
// The ticks
this
.
ticks
=
null
;
// The ticks
// Initialize slider
// Initialize slider
this
.
init
();
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
();
}
/**
},
self
.
options
.
interval
);
* Initialize slider
*
thrHigh
=
rzThrottle
(
function
()
{
* @returns {undefined}
self
.
setMinAndMax
();
*/
self
.
updateHighHandle
(
self
.
valueToOffset
(
self
.
scope
.
rzSliderHigh
));
init
:
function
()
{
self
.
updateSelectionBar
();
var
thrLow
,
thrHigh
,
self
.
updateTicksScale
();
calcDimFn
=
angular
.
bind
(
this
,
this
.
calcViewDimensions
),
self
.
updateCmbLabel
();
self
=
this
;
},
self
.
options
.
interval
)
;
this
.
applyOptions
();
this
.
scope
.
$on
(
'rzSliderForceRender'
,
function
()
{
this
.
initElemHandles
();
self
.
resetLabelsValue
();
th
is
.
manageElementsStyle
();
th
rLow
();
this
.
addAccessibility
();
if
(
self
.
range
)
{
this
.
manageEventsBindings
();
thrHigh
();
this
.
setDisabledState
();
}
this
.
calcViewDimensions
();
self
.
resetSlider
();
this
.
setMinAndMax
(
);
}
);
$timeout
(
function
()
{
// Watchers
self
.
updateCeilLab
();
this
.
scope
.
$watch
(
'rzSliderModel'
,
function
(
newValue
,
oldValue
)
{
self
.
updateFloorLab
();
if
(
newValue
===
oldValue
)
self
.
initHandles
()
;
return
;
self
.
bindEvents
();
thrLow
();
});
});
// Recalculate slider view dimensions
this
.
scope
.
$watch
(
'rzSliderHigh'
,
function
(
newValue
,
oldValue
)
{
this
.
scope
.
$on
(
'reCalcViewDimensions'
,
calcDimFn
);
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
this
.
scope
.
$watch
(
'rzSliderOptions'
,
function
(
newValue
,
oldValue
)
{
angular
.
element
(
$window
).
on
(
'resize'
,
calcDimFn
);
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
()
{
if
(
this
.
options
.
step
<=
0
)
self
.
setMinAndMax
();
this
.
options
.
step
=
1
;
self
.
updateLowHandle
(
self
.
valueToOffset
(
self
.
scope
.
rzSliderModel
));
this
.
range
=
this
.
scope
.
rzSliderModel
!==
undefined
&&
this
.
scope
.
rzSliderHigh
!==
undefined
;
self
.
updateSelectionBar
();
this
.
options
.
draggableRange
=
this
.
range
&&
this
.
options
.
draggableRange
;
self
.
updateTicksScale
();
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
()
{
},
this
);
self
.
setMinAndMax
();
self
.
updateHighHandle
(
self
.
valueToOffset
(
self
.
scope
.
rzSliderHigh
));
self
.
updateSelectionBar
();
self
.
updateTicksScale
();
self
.
updateCmbLabel
();
},
self
.
options
.
interval
);
this
.
scope
.
$on
(
'rzSliderForceRender'
,
function
()
{
// Initialize offset cache properties
self
.
resetLabelsValue
();
this
.
selBar
.
rzsl
=
0
;
thrLow
();
this
.
minH
.
rzsl
=
0
;
if
(
self
.
range
)
{
this
.
maxH
.
rzsl
=
0
;
thrHigh
();
this
.
flrLab
.
rzsl
=
0
;
}
this
.
ceilLab
.
rzsl
=
0
;
self
.
resetSlider
();
this
.
minLab
.
rzsl
=
0
;
});
this
.
maxLab
.
rzsl
=
0
;
this
.
cmbLab
.
rzsl
=
0
;
},
// Watchers
/** Update each elements style based on options
this
.
scope
.
$watch
(
'rzSliderModel'
,
function
(
newValue
,
oldValue
)
{
*
if
(
newValue
===
oldValue
)
*/
return
;
manageElementsStyle
:
function
()
{
thrLow
();
});
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
)
* Manage the events bindings based on readOnly and disabled options
return
;
*
if
(
newValue
!=
null
)
* @returns {undefined}
thrHigh
();
*/
if
(
self
.
range
&&
newValue
==
null
||
!
self
.
range
&&
newValue
!=
null
)
{
manageEventsBindings
:
function
()
{
self
.
applyOptions
();
if
(
this
.
options
.
disabled
||
this
.
options
.
readOnly
)
self
.
resetSlider
();
this
.
unbindEvents
();
}
else
if
(
!
this
.
options
.
disabled
||
!
this
.
options
.
readOnly
)
});
this
.
bindEvents
();
},
this
.
scope
.
$watch
(
'rzSliderOptions'
,
function
(
newValue
,
oldValue
)
{
/**
if
(
newValue
===
oldValue
)
* Set the disabled state based on rzSliderDisabled
return
;
*
self
.
applyOptions
();
* @returns {undefined}
self
.
resetSlider
();
*/
},
true
);
setDisabledState
:
function
()
{
if
(
this
.
options
.
disabled
)
{
this
.
sliderElem
.
attr
(
'disabled'
,
'disabled'
);
}
else
{
this
.
sliderElem
.
attr
(
'disabled'
,
null
);
}
},
this
.
scope
.
$on
(
'$destroy'
,
function
()
{
/**
self
.
unbindEvents
();
* Reset label values
angular
.
element
(
$window
).
off
(
'resize'
,
calcDimFn
);
*
});
* @return {undefined}
},
*/
resetLabelsValue
:
function
()
{
this
.
minLab
.
rzsv
=
undefined
;
this
.
maxLab
.
rzsv
=
undefined
;
},
/**
/**
* Read the user options and apply them to the slider model
* Initialize slider handles positions and labels
*/
*
applyOptions
:
function
()
{
* Run only once during initialization and every time view port changes size
this
.
options
=
RzSliderOptions
.
getOptions
(
this
.
scope
.
rzSliderOptions
);
*
* @returns {undefined}
if
(
this
.
options
.
step
<=
0
)
*/
this
.
options
.
step
=
1
;
initHandles
:
function
()
{
this
.
range
=
this
.
scope
.
rzSliderModel
!==
undefined
&&
this
.
scope
.
rzSliderHigh
!==
undefined
;
this
.
updateLowHandle
(
this
.
valueToOffset
(
this
.
scope
.
rzSliderModel
));
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
;
}
},
this
);
/*
the order here is important since the selection bar should be
// Initialize offset cache properties
updated after the high handle but before the combined label
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}
*/
*/
manageEventsBindings
:
function
()
{
if
(
this
.
range
)
if
(
this
.
options
.
disabled
||
this
.
options
.
readOnly
)
this
.
updateHighHandle
(
this
.
valueToOffset
(
this
.
scope
.
rzSliderHigh
));
this
.
unbindEvents
();
this
.
updateSelectionBar
();
else
if
(
!
this
.
options
.
disabled
||
!
this
.
options
.
readOnly
)
if
(
this
.
range
)
this
.
bindEvents
();
this
.
updateCmbLabel
();
},
/**
* 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
.
updateTicksScale
();
* 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
();
/**
},
* Translate value to human readable format
*
/**
* @param {number|string} value
* Translate value to human readable format
* @param {jqLite} label
*
* @param {boolean} [useCustomTr]
* @param {number|string} value
* @returns {undefined}
* @param {jqLite} label
*/
* @param {boolean} [useCustomTr]
translateFn
:
function
(
value
,
label
,
useCustomTr
)
{
* @returns {undefined}
useCustomTr
=
useCustomTr
===
undefined
?
true
:
useCustomTr
;
*/
translateFn
:
function
(
value
,
label
,
useCustomTr
)
{
useCustomTr
=
useCustomTr
===
undefined
?
true
:
useCustomTr
;
var
valStr
=
String
((
useCustomTr
?
this
.
customTrFn
(
value
,
this
.
options
.
id
)
:
value
)),
var
valStr
=
String
((
useCustomTr
?
this
.
customTrFn
(
value
,
this
.
options
.
id
)
:
value
)),
getWidth
=
false
;
getWidth
=
false
;
if
(
label
.
rzsv
===
undefined
||
label
.
rzsv
.
length
!==
valStr
.
length
||
(
label
.
rzsv
.
length
>
0
&&
label
.
rzsw
===
0
))
{
if
(
label
.
rzsv
===
undefined
||
label
.
rzsv
.
length
!==
valStr
.
length
||
(
label
.
rzsv
.
length
>
0
&&
label
.
rzsw
===
0
))
{
getWidth
=
true
;
getWidth
=
true
;
label
.
rzsv
=
valStr
;
label
.
rzsv
=
valStr
;
}
}
label
.
text
(
valStr
);
label
.
text
(
valStr
);
// Update width only when length of the label have changed
// Update width only when length of the label have changed
if
(
getWidth
)
{
if
(
getWidth
)
{
this
.
getWidth
(
label
);
this
.
getWidth
(
label
);
}
}
},
},
/**
/**
* Set maximum and minimum values for the slider and ensure the model and high
* Set maximum and minimum values for the slider and ensure the model and high
* value match these limits
* value match these limits
* @returns {undefined}
* @returns {undefined}
*/
*/
setMinAndMax
:
function
()
{
setMinAndMax
:
function
()
{
this
.
step
=
+
this
.
options
.
step
;
this
.
step
=
+
this
.
options
.
step
;
this
.
precision
=
+
this
.
options
.
precision
;
this
.
precision
=
+
this
.
options
.
precision
;
this
.
scope
.
rzSliderModel
=
this
.
roundStep
(
this
.
scope
.
rzSliderModel
);
this
.
scope
.
rzSliderModel
=
this
.
roundStep
(
this
.
scope
.
rzSliderModel
);
if
(
this
.
range
)
if
(
this
.
range
)
this
.
scope
.
rzSliderHigh
=
this
.
roundStep
(
this
.
scope
.
rzSliderHigh
);
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
)
if
(
this
.
options
.
ceil
)
this
.
maxValue
=
this
.
roundStep
(
+
this
.
options
.
ceil
);
this
.
maxValue
=
this
.
roundStep
(
+
this
.
options
.
ceil
);
else
else
this
.
maxValue
=
this
.
options
.
ceil
=
this
.
range
?
this
.
scope
.
rzSliderHigh
:
this
.
scope
.
rzSliderModel
;
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
* Adds accessibility atributes
*
*
* Run only once during initialization
* Run only once during initialization
*
*
* @returns {undefined}
* @returns {undefined}
*/
*/
addAccessibility
:
function
()
{
addAccessibility
:
function
()
{
this
.
sliderElem
.
attr
(
"role"
,
"slider"
);
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
);
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
.
maxLeft
=
this
.
barWidth
-
handleWidth
;
this
.
sliderElem
.
rzsl
=
this
.
sliderElem
[
0
].
getBoundingClientRect
().
left
;
if
(
this
.
initHasRun
)
{
this
.
getWidth
(
this
.
sliderElem
);
this
.
updateFloorLab
();
this
.
sliderElem
.
rzsl
=
this
.
sliderElem
[
0
].
getBoundingClientRect
().
left
;
this
.
updateCeilLab
();
this
.
initHandles
();
}
},
/**
if
(
this
.
initHasRun
)
{
* Update the ticks position
this
.
updateFloorLab
();
*
this
.
updateCeilLab
();
* @returns {undefined}
this
.
initHandles
();
*/
}
updateTicksScale
:
function
()
{
},
if
(
!
this
.
options
.
showTicks
)
return
;
if
(
!
this
.
step
)
return
;
//if step is 0, the following loop will be endless.
/**
* Update the ticks position
var
positions
=
''
,
*
ticksCount
=
Math
.
round
((
this
.
maxValue
-
this
.
minValue
)
/
this
.
step
)
+
1
;
* @returns {undefined}
for
(
var
i
=
0
;
i
<
ticksCount
;
i
++
)
{
*/
var
value
=
this
.
roundStep
(
this
.
minValue
+
i
*
this
.
step
);
updateTicksScale
:
function
()
{
var
selectedClass
=
this
.
isTickSelected
(
value
)
?
'selected'
:
''
;
if
(
!
this
.
options
.
showTicks
)
return
;
positions
+=
'<li class="tick '
+
selectedClass
+
'">'
;
if
(
!
this
.
step
)
return
;
//if step is 0, the following loop will be endless.
if
(
this
.
options
.
showTicksValues
)
{
var
tooltip
=
''
;
var
positions
=
''
,
if
(
this
.
options
.
ticksValuesTooltip
)
{
ticksCount
=
Math
.
round
((
this
.
maxValue
-
this
.
minValue
)
/
this
.
step
)
+
1
;
tooltip
=
'uib-tooltip="'
+
this
.
options
.
ticksValuesTooltip
(
value
)
+
'"'
;
for
(
var
i
=
0
;
i
<
ticksCount
;
i
++
)
{
}
var
value
=
this
.
roundStep
(
this
.
minValue
+
i
*
this
.
step
);
positions
+=
'<span '
+
tooltip
+
' class="tick-value">'
+
this
.
getDisplayValue
(
value
)
+
'</span>'
;
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>'
;
positions
+=
'<span '
+
tooltip
+
' class="tick-value">'
+
this
.
getDisplayValue
(
value
)
+
'</span>'
;
}
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
+=
'</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
* Update position of the ceiling label
*
*
* @returns {undefined}
* @returns {undefined}
*/
*/
callOnChange
:
function
()
{
updateCeilLab
:
function
()
{
if
(
this
.
options
.
onChange
)
{
this
.
translateFn
(
this
.
maxValue
,
this
.
ceilLab
);
var
self
=
this
;
this
.
setLeft
(
this
.
ceilLab
,
this
.
barWidth
-
this
.
ceilLab
.
rzsw
);
$timeout
(
function
()
{
this
.
getWidth
(
this
.
ceilLab
);
self
.
options
.
onChange
();
},
});
}
},
/**
/**
* Call the onEnd callback if defined
* Update position of the floor label
*
*
* @returns {undefined}
* @returns {undefined}
*/
*/
callOnEnd
:
function
()
{
updateFloorLab
:
function
()
{
if
(
this
.
options
.
onEnd
)
{
this
.
translateFn
(
this
.
minValue
,
this
.
flrLab
);
var
self
=
this
;
this
.
getWidth
(
this
.
flrLab
);
$timeout
(
function
()
{
},
self
.
options
.
onEnd
();
});
}
},
/**
/**
* Update slider handles and label positions
* Call the onStart callback if defined
*
*
* @param {string} which
* @returns {undefined}
* @param {number} newOffset
*/
*/
callOnStart
:
function
()
{
updateHandles
:
function
(
which
,
newOffset
)
{
if
(
this
.
options
.
onStart
)
{
if
(
which
===
'rzSliderModel'
)
{
var
self
=
this
;
this
.
updateLowHandle
(
newOffset
);
$timeout
(
function
()
{
this
.
updateSelectionBar
();
self
.
options
.
onStart
();
this
.
updateTicksScale
();
});
}
if
(
this
.
range
)
{
},
this
.
updateCmbLabel
();
}
return
;
}
if
(
which
===
'rzSliderHigh'
)
{
/**
this
.
updateHighHandle
(
newOffset
);
* Call the onChange callback if defined
this
.
updateSelectionBar
();
*
this
.
updateTicksScale
();
* @returns {undefined}
*/
callOnChange
:
function
()
{
if
(
this
.
options
.
onChange
)
{
var
self
=
this
;
$timeout
(
function
()
{
self
.
options
.
onChange
();
});
}
},
if
(
this
.
range
)
{
/**
this
.
updateCmbLabel
();
* Call the onEnd callback if defined
}
*
return
;
* @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
.
updateLowHandle
(
newOffset
);
this
.
updateHighHandle
(
newOffset
);
this
.
updateSelectionBar
();
this
.
updateSelectionBar
();
this
.
updateTicksScale
();
this
.
updateTicksScale
();
this
.
updateCmbLabel
();
},
/**
if
(
this
.
range
)
{
* Update low slider handle position and label
this
.
updateCmbLabel
();
*
* @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
{
return
;
flHidden
=
false
;
}
this
.
showEl
(
this
.
flrLab
);
if
(
which
===
'rzSliderHigh'
)
{
this
.
updateHighHandle
(
newOffset
);
this
.
updateSelectionBar
();
this
.
updateTicksScale
();
if
(
this
.
range
)
{
this
.
updateCmbLabel
();
}
}
return
;
}
// Update both
this
.
updateLowHandle
(
newOffset
);
this
.
updateHighHandle
(
newOffset
);
this
.
updateSelectionBar
();
this
.
updateTicksScale
();
this
.
updateCmbLabel
();
},
/**
* Update low slider handle position and label
*
* @param {number} newOffset
* @returns {undefined}
*/
updateLowHandle
:
function
(
newOffset
)
{
this
.
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
)
{
if
(
this
.
minLab
.
rzsl
+
this
.
minLab
.
rzsw
>=
this
.
ceilLab
.
rzsl
-
this
.
handleHalfWidth
-
10
)
{
clHidden
=
true
;
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
);
this
.
hideEl
(
this
.
ceilLab
);
}
}
else
if
(
!
clHidden
)
{
else
{
clHidden
=
false
;
this
.
showEl
(
this
.
ceilLab
);
this
.
showEl
(
this
.
ceilLab
);
}
}
if
(
this
.
range
)
{
// Hide or show floor label
if
(
this
.
maxLab
.
rzsl
+
this
.
maxLab
.
rzsw
>=
this
.
ceilLab
.
rzsl
-
10
)
{
if
(
this
.
maxLab
.
rzsl
<=
this
.
flrLab
.
rzsl
+
this
.
flrLab
.
rzsw
+
this
.
handleHalfWidth
)
{
this
.
hideEl
(
this
.
ceilLab
);
this
.
hideEl
(
this
.
flrLab
);
}
}
else
if
(
!
flHidden
)
{
else
if
(
!
clHidden
)
{
this
.
showEl
(
this
.
flrLab
);
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
);
}
}
}
},
}
},
/**
/**
* Update slider selection bar, combined label and range label
* Update slider selection bar, combined label and range label
*
*
* @returns {undefined}
* @returns {undefined}
*/
*/
updateSelectionBar
:
function
()
{
updateSelectionBar
:
function
()
{
this
.
setWidth
(
this
.
selBar
,
Math
.
abs
(
this
.
maxH
.
rzsl
-
this
.
minH
.
rzsl
)
+
this
.
handleHalfWidth
);
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
);
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
);
}
},
/**
/**
* Return the translated value if a translate function is provided else the original value
* Update combined label position and value
* @param value
*
* @returns {*}
* @returns {undefined}
*/
*/
getDisplayValue
:
function
(
value
)
{
updateCmbLabel
:
function
()
{
return
this
.
customTrFn
(
value
,
this
.
options
.
id
);
var
lowTr
,
highTr
;
},
if
(
this
.
minLab
.
rzsl
+
this
.
minLab
.
rzsw
+
10
>=
this
.
maxLab
.
rzsl
)
{
/**
lowTr
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderModel
);
* Round value to step and precision
highTr
=
this
.
getDisplayValue
(
this
.
scope
.
rzSliderHigh
);
*
* @param {number} value
this
.
translateFn
(
lowTr
+
' - '
+
highTr
,
this
.
cmbLab
,
false
);
* @returns {number}
this
.
setLeft
(
this
.
cmbLab
,
this
.
selBar
.
rzsl
+
this
.
selBar
.
rzsw
/
2
-
this
.
cmbLab
.
rzsw
/
2
);
*/
this
.
hideEl
(
this
.
minLab
);
roundStep
:
function
(
value
)
{
this
.
hideEl
(
this
.
maxLab
);
var
step
=
this
.
step
,
this
.
showEl
(
this
.
cmbLab
);
remainder
=
+
((
value
-
this
.
minValue
)
%
step
).
toFixed
(
3
),
}
else
{
steppedValue
=
remainder
>
(
step
/
2
)
?
value
+
step
-
remainder
:
value
-
remainder
;
this
.
showEl
(
this
.
maxLab
);
this
.
showEl
(
this
.
minLab
);
steppedValue
=
steppedValue
.
toFixed
(
this
.
precision
);
this
.
hideEl
(
this
.
cmbLab
);
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
;
}
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
* Round value to step and precision
*
*
* @param {jqLite} elem The jqLite wrapped DOM element
* @param {number} value
* @param {number} left
* @returns {number}
* @returns {number}
*/
*/
roundStep
:
function
(
value
)
{
setLeft
:
function
(
elem
,
left
)
{
var
step
=
this
.
step
,
elem
.
rzsl
=
left
;
remainder
=
+
((
value
-
this
.
minValue
)
%
step
).
toFixed
(
3
),
elem
.
css
({
left
:
left
+
'px'
});
steppedValue
=
remainder
>
(
step
/
2
)
?
value
+
step
-
remainder
:
value
-
remainder
;
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
;
},
// Events
steppedValue
=
steppedValue
.
toFixed
(
this
.
precision
);
return
+
steppedValue
;
},
/**
/**
* Get the X-coordinate of an event
* Hide element
*
*
* @param {Object} event The event
* @param element
* @returns {number}
* @returns {jqLite} The jqLite wrapped DOM element
*/
*/
getEventX
:
function
(
event
)
{
hideEl
:
function
(
element
)
{
/* http://stackoverflow.com/a/12336075/282882 */
return
element
.
css
({
//noinspection JSLint
opacity
:
0
if
(
'clientX'
in
event
)
{
});
return
event
.
clientX
;
},
}
return
event
.
originalEvent
===
undefined
?
/**
event
.
touches
[
0
].
clientX
* Show element
:
event
.
originalEvent
.
touches
[
0
].
clientX
;
*
},
* @param element The jqLite wrapped DOM element
* @returns {jqLite} The jqLite
*/
showEl
:
function
(
element
)
{
if
(
!!
element
.
rzAlwaysHide
)
{
return
element
;
}
/**
return
element
.
css
({
* Get the handle closest to an event.
opacity
:
1
*
});
* @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
;
}
this
.
minH
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
minH
,
'rzSliderModel'
));
/**
if
(
this
.
range
)
{
* Set element left offset
this
.
maxH
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
maxH
,
'rzSliderHigh'
));
*
}
* @param {jqLite} elem The jqLite wrapped DOM element
this
.
fullBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
* @param {number} left
this
.
fullBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
fullBar
));
* @returns {number}
this
.
selBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
barStart
,
null
,
barTracking
));
*/
this
.
selBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
barMove
,
this
.
selBar
));
setLeft
:
function
(
elem
,
left
)
{
this
.
ticks
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
elem
.
rzsl
=
left
;
this
.
ticks
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
ticks
));
elem
.
css
({
left
:
left
+
'px'
this
.
minH
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
minH
,
'rzSliderModel'
));
});
if
(
this
.
range
)
{
return
left
;
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
();
* 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.
* Translate value to pixel offset
this
.
calcViewDimensions
();
*
* @param {number} val
* @returns {number}
*/
valueToOffset
:
function
(
val
)
{
return
(
this
.
sanitizeOffsetValue
(
val
)
-
this
.
minValue
)
*
this
.
maxLeft
/
this
.
valueRange
||
0
;
},
if
(
pointer
)
{
/**
this
.
tracking
=
ref
;
* Ensure that the position rendered is within the slider bounds, even if the value is not
}
*
else
{
* @param {number} val
pointer
=
this
.
getNearestHandle
(
event
);
* @returns {number}
this
.
tracking
=
pointer
===
this
.
minH
?
'rzSliderModel'
:
'rzSliderHigh'
;
*/
}
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
);
// Events
ehEnd
=
angular
.
bind
(
this
,
this
.
onEnd
,
ehMove
);
$document
.
on
(
eventNames
.
moveEvent
,
ehMove
);
/**
$document
.
one
(
eventNames
.
endEvent
,
ehEnd
);
* Get the X-coordinate of an event
this
.
callOnStart
();
*
},
* @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
;
}
/**
return
event
.
originalEvent
===
undefined
?
* onMove event handler
event
.
touches
[
0
].
clientX
:
event
.
originalEvent
.
touches
[
0
].
clientX
;
*
},
* @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
);
/**
},
* 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
* Bind mouse and touch events to slider handles
*
*
* @param {number} newMinValue the new minimum value
* @returns {undefined}
* @param {number} newMaxValue the new maximum value
*/
* @param {number} newMinOffset the new minimum offset
bindEvents
:
function
()
{
* @param {number} newMaxOffset the new maximum offset
if
(
this
.
options
.
readOnly
||
this
.
options
.
disabled
)
return
;
*/
var
barTracking
,
barStart
,
barMove
;
positionTrackingBar
:
function
(
newMinValue
,
newMaxValue
,
newMinOffset
,
newMaxOffset
)
{
this
.
scope
.
rzSliderModel
=
newMinValue
;
if
(
this
.
options
.
draggableRange
)
{
this
.
scope
.
rzSliderHigh
=
newMaxValue
;
barTracking
=
'rzSliderDrag'
;
this
.
updateHandles
(
'rzSliderModel'
,
newMinOffset
);
barStart
=
this
.
onDragStart
;
this
.
updateHandles
(
'rzSliderHigh'
,
newMaxOffset
);
barMove
=
this
.
onDragMove
;
this
.
scope
.
$apply
();
}
else
{
this
.
callOnChange
();
barTracking
=
'rzSliderModel'
;
},
barStart
=
this
.
onStart
;
barMove
=
this
.
onMove
;
}
/**
this
.
minH
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
minH
,
'rzSliderModel'
));
* Set the new value and offset to the current tracking handle
if
(
this
.
range
)
{
*
this
.
maxH
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
maxH
,
'rzSliderHigh'
));
* @param {number} newValue new model value
}
* @param {number} newOffset new offset value
this
.
fullBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
*/
this
.
fullBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
fullBar
));
positionTrackingHandle
:
function
(
newValue
,
newOffset
)
{
this
.
selBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
barStart
,
null
,
barTracking
));
if
(
this
.
range
)
{
this
.
selBar
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
barMove
,
this
.
selBar
));
/* This is to check if we need to switch the min and max handles*/
this
.
ticks
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
if
(
this
.
tracking
===
'rzSliderModel'
&&
newValue
>=
this
.
scope
.
rzSliderHigh
)
{
this
.
ticks
.
on
(
'mousedown'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
ticks
));
this
.
scope
[
this
.
tracking
]
=
this
.
scope
.
rzSliderHigh
;
this
.
updateHandles
(
this
.
tracking
,
this
.
maxH
.
rzsl
);
this
.
minH
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
minH
,
'rzSliderModel'
));
this
.
tracking
=
'rzSliderHigh'
;
if
(
this
.
range
)
{
this
.
minH
.
removeClass
(
'rz-active'
);
this
.
maxH
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
this
.
maxH
,
'rzSliderHigh'
));
this
.
maxH
.
addClass
(
'rz-active'
);
}
/* We need to apply here because we are not sure that we will enter the next block */
this
.
fullBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
this
.
scope
.
$apply
();
this
.
fullBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
fullBar
));
this
.
callOnChange
();
this
.
selBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
barStart
,
null
,
barTracking
));
}
this
.
selBar
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
barMove
,
this
.
selBar
));
else
if
(
this
.
tracking
===
'rzSliderHigh'
&&
newValue
<=
this
.
scope
.
rzSliderModel
)
{
this
.
ticks
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onStart
,
null
,
null
));
this
.
scope
[
this
.
tracking
]
=
this
.
scope
.
rzSliderModel
;
this
.
ticks
.
on
(
'touchstart'
,
angular
.
bind
(
this
,
this
.
onMove
,
this
.
ticks
));
this
.
updateHandles
(
this
.
tracking
,
this
.
minH
.
rzsl
);
},
this
.
tracking
=
'rzSliderModel'
;
this
.
maxH
.
removeClass
(
'rz-active'
);
/**
this
.
minH
.
addClass
(
'rz-active'
);
* Unbind mouse and touch events to slider handles
/* We need to apply here because we are not sure that we will enter the next block */
*
this
.
scope
.
$apply
();
* @returns {undefined}
this
.
callOnChange
();
*/
}
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
;
* Set the new value and offset to the current tracking handle
this
.
updateHandles
(
this
.
tracking
,
newOffset
);
*
* @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
.
scope
.
$apply
();
this
.
callOnChange
();
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'
);
if
(
this
.
scope
[
this
.
tracking
]
!==
newValue
)
{
this
.
maxH
.
removeClass
(
'rz-active'
);
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
.
minH
.
removeClass
(
'rz-active
'
);
this
.
tracking
=
''
;
this
.
maxH
.
removeClass
(
'rz-active'
)
;
this
.
dragging
.
active
=
false
;
$document
.
off
(
moveEventName
,
ehMove
);
this
.
callOnEnd
();
},
/**
this
.
scope
.
$emit
(
'slideEnded'
);
* Get event names for move and event end
this
.
tracking
=
''
;
*
* @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
))
{
this
.
dragging
.
active
=
false
;
eventNames
.
moveEvent
=
'touchmove'
;
this
.
callOnEnd
();
eventNames
.
endEvent
=
'touchend'
;
},
}
else
{
eventNames
.
moveEvent
=
'mousemove'
;
eventNames
.
endEvent
=
'mouseup'
;
}
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
)
{
return
Slider
;
'use strict'
;
})
return
{
.
directive
(
'rzslider'
,
function
(
RzSlider
)
{
restrict
:
'E'
,
'use strict'
;
scope
:
{
rzSliderModel
:
'=?'
,
rzSliderHigh
:
'=?'
,
rzSliderOptions
:
'=?'
,
rzSliderTplUrl
:
'@'
},
/**
* Return template URL
*
* @param {jqLite} elem
* @param {Object} attrs
* @return {string}
*/
templateUrl
:
function
(
elem
,
attrs
)
{
//noinspection JSUnresolvedVariable
return
attrs
.
rzSliderTplUrl
||
'rzSliderTpl.html'
;
},
link
:
function
(
scope
,
elem
)
{
return
{
return
new
RzSlider
(
scope
,
elem
);
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
* @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