Commit 2c3ca884 authored by Valentin Hervieu's avatar Valentin Hervieu

Merge pull request #158 from rzajac/2.0.0

Refactor to add an rzSliderOptions attribute
parents d26c0eaf 51cd1bfb
# 2.0.0 (2015-11-XX)
## Breaking changes
- All attributes except `rzSliderModel` and `rzSliderHigh` are moved to `rzSliderOptions`. (See the new documentation in ReadMe)
## Features
- Add a `rzSliderOptions` attribute to pass options to the slider.
- Add a `RzSliderOptions.options()` method to set global options.
- Add a `scale` option to fix sliders displayed in an element that uses `transform: scale(0.5)`.
- Add a `stepsArray` option (#163)
- Add an `id` option that is passed to the translate function as second arg (#161)
- Add a `ticksValuesTooltip` option that is used to display a tooltip on the ticks values (requires angular-ui bootstrap).
# 1.1.0 (2015-11-07) # 1.1.0 (2015-11-07)
## Features ## Features
- Configurable update interval (#153) - Configurable update interval (#153)
......
...@@ -71,16 +71,17 @@ module.exports = function(grunt) { ...@@ -71,16 +71,17 @@ module.exports = function(grunt) {
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: [ files: [{
{expand: true, flatten: true, src: ['src/rzslider.js'], dest: 'dist/'} expand: true,
] flatten: true,
src: ['src/rzslider.js'],
dest: 'dist/'
}]
} }
}, },
...@@ -94,8 +95,7 @@ module.exports = function(grunt) { ...@@ -94,8 +95,7 @@ module.exports = function(grunt) {
}, { }, {
expand: true, expand: true,
src: ['dist/rzslider.js'] src: ['dist/rzslider.js']
} }]
]
} }
}, },
watch: { watch: {
......
## AngularJS slider directive with no external dependencies ## AngularJS slider directive with no external dependencies
> **A refactoring is on-going, any feedback is welcome:** https://github.com/rzajac/angularjs-slider/pull/158
Slider directive implementation for AngularJS, without any dependencies. Slider directive implementation for AngularJS, without any dependencies.
- Mobile friendly - Mobile friendly
...@@ -14,7 +12,6 @@ Slider directive implementation for AngularJS, without any dependencies. ...@@ -14,7 +12,6 @@ Slider directive implementation for AngularJS, without any dependencies.
## Examples ## Examples
- **Various examples:** [http://rzajac.github.io/angularjs-slider/](http://rzajac.github.io/angularjs-slider/index.html) - **Various examples:** [http://rzajac.github.io/angularjs-slider/](http://rzajac.github.io/angularjs-slider/index.html)
- **Slider inside Angular UI tabs:** http://jsfiddle.net/7w755fLv/
## Reporting issues ## Reporting issues
Make sure the report is accompanied by a reproducible demo. The ideal demo is created by forking [our standard jsFiddle](http://jsfiddle.net/1ruqgnhk/), adding your own code and stripping it down to an absolute minimum needed to demonstrate the bug. Make sure the report is accompanied by a reproducible demo. The ideal demo is created by forking [our standard jsFiddle](http://jsfiddle.net/1ruqgnhk/), adding your own code and stripping it down to an absolute minimum needed to demonstrate the bug.
...@@ -33,7 +30,7 @@ $ bower install --save angularjs-slider ...@@ -33,7 +30,7 @@ $ bower install --save angularjs-slider
### Module ### Module
```javascript ```javascript
angular.module('', ['rzModule']); angular.module('yourApp', ['rzModule']);
``` ```
### Single slider ### Single slider
...@@ -49,42 +46,56 @@ $scope.priceSlider = 150; ...@@ -49,42 +46,56 @@ $scope.priceSlider = 150;
</div> </div>
``` ```
Above example would render a slider from 0 to 150. If you need floor and ceiling values use `rz-slider-floor` and `rz-slider-ceil` attributes. Above example would render a slider from 0 to 150. If you need floor and ceiling values use `rz-slider-options` attribute and provide an object with `floor`and `ceil`.
```html ```html
<div> <div>
<rzslider <rzslider
rz-slider-model="priceSlider" rz-slider-model="slider.value"
rz-slider-ceil="450"></rzslider> rz-slider-options="slider.options"></rzslider>
</div>
<!-- OR --> ```
```js
$scope.slider = {
value: 150,
options: {
floor: 0,
ceil: 450
}
};
```
If you don't want to bother with an object set in your javascript file, you can pass an anonymous object literal to the slider options:
```html
<div>
<rzslider <rzslider
rz-slider-model="priceSlider" rz-slider-model="value"
rz-slider-floor="0" rz-slider-options="{floor: 0, ceil: 450}"></rzslider>
rz-slider-ceil="450"></rzslider>
</div> </div>
``` ```
```js
$scope.value = 150;
```
### Range slider ### Range slider
```javascript ```javascript
// In your controller // In your controller
$scope.priceSlider = { $scope.slider = {
min: 100, min: 100,
max: 180, max: 180,
ceil: 500, options: {
floor: 0 floor: 0,
ceil: 450
}
}; };
``` ```
```html ```html
<rzslider <rzslider
rz-slider-floor="priceSlider.floor" rz-slider-model="slider.min"
rz-slider-ceil="priceSlider.ceil" rz-slider-high="slider.max"
rz-slider-model="priceSlider.min" rz-slider-options="slider.options"></rzslider>
rz-slider-high="priceSlider.max"></rzslider>
``` ```
## Directive attributes ## Directive attributes
...@@ -95,107 +106,109 @@ $scope.priceSlider = { ...@@ -95,107 +106,109 @@ $scope.priceSlider = {
**rz-slider-high** **rz-slider-high**
> Model for high value slider. Providing both _rz-slider-high_ and _rz-slider-model_ will render range slider. > Model for high value slider. Providing both _rz-slider-model_ and _rz-slider-high_ will render range slider.
**rz-slider-floor**
> Minimum value for a slider.
**rz-slider-ceil**
> Maximum value for a slider.
**rz-slider-step**
> slider step.
**rz-slider-precision**
> The precision to display values with. The `toFixed()` is used internally for this.
**rz-slider-hide-limit-labels**
> Set to true to hide min / max labels
**rz-slider-always-show-bar**
> Set to true to always show selection bar
**rz-slider-present-only**
> When set to true slider is used in presentation mode. No handle dragging. **rz-slider-options**
**rz-slider-draggable-range** > An object with all the other options of the slider. Each option can be updated at runtime and the slider will automatically be re-rendered.
> When set to true and using a range slider, the range can be dragged by the selection bar. The default options are:
```js
{
floor: 0,
ceil: null, //defaults to rz-slider-model
step: 1,
precision: 0,
translate: null,
id: null,
stepsArray: null,
draggableRange: false,
showSelectionBar: false,
hideLimitLabels: false,
readOnly: false,
disabled: false,
interval: 350,
showTicks: false,
showTicksValues: false,
scale: 1,
onStart: null,
onChange: null,
onEnd: null
}
````
**rz-slider-translate** **floor** - _Number (defaults to 0)_: Minimum value for a slider.
> Custom translate function. Use this if you want to translate values displayed on the slider. For example if you want to display dollar amounts instead of just numbers do this: **ceil** - _Number (defaults to `rz-slider-model`value)_: Maximum value for a slider.
**rz-slider-on-start** **step** - _Number (defaults to 1)_: Step between each value.
> Function to be called when a slider update is started. **precision** - _Number (defaults to 0)_: The precision to display values with. The `toFixed()` is used internally for this.
**rz-slider-on-change** **translate** - _Function(value, sliderId)_: Custom translate function. Use this if you want to translate values displayed on the slider. For example if you want to display dollar amounts instead of just numbers:
```html
<div>
<rzslider
rz-slider-model="slider.value"
rz-slider-options="slider.options"></rzslider>
</div>
```
```js
$scope.slider = {
value: 0,
options: {
floor: 0,
ceil: 100,
translate: function(value) {
return '$' + value;
}
}
};
```
> Function to be called when rz-slider-model or rz-slider-high change. **id** - _Any (defaults to null)_: If you want to use the same `translate` function for several sliders, just set the `id` to anything you want, and it will be passed to the `translate(value, sliderId)` function as a second argument.
**rz-slider-on-end** **stepsArray** - _Array_: If you want to display a slider with non linear/number steps. Just pass an array with each slider value and that's it; the floor, ceil and step settings of the slider will be computed automatically. The `rz-slider-model` value will be the index of the selected item in the stepsArray.
> Function to be called when a slider update is ended. **draggableRange** - _Boolean (defaults to false)_: When set to true and using a range slider, the range can be dragged by the selection bar. _This doesn't work when ticks are shown._
**rz-slider-show-ticks** **showSelectionBar** - _Boolean (defaults to false)_: Set to true to always show the selection bar.
> Display a tick for each value. **hideLimitLabels** - _Boolean (defaults to false)_: Set to true to hide min / max labels
**rz-slider-show-ticks-value** **readOnly** - _Boolean (defaults to false)_: Set to true to make the slider read-only.
> Display a tick for each value and the value of the tick. **disabled** - _Boolean (defaults to false)_: Set to true to disable the slider.
**rz-slider-disabled** **interval** - _Number in ms (defaults to 350)_: Internally, a `throttle` function (See http://underscorejs.org/#throttle) is used when the model or high values of the slider are changed from outside the slider. This is to prevent from re-rendering the slider too many times in a row. `interval` is the number of milliseconds to wait between two updates of the slider.
> Disable the slider (apply a special style and unbind events) **showTicks** - _Boolean (defaults to false)_: Set to true to display a tick for each step of the slider.
**rz-slider-interval** **showTicksValues** - _Boolean (defaults to false)_: Set to true to display a tick and the step value for each step of the slider.
> The interval (in ms) at which the slider DOM element updates when rz-slider-model or rz-slider-high change from outside the slider. Defaults to 350. **ticksValuesTooltip** - _Function(value) (defaults to null)_: (requires angular-ui bootstrap) Used to display a tooltip when a tick value is hovered. Set to a function that returns the tooltip content for a given value.
```javascript **scale** - _Number (defaults to 1)_: If you display the slider in an element that uses `transform: scale(0.5)`, set the `scale` value to 2 so that the slider is rendered properly and the events are handled correctly.
// In your controller
$scope.priceSlider = { **onStart** - _Function()_: Function to be called when a slider update is started.
min: 100,
max: 180,
ceil: 500,
floor: 0
};
$scope.translate = function(value) **onChange** - _Function()_: Function to be called when rz-slider-model or rz-slider-high change.
{
return '$' + value;
}
$scope.onSliderChange = function() **onEnd** - _Function()_: Function to be called when a slider update is ended.
{
console.log('changed', $scope.priceSlider);
}
```
```html ## Change default options
<rzslider If you want the change the default options for all the sliders displayed in your application, you can set them using the `RzSliderOptions.options()` method:
rz-slider-floor="priceSlider.floor" ```js
rz-slider-ceil="priceSlider.ceil" angular.module('App', ['rzModule'])
rz-slider-model="priceSlider.min" .run(function( RzSliderOptions ) {
rz-slider-high="priceSlider.max" // show ticks for all sliders
rz-slider-translate="translate" RzSliderOptions.options( { showTicks: true } );
rz-slider-on-change="onSliderChange()" });
rz-slider-show-ticks="true"></rzslider>
``` ```
## Slider events ## Slider events
To force slider to recalculate dimensions broadcast **reCalcViewDimensions** event from parent scope. This is useful for example when you use slider inside a widget where the content is hidden at start - see the "Sliders into modal" example [on the demo site](http://rzajac.github.io/angularjs-slider/). To force slider to recalculate dimensions, broadcast **reCalcViewDimensions** event from parent scope. This is useful for example when you use slider inside a widget where the content is hidden at start - see the "Sliders into modal" example [on the demo site](http://rzajac.github.io/angularjs-slider/).
You can also force redraw with **rzSliderForceRender** event. You can also force redraw with **rzSliderForceRender** event.
...@@ -220,13 +233,12 @@ $scope.$on("slideEnded", function() { ...@@ -220,13 +233,12 @@ $scope.$on("slideEnded", function() {
## Browser support ## Browser support
I use Slider on couple of my projects and it's being tested on desktop versions of Chrome, Firefox, Safari, IE 9/10. I use Slider on couple of my projects and it's being tested on desktop versions of Chrome, Firefox, Safari, IE 9/10 (Ticks are displayed using flex display so they don't work on IE9).
Slider is also tested on Android and iPhone using all browsers available on those platforms. Slider is also tested on Android and iPhone using all browsers available on those platforms.
## Disclaimer ## Disclaimer
This project is based on [https://github.com/prajwalkman/angular-slider](https://github.com/prajwalkman/angular-slider). It has been rewritten from scratch in JavaScript This project is based on [https://github.com/prajwalkman/angular-slider](https://github.com/prajwalkman/angular-slider). It has been rewritten from scratch in JavaScript (the original source was written in CoffeeScript).
(the original source was written in CoffeeScript).
## License ## License
......
{ {
"name": "angularjs-slider", "name": "angularjs-slider",
"version": "1.1.0", "version": "2.0.0",
"homepage": "https://github.com/rzajac/angularjs-slider", "homepage": "https://github.com/rzajac/angularjs-slider",
"authors": [ "authors": [
"Rafal Zajac <rzajac@gmail.com>", "Rafal Zajac <rzajac@gmail.com>",
......
* { margin: 0; padding: 0; } * { margin: 0; padding: 0; }
body { font-family: 'Open Sans', sans-serif; color: #1f2636; font-size: 14px; } body { font-family: 'Open Sans', sans-serif; color: #1f2636; font-size: 14px; padding-bottom: 40px; }
header { background: #0db9f0; color: #fff; margin: -40px; margin-bottom: 40px; text-align: center; padding: 40px 0; } header { background: #0db9f0; color: #fff; margin: -40px; margin-bottom: 40px; text-align: center; padding: 40px 0; }
h1 { font-weight: 300; } h1 { font-weight: 300; }
h2 {margin-bottom:10px;}
.wrapper { background: #fff; padding: 40px; } .wrapper { background: #fff; padding: 40px; }
article { margin-bottom: 40px; } article { margin-bottom: 10px; }
.tab-pane{
padding-top: 10px;
}
.field-title {
width: 100px;
}
var app = angular.module('rzSliderDemo', ['rzModule', 'ui.bootstrap']);
app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) {
//Minimal slider config
$scope.minSlider = {
value: 10
};
//Slider with selection bar
$scope.slider_visible_bar = {
value: 10,
options: {
showSelectionBar: true
}
};
//Range slider config
$scope.minRangeSlider = {
minValue: 10,
maxValue: 90,
options: {
floor: 0,
ceil: 100,
step: 1
}
};
//Slider config with floor, ceil and step
$scope.slider_floor_ceil = {
value: 12,
options: {
floor: 10,
ceil: 100,
step: 5
}
};
//Slider config with callbacks
$scope.slider_callbacks = {
value: 100,
options: {
onStart: function() {
$scope.otherData.start = $scope.slider_callbacks.value * 10;
},
onChange: function() {
$scope.otherData.change = $scope.slider_callbacks.value * 10;
},
onEnd: function() {
$scope.otherData.end = $scope.slider_callbacks.value * 10;
}
}
};
$scope.otherData = {start: 0, change: 0, end: 0};
//Slider config with custom display function
$scope.slider_translate = {
minValue: 100,
maxValue: 400,
options: {
ceil: 500,
floor: 0,
translate: function(value) {
return '$' + value;
}
}
};
//Slider config with steps array of letters
$scope.slider_alphabet = {
value: 0,
options: {
stepsArray:'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('')
}
};
//Slider with ticks
$scope.slider_ticks = {
value: 5,
options: {
ceil: 10,
floor: 0,
showTicks: true
}
};
//Slider with ticks and values
$scope.slider_ticks_values = {
value: 5,
options: {
ceil: 10,
floor: 0,
showTicksValues: true,
ticksValuesTooltip: function(v) {
return 'Tooltip for ' + v;
}
}
};
//Range slider with ticks and values
$scope.range_slider_ticks_values = {
minValue: 1,
maxValue: 8,
options: {
ceil: 10,
floor: 0,
showTicksValues: true
}
};
//Slider with draggable range
$scope.slider_draggable_range = {
minValue: 1,
maxValue: 8,
options: {
ceil: 10,
floor: 0,
draggableRange: true
}
};
//Read-only slider
$scope.read_only_slider = {
value: 50,
options: {
ceil: 100,
floor: 0,
readOnly: true
}
};
//Disabled slider
$scope.disabled_slider = {
value: 50,
options: {
ceil: 100,
floor: 0,
disabled: true
}
};
// Slider inside ng-show
$scope.visible = false;
$scope.slider_toggle = {
value: 5,
options: {
ceil: 10,
floor: 0
}
};
$scope.toggle = function() {
$scope.visible = !$scope.visible;
$timeout(function() {
$scope.$broadcast('rzSliderForceRender');
});
};
//Slider inside modal
$scope.percentages = {
normal: {
low: 15
},
range: {
low: 10,
high: 50
}
};
$scope.openModal = function() {
var modalInstance = $modal.open({
templateUrl: 'sliderModal.html',
controller: function($scope, $modalInstance, values) {
$scope.percentages = JSON.parse(JSON.stringify(values)); //Copy of the object in order to keep original values in $scope.percentages in parent controller.
var formatToPercentage = function(value) {
return value + '%';
};
$scope.percentages.normal.options = {
floor: 0,
ceil: 100,
translate: formatToPercentage,
showSelectionBar: true
};
$scope.percentages.range.options = {
floor: 0,
ceil: 100,
translate: formatToPercentage
};
$scope.ok = function() {
$modalInstance.close($scope.percentages);
};
$scope.cancel = function() {
$modalInstance.dismiss();
};
},
resolve: {
values: function() {
return $scope.percentages;
}
}
});
modalInstance.result.then(function(percentages) {
$scope.percentages = percentages;
});
modalInstance.rendered.then(function() {
$rootScope.$broadcast('rzSliderForceRender');//Force refresh sliders on render. Otherwise bullets are aligned at left side.
});
};
//Slider inside tabs
$scope.tabSliders = {
slider1: {
value: 100
},
slider2: {
value: 200
}
};
$scope.refreshSlider = function() {
$timeout(function() {
$scope.$broadcast('rzSliderForceRender');
});
};
//Slider with draggable range
$scope.slider_all_options = {
minValue: 2,
options: {
floor: 0,
ceil: 10,
step: 1,
precision: 0,
draggableRange: false,
showSelectionBar: false,
hideLimitLabels: false,
readOnly: false,
disabled: false,
showTicks: false,
showTicksValues: false
}
};
$scope.toggleHighValue = function() {
if($scope.slider_all_options.maxValue != null) {
$scope.slider_all_options.maxValue = undefined;
}
else {
$scope.slider_all_options.maxValue = 8;
}
}
});
...@@ -5,8 +5,10 @@ ...@@ -5,8 +5,10 @@
<meta charset="utf-8"/> <meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>AngularJS Touch Slider</title> <title>AngularJS Touch Slider</title>
<link rel="stylesheet" href="demo.css"/> <!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<link rel="stylesheet" href="../dist/rzslider.css"/> <link rel="stylesheet" href="../dist/rzslider.css"/>
<link rel="stylesheet" href="demo.css"/>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300,400,700' rel='stylesheet' type='text/css'> <link href='http://fonts.googleapis.com/css?family=Open+Sans:300,400,700' rel='stylesheet' type='text/css'>
</head> </head>
...@@ -18,224 +20,187 @@ ...@@ -18,224 +20,187 @@
</header> </header>
<article> <article>
<h2>Min/max slider example</h2> <h2>Simple slider</h2>
Value: Model: <input type="number" ng-model="minSlider.value"/><br/>
<pre>{{ slider_data | json }}</pre> <rzslider rz-slider-model="minSlider.value"></rzslider>
<p>Value linked on change: {{ otherData.value }}</p> </article>
<article>
<h2>Range slider</h2>
Min Value: <input type="number" ng-model="minRangeSlider.minValue"/><br/>
Max Value: <input type="number" ng-model="minRangeSlider.maxValue"/><br/>
<rzslider <rzslider
rz-slider-floor="0.5" rz-slider-model="minRangeSlider.minValue"
rz-slider-ceil="10.5" rz-slider-high="minRangeSlider.maxValue"
rz-slider-step="0.3" rz-slider-options="minRangeSlider.options"
rz-slider-precision="1" ></rzslider>
rz-slider-model="slider_data.value"
rz-slider-on-start="onStart()"
rz-slider-on-change="onChange()"
rz-slider-on-end="onEnd()"></rzslider>
</article> </article>
<article> <article>
<h2>Min/max slider example</h2> <h2>Slider with visible selection bar</h2>
Value:
<pre>{{ priceSlider | json }}</pre>
<input type="text" ng-model="priceSlider.min"/><br/>
<input type="text" ng-model="priceSlider.max"/><br/>
<rzslider <rzslider
rz-slider-floor="priceSlider.floor" rz-slider-model="slider_visible_bar.value"
rz-slider-ceil="priceSlider.ceil" rz-slider-options="slider_visible_bar.options"
rz-slider-model="priceSlider.min" ></rzslider>
rz-slider-high="priceSlider.max"
rz-slider-step="6"
rz-slider-tpl-url="rzSliderTpl.html"></rzslider>
</article> </article>
<article> <article>
<h2>Currency slider example</h2> <h2>Slider with custom floor/ceil/step</h2>
Value: {{ priceSlider2 | json }}
<rzslider <rzslider
rz-slider-floor="0" rz-slider-model="slider_floor_ceil.value"
rz-slider-ceil="450" rz-slider-options="slider_floor_ceil.options"
rz-slider-model="priceSlider2" ></rzslider>
rz-slider-translate="translate"
rz-slider-tpl-url="rzSliderTpl.html"></rzslider>
</article> </article>
<article> <article>
<h2>One value slider example</h2> <h2>Slider with callbacks on start, change and end</h2>
<p>Value linked on start: {{ otherData.start }}</p>
<p>Value linked on change: {{ otherData.change }}</p>
<p>Value linked on end: {{ otherData.end }}</p>
Value: {{ priceSlider3 | json }} <rzslider
<rzslider rz-slider-model="priceSlider3" rz-slider-model="slider_callbacks.value"
rz-slider-floor="50" rz-slider-options="slider_callbacks.options"
rz-slider-ceil="450" ></rzslider>
rz-slider-always-show-bar="true"
rz-slider-tpl-url="rzSliderTpl.html"></rzslider>
</article> </article>
<article> <article>
<h2>Alphabet slider example</h2> <h2>Slider with custom display function</h2>
Value: {{ alphabetTranslate(letter) }}
<rzslider <rzslider
rz-slider-floor="0" rz-slider-model="slider_translate.minValue"
rz-slider-ceil="letterMax" rz-slider-high="slider_translate.maxValue"
rz-slider-model="letter" rz-slider-options="slider_translate.options"
rz-slider-translate="alphabetTranslate" ></rzslider>
rz-slider-tpl-url="rzSliderTpl.html"></rzslider>
</article> </article>
<article> <article>
<h2>Slider with ticks example</h2> <h2>Slider with Alphabet</h2>
Value: {{ priceSlider4 | json }} <rzslider
<rzslider rz-slider-model="priceSlider4" rz-slider-model="slider_alphabet.value"
rz-slider-floor="0" rz-slider-options="slider_alphabet.options"
rz-slider-ceil="10" ></rzslider>
rz-slider-show-ticks="true"></rzslider>
</article> </article>
<article> <article>
<h2>Slider with ticks value example</h2> <h2>Slider with ticks</h2>
Value: {{ priceSlider5 | json }} <rzslider
<rzslider rz-slider-model="priceSlider5" rz-slider-model="slider_ticks.value"
rz-slider-floor="0" rz-slider-options="slider_ticks.options"
rz-slider-ceil="10" ></rzslider>
rz-slider-show-ticks-value="true"></rzslider>
</article> </article>
<article> <article>
<h2>Slider with ticks value and visible bar example</h2> <h2>Slider with ticks and values (and tooltips)</h2>
Value: {{ priceSlider6 | json }} <rzslider
<rzslider rz-slider-model="priceSlider6" rz-slider-model="slider_ticks_values.value"
rz-slider-floor="0.5" rz-slider-options="slider_ticks_values.options"
rz-slider-ceil="1.5" ></rzslider>
rz-slider-step="0.1"
rz-slider-precision="1"
rz-slider-always-show-bar="true"
rz-slider-show-ticks-value="true"></rzslider>
</article> </article>
<article> <article>
<h2>Range Slider with ticks value example</h2> <h2>Range slider with ticks and values</h2>
Value: {{ priceSlider7 | json }} <rzslider
<rzslider rz-slider-model="priceSlider7.min" rz-slider-model="range_slider_ticks_values.minValue"
rz-slider-high="priceSlider7.max" rz-slider-high="range_slider_ticks_values.maxValue"
rz-slider-floor="0" rz-slider-options="range_slider_ticks_values.options"
rz-slider-ceil="10" ></rzslider>
rz-slider-show-ticks-value="true"></rzslider>
</article> </article>
<article> <article>
<h2>Draggable range example</h2> <h2>Slider with draggable range</h2>
Value: <rzslider
<pre>{{ priceSlider | json }}</pre> rz-slider-model="slider_draggable_range.minValue"
rz-slider-high="slider_draggable_range.maxValue"
rz-slider-options="slider_draggable_range.options"
></rzslider>
</article>
<input type="text" ng-model="priceSlider.min"/><br/> <article>
<input type="text" ng-model="priceSlider.max"/><br/> <h2>Disabled slider</h2>
<label>Disabled <input type="checkbox" ng-model="disabled_slider.options.disabled"></label>
<rzslider
rz-slider-model="disabled_slider.value"
rz-slider-options="disabled_slider.options"
></rzslider>
</article>
<article>
<h2>Read-only slider</h2>
<label>Read-only <input type="checkbox" ng-model="read_only_slider.options.readOnly"></label>
<rzslider <rzslider
rz-slider-draggable-range="true" rz-slider-model="read_only_slider.value"
rz-slider-floor="priceSlider.floor" rz-slider-options="read_only_slider.options"
rz-slider-ceil="priceSlider.ceil" ></rzslider>
rz-slider-model="priceSlider.min"
rz-slider-high="priceSlider.max"
rz-slider-step="5"
rz-slider-tpl-url="rzSliderTpl.html"></rzslider>
</article> </article>
<article> <article>
<h2>Toggle slider example</h2> <h2>Toggle slider example</h2>
<button ng-click="toggle()">Show</button> <button ng-click="toggle()">{{ visible ? 'Hide' : 'Show' }}</button>
<br/>
<div ng-show="visible"> <div ng-show="visible">
<rzslider rz-slider-model="toggleSlider.value" <rzslider
rz-slider-floor="toggleSlider.floor" rz-slider-model="slider_toggle.value"
rz-slider-ceil="toggleSlider.ceil"></rzslider> rz-slider-options="slider_toggle.options"></rzslider>
</div> </div>
</article> </article>
<article> <article>
<h2>Disabled slider example</h2> <h2>Sliders inside a modal</h2>
<label>Disable slider <input type="checkbox" ng-model="disableSlider"></label> Normal slider value: {{percentages.normal.low}}%
<rzslider rz-slider-model="priceSlider8" </br>
rz-slider-floor="0" Range slider values: {{percentages.range.low}}% and {{percentages.range.high}}%
rz-slider-ceil="10" </br>
rz-slider-disabled="disableSlider"></rzslider> <button type="button" ng-click="openModal()" class="btn btn-default btn-lg">Open Modal!</button>
</article> </article>
</div> <article>
<h2>Sliders inside tabs</h2>
<p>Price 1: {{tabSliders.slider1.value}}</p>
<p>Price 2: {{tabSliders.slider2.value}}</p>
<tabset>
<tab heading="Slider 1" select="refreshSlider()">
<rzslider rz-slider-model="tabSliders.slider1.value"></rzslider>
</tab>
<tab heading="Slider 2" select="refreshSlider()">
<rzslider rz-slider-model="tabSliders.slider2.value"></rzslider>
</tab>
</tabset>
</article>
<article>
<h2>Slider with all options demo</h2>
<div class="row all-options">
<div class="col-md-4">
<label class="field-title">Min Value: </label><input type="number" ng-model="slider_all_options.minValue"/><br/>
<label class="field-title"><input type="checkbox" ng-click="toggleHighValue()"> Max Value: </label>
<input type="number" ng-model="slider_all_options.maxValue" ng-disabled="slider_all_options.maxValue == null"/><br/>
<label class="field-title">Floor: </label><input type="number" ng-model="slider_all_options.options.floor"/><br/>
<label class="field-title">Ceil: </label><input type="number" ng-model="slider_all_options.options.ceil"/><br/>
</div>
<div class="col-md-4">
<label class="field-title">Step: </label><input type="number" ng-model="slider_all_options.options.step"/><br/>
<label class="field-title">Precision: </label><input type="number" ng-model="slider_all_options.options.precision"/><br/>
<label>Hide limits <input type="checkbox" ng-model="slider_all_options.options.hideLimitLabels"></label><br/>
<label>Draggable range <input type="checkbox" ng-model="slider_all_options.options.draggableRange"></label>
</div>
<div class="col-md-4">
<label>Show ticks <input type="checkbox" ng-model="slider_all_options.options.showTicks"></label><br/>
<label>Show ticks values <input type="checkbox" ng-model="slider_all_options.options.showTicksValues"></label><br/>
<label>Disabled <input type="checkbox" ng-model="slider_all_options.options.disabled"></label><br/>
<label>Read-Only <input type="checkbox" ng-model="slider_all_options.options.readOnly"></label>
</div>
</div>
<rzslider
rz-slider-model="slider_all_options.minValue"
rz-slider-high="slider_all_options.maxValue"
rz-slider-options="slider_all_options.options"
></rzslider>
</article>
</div>
</body>
<script src="../bower_components/angular/angular.js"></script> <script src="../bower_components/angular/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.14.3/ui-bootstrap-tpls.js"></script>
<script src="../dist/rzslider.js"></script> <script src="../dist/rzslider.js"></script>
<script> <script src="demo.js"></script>
var app = angular.module('rzSliderDemo', ['rzModule']);
app.controller('MainCtrl', function($scope, $timeout) {
$scope.priceSlider = {
min: 100,
max: 400,
ceil: 500,
floor: 0
};
$scope.priceSlider2 = 150;
$scope.priceSlider3 = 250;
$scope.priceSlider4 = 5;
$scope.priceSlider5 = 5;
$scope.priceSlider6 = 1;
$scope.priceSlider7 = {
min: 2,
max: 8
};
$scope.priceSlider8 = 5;
$scope.disableSlider = true;
$scope.translate = function(value) {
return '$' + value;
};
var alphabetArray = 'abcdefghijklmnopqrstuvwxyz'.split('');
$scope.letter = 5;
$scope.letterMax = alphabetArray.length - 1;
$scope.alphabetTranslate = function(value) {
return alphabetArray[value].toUpperCase();
};
$scope.slider_data = {value: 1};
$scope.otherData = {value: 10};
$scope.onStart = function() {
console.info('started', $scope.slider_data.value);
};
$scope.onChange = function() {
console.info('changed', $scope.slider_data.value);
$scope.otherData.value = $scope.slider_data.value * 10;
};
$scope.onEnd = function() {
console.info('ended', $scope.slider_data.value);
};
$scope.visible = false;
$scope.toggle = function() {
$scope.visible = !$scope.visible;
$timeout(function() {
$scope.$broadcast('rzSliderForceRender');
});
};
$scope.toggleSlider = {
value: 1,
ceil: 500,
floor: 0
};
});
</script>
</body>
</html> </html>
<div class="modal-body">
<div class="container-fluid">
<div class="row">
<div class="col-md-12 col-lg-12">
<label class="control-label">Normal slider into modal</label>
<rzslider
rz-slider-model="percentages.normal.low"
rz-slider-options="percentages.normal.options">
</rzslider>
</div>
</div>
<div class="row">
<div class=" col-md-12 col-lg-12">
<label class="control-label">Range slider into modal</label>
<rzslider
rz-slider-model="percentages.range.low"
rz-slider-high="percentages.range.high"
rz-slider-options="percentages.range.options">
</rzslider>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<button type="button" ng-click="ok()" class="btn btn-primary">Save</button>
<button type="button" ng-click="cancel()" class="btn btn-default">Cancel</button>
</div>
</div>
</div>
</div>
...@@ -16,7 +16,7 @@ rzslider { ...@@ -16,7 +16,7 @@ rzslider {
display: inline-block; display: inline-block;
width: 100%; width: 100%;
height: 4px; height: 4px;
margin: 30px 0 15px 0; margin: 35px 0 15px 0;
vertical-align: middle; vertical-align: middle;
-webkit-user-select: none; -webkit-user-select: none;
-moz-user-select: none; -moz-user-select: none;
...@@ -55,6 +55,10 @@ rzslider .rz-bar-wrapper { ...@@ -55,6 +55,10 @@ rzslider .rz-bar-wrapper {
box-sizing: border-box; box-sizing: border-box;
} }
rzslider .rz-bar-wrapper.rz-draggable {
cursor: move;
}
rzslider .rz-bar { rzslider .rz-bar {
left: 0; left: 0;
z-index: 1; z-index: 1;
......
...@@ -4,14 +4,14 @@ ...@@ -4,14 +4,14 @@
* (c) Rafal Zajac <rzajac@gmail.com> * (c) Rafal Zajac <rzajac@gmail.com>
* http://github.com/rzajac/angularjs-slider * http://github.com/rzajac/angularjs-slider
* *
* Version: v1.1.0 * Version: v1.0.0
* *
* Licensed under the MIT license * Licensed under the MIT license
*/ */
/*jslint unparam: true */ /*jslint unparam: true */
/*global angular: false, console: false, define, module */ /*global angular: false, console: false, define, module */
(function (root, factory) { (function(root, factory) {
'use strict'; 'use strict';
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module. // AMD. Register as an anonymous module.
...@@ -27,13 +27,59 @@ ...@@ -27,13 +27,59 @@
factory(root.angular); factory(root.angular);
} }
}(this, function (angular) { }(this, function(angular) {
'use strict'; 'use strict';
var module = angular.module('rzModule', []) var module = angular.module('rzModule', [])
.factory('RzSliderOptions', function() {
var defaultOptions = {
floor: 0,
ceil: null, //defaults to rz-slider-model
step: 1,
precision: 0,
id: null,
translate: null,
stepsArray: null,
draggableRange: false,
showSelectionBar: false,
hideLimitLabels: false,
readOnly: false,
disabled: false,
interval: 350,
showTicks: false,
showTicksValues: false,
ticksValuesTooltip: null,
scale: 1,
onStart: null,
onChange: null,
onEnd: null
};
var globalOptions = {};
var factory = {};
/**
* `options({})` allows global configuration of all sliders in the
* application.
*
* var app = angular.module( 'App', ['rzModule'], function( RzSliderOptions ) {
* // show ticks for all sliders
* RzSliderOptions.options( { showTicks: true } );
* });
*/
factory.options = function(value) {
angular.extend(globalOptions, value);
};
factory.getOptions = function(options) {
return angular.extend({}, defaultOptions, globalOptions, options);
};
.value('throttle', return factory;
})
.value('rzThrottle',
/** /**
* throttle * rzThrottle
* *
* Taken from underscore project * Taken from underscore project
* *
...@@ -42,7 +88,7 @@ var module = angular.module('rzModule', []) ...@@ -42,7 +88,7 @@ var module = angular.module('rzModule', [])
* @param {ThrottleOptions} options * @param {ThrottleOptions} options
* @returns {Function} * @returns {Function}
*/ */
function throttle(func, wait, options) { function throttle(func, wait, options) {
'use strict'; 'use strict';
var getTime = (Date.now || function() { var getTime = (Date.now || function() {
return new Date().getTime(); return new Date().getTime();
...@@ -59,7 +105,9 @@ function throttle(func, wait, options) { ...@@ -59,7 +105,9 @@ function throttle(func, wait, options) {
}; };
return function() { return function() {
var now = getTime(); var now = getTime();
if (!previous && options.leading === false) { previous = now; } if (!previous && options.leading === false) {
previous = now;
}
var remaining = wait - (now - previous); var remaining = wait - (now - previous);
context = this; context = this;
args = arguments; args = arguments;
...@@ -74,10 +122,9 @@ function throttle(func, wait, options) { ...@@ -74,10 +122,9 @@ function throttle(func, wait, options) {
} }
return result; return result;
}; };
}) })
.factory('RzSlider', ['$timeout', '$document', '$window', 'throttle', function($timeout, $document, $window, throttle) .factory('RzSlider', ['$timeout', '$document', '$window', '$compile', 'RzSliderOptions', 'rzThrottle', function($timeout, $document, $window, $compile, RzSliderOptions, rzThrottle) {
{
'use strict'; 'use strict';
/** /**
...@@ -85,11 +132,9 @@ function throttle(func, wait, options) { ...@@ -85,11 +132,9 @@ function throttle(func, wait, options) {
* *
* @param {ngScope} scope The AngularJS scope * @param {ngScope} scope The AngularJS scope
* @param {Element} sliderElem The slider directive element wrapped in jqLite * @param {Element} sliderElem The slider directive element wrapped in jqLite
* @param {*} attributes The slider directive attributes
* @constructor * @constructor
*/ */
var Slider = function(scope, sliderElem, attributes) var Slider = function(scope, sliderElem) {
{
/** /**
* The slider's scope * The slider's scope
* *
...@@ -97,13 +142,6 @@ function throttle(func, wait, options) { ...@@ -97,13 +142,6 @@ function throttle(func, wait, options) {
*/ */
this.scope = scope; this.scope = scope;
/**
* The slider attributes
*
* @type {Object}
*/
this.attributes = attributes;
/** /**
* Slider element wrapped in jqLite * Slider element wrapped in jqLite
* *
...@@ -116,14 +154,7 @@ function throttle(func, wait, options) { ...@@ -116,14 +154,7 @@ function throttle(func, wait, options) {
* *
* @type {boolean} Set to true for range slider * @type {boolean} Set to true for range slider
*/ */
this.range = attributes.rzSliderHigh !== undefined && attributes.rzSliderModel !== undefined; this.range = this.scope.rzSliderModel !== undefined && this.scope.rzSliderHigh !== undefined;
/**
* Whether to allow draggable range
*
* @type {boolean} Set to true for draggable range slider
*/
this.dragRange = this.range && attributes.rzSliderDraggableRange === 'true';
/** /**
* Values recorded when first dragging the bar * Values recorded when first dragging the bar
...@@ -146,13 +177,6 @@ function throttle(func, wait, options) { ...@@ -146,13 +177,6 @@ function throttle(func, wait, options) {
*/ */
this.handleHalfWidth = 0; this.handleHalfWidth = 0;
/**
* Always show selection bar
*
* @type {boolean}
*/
this.alwaysShowBar = !!attributes.rzSliderAlwaysShowBar;
/** /**
* Maximum left the slider handle can have * Maximum left the slider handle can have
* *
...@@ -195,50 +219,6 @@ function throttle(func, wait, options) { ...@@ -195,50 +219,6 @@ function throttle(func, wait, options) {
*/ */
this.maxValue = 0; this.maxValue = 0;
/**
* Hide limit labels
*
* @type {boolean}
*/
this.hideLimitLabels = !!attributes.rzSliderHideLimitLabels;
/**
* Only present model values
*
* Do not allow to change values
*
* @type {boolean}
*/
this.presentOnly = attributes.rzSliderPresentOnly === 'true';
/**
* Display ticks on each possible value.
*
* @type {boolean}
*/
this.showTicks = attributes.rzSliderShowTicks || attributes.rzSliderShowTicksValue;
/**
* Display the value on each tick.
*
* @type {boolean}
*/
this.showTicksValue = attributes.rzSliderShowTicksValue;
/**
* Disable the slider
*
* @type {boolean}
*/
this.disabled = this.scope.rzSliderDisabled;
/**
* The interval at which the slider updates when the model/high values
* are altered from outside the slider
*
* @type {number}
*/
this.interval = this.scope.rzSliderInterval !== null ? this.scope.rzSliderInterval : 350;
/** /**
* The delta between min and max value * The delta between min and max value
...@@ -254,20 +234,6 @@ function throttle(func, wait, options) { ...@@ -254,20 +234,6 @@ function throttle(func, wait, options) {
*/ */
this.initHasRun = false; this.initHasRun = false;
/**
* Custom translate function
*
* @type {function}
*/
this.customTrFn = this.scope.rzSliderTranslate() || function(value) { return String(value); };
/**
* Array of de-registration functions to call on $destroy
*
* @type {Array.<Function>}
*/
this.deRegFuncs = [];
// 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
...@@ -292,23 +258,21 @@ function throttle(func, wait, options) { ...@@ -292,23 +258,21 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
init: function() init: function() {
{ var thrLow, thrHigh,
var thrLow, thrHigh, unRegFn,
calcDimFn = angular.bind(this, this.calcViewDimensions), calcDimFn = angular.bind(this, this.calcViewDimensions),
self = this; self = this;
this.applyOptions();
this.initElemHandles(); this.initElemHandles();
this.manageElementsStyle();
this.addAccessibility(); this.addAccessibility();
this.manageEventsBindings();
this.setDisabledState(); this.setDisabledState();
this.calcViewDimensions(); this.calcViewDimensions();
this.setMinAndMax(); this.setMinAndMax();
this.precision = this.scope.rzSliderPrecision === undefined ? 0 : +this.scope.rzSliderPrecision; $timeout(function() {
this.step = this.scope.rzSliderStep === undefined ? 1 : +this.scope.rzSliderStep;
$timeout(function()
{
self.updateCeilLab(); self.updateCeilLab();
self.updateFloorLab(); self.updateFloorLab();
self.initHandles(); self.initHandles();
...@@ -316,8 +280,7 @@ function throttle(func, wait, options) { ...@@ -316,8 +280,7 @@ function throttle(func, wait, options) {
}); });
// Recalculate slider view dimensions // Recalculate slider view dimensions
unRegFn = this.scope.$on('reCalcViewDimensions', calcDimFn); this.scope.$on('reCalcViewDimensions', calcDimFn);
this.deRegFuncs.push(unRegFn);
// Recalculate stuff if view port dimensions have changed // Recalculate stuff if view port dimensions have changed
angular.element($window).on('resize', calcDimFn); angular.element($window).on('resize', calcDimFn);
...@@ -326,98 +289,91 @@ function throttle(func, wait, options) { ...@@ -326,98 +289,91 @@ function throttle(func, wait, options) {
// Watch for changes to the model // Watch for changes to the model
thrLow = throttle(function() thrLow = rzThrottle(function() {
{
self.setMinAndMax(); self.setMinAndMax();
self.updateLowHandle(self.valueToOffset(self.scope.rzSliderModel)); self.updateLowHandle(self.valueToOffset(self.scope.rzSliderModel));
self.updateSelectionBar(); self.updateSelectionBar();
self.updateTicksScale(); self.updateTicksScale();
if(self.range) if (self.range) {
{
self.updateCmbLabel(); self.updateCmbLabel();
} }
}, self.interval); }, self.options.interval);
thrHigh = throttle(function() thrHigh = rzThrottle(function() {
{
self.setMinAndMax(); self.setMinAndMax();
self.updateHighHandle(self.valueToOffset(self.scope.rzSliderHigh)); self.updateHighHandle(self.valueToOffset(self.scope.rzSliderHigh));
self.updateSelectionBar(); self.updateSelectionBar();
self.updateTicksScale(); self.updateTicksScale();
self.updateCmbLabel(); self.updateCmbLabel();
}, self.interval); }, self.options.interval);
this.scope.$on('rzSliderForceRender', function() this.scope.$on('rzSliderForceRender', function() {
{
self.resetLabelsValue(); self.resetLabelsValue();
thrLow(); thrLow();
if(self.range) { thrHigh(); } if (self.range) {
thrHigh();
}
self.resetSlider(); self.resetSlider();
}); });
// Watchers // Watchers
this.scope.$watch('rzSliderModel', function(newValue, oldValue) {
unRegFn = this.scope.$watch('rzSliderModel', function(newValue, oldValue) if (newValue === oldValue)
{ return;
if(newValue === oldValue) { return; }
thrLow(); thrLow();
}); });
this.deRegFuncs.push(unRegFn);
unRegFn = this.scope.$watch('rzSliderHigh', function(newValue, oldValue) this.scope.$watch('rzSliderHigh', function(newValue, oldValue) {
{ if (newValue === oldValue)
if(newValue === oldValue) { return; } return;
if (newValue != null)
thrHigh(); thrHigh();
}); if (self.range && newValue == null || !self.range && newValue != null) {
this.deRegFuncs.push(unRegFn); self.applyOptions();
this.scope.$watch('rzSliderFloor', function(newValue, oldValue)
{
if(newValue === oldValue) { return; }
self.resetSlider(); self.resetSlider();
}
}); });
this.deRegFuncs.push(unRegFn);
unRegFn = this.scope.$watch('rzSliderCeil', function(newValue, oldValue) this.scope.$watch('rzSliderOptions', function(newValue, oldValue) {
{ if (newValue === oldValue)
if(newValue === oldValue) { return; } return;
self.applyOptions();
self.resetSlider(); self.resetSlider();
}); }, true);
this.deRegFuncs.push(unRegFn);
unRegFn = this.scope.$watch('rzSliderShowTicks', function(newValue, oldValue) this.scope.$on('$destroy', function() {
{ self.unbindEvents();
if(newValue === oldValue) { return; } angular.element($window).off('resize', calcDimFn);
self.resetSlider();
}); });
this.deRegFuncs.push(unRegFn); },
unRegFn = this.scope.$watch('rzSliderShowTicksValue', function(newValue, oldValue) /**
{ * Read the user options and apply them to the slider model
if(newValue === oldValue) { return; } */
self.resetSlider(); applyOptions: function() {
}); this.options = RzSliderOptions.getOptions(this.scope.rzSliderOptions);
this.deRegFuncs.push(unRegFn);
unRegFn = this.scope.$watch('rzSliderDisabled', function(newValue, oldValue) if (this.options.step <= 0)
{ this.options.step = 1;
if(newValue === oldValue) { return; } this.range = this.scope.rzSliderModel !== undefined && this.scope.rzSliderHigh !== undefined;
self.resetSlider(); this.options.draggableRange = this.range && this.options.draggableRange;
if(self.disabled) this.options.showTicks = this.options.showTicks || this.options.showTicksValues;
self.unbindEvents();
else
self.bindEvents();
});
this.deRegFuncs.push(unRegFn);
this.scope.$on('$destroy', function() if (this.options.stepsArray) {
{ this.options.floor = 0;
self.unbindEvents(); this.options.ceil = this.options.stepsArray.length - 1;
angular.element($window).off('resize', calcDimFn); this.options.step = 1;
self.deRegFuncs.map(function(unbind) { unbind(); }); 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);
};
}, },
/** /**
...@@ -425,30 +381,132 @@ function throttle(func, wait, options) { ...@@ -425,30 +381,132 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
resetSlider: function() resetSlider: function() {
{ this.manageElementsStyle();
this.setMinAndMax(); this.setMinAndMax();
this.updateCeilLab(); this.updateCeilLab();
this.updateFloorLab(); this.updateFloorLab();
this.unbindEvents();
this.manageEventsBindings();
this.setDisabledState(); this.setDisabledState();
this.calcViewDimensions(); 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);
// Initialize offset cache properties
this.selBar.rzsl = 0;
this.minH.rzsl = 0;
this.maxH.rzsl = 0;
this.flrLab.rzsl = 0;
this.ceilLab.rzsl = 0;
this.minLab.rzsl = 0;
this.maxLab.rzsl = 0;
this.cmbLab.rzsl = 0;
},
/** Update each elements style based on options
*
*/
manageElementsStyle: function() {
if (!this.range)
this.maxH.css('display', 'none');
else
this.maxH.css('display', null);
this.alwaysHide(this.flrLab, this.options.showTicksValues || this.options.hideLimitLabels);
this.alwaysHide(this.ceilLab, this.options.showTicksValues || this.options.hideLimitLabels);
this.alwaysHide(this.minLab, this.options.showTicksValues);
this.alwaysHide(this.maxLab, this.options.showTicksValues || !this.range);
this.alwaysHide(this.cmbLab, this.options.showTicksValues || !this.range);
this.alwaysHide(this.selBar, !this.range && !this.options.showSelectionBar);
if (!this.options.showTicks)
this.ticks.html('');
if (this.options.draggableRange)
this.selBar.addClass('rz-draggable');
else
this.selBar.removeClass('rz-draggable');
},
alwaysHide: function(el, hide) {
el.rzAlwaysHide = hide;
if (hide)
this.hideEl(el);
else
this.showEl(el)
},
/**
* Manage the events bindings based on readOnly and disabled options
*
* @returns {undefined}
*/
manageEventsBindings: function() {
if (this.options.disabled || this.options.readOnly)
this.unbindEvents();
else if (!this.options.disabled || !this.options.readOnly)
this.bindEvents();
},
/** /**
* Set the disabled state based on rzSliderDisabled * Set the disabled state based on rzSliderDisabled
* *
* @returns {undefined} * @returns {undefined}
*/ */
setDisabledState: function() setDisabledState: function() {
{ if (this.options.disabled) {
this.disabled = this.scope.rzSliderDisabled;
if(this.disabled) {
this.sliderElem.attr('disabled', 'disabled'); this.sliderElem.attr('disabled', 'disabled');
} } else {
else {
this.sliderElem.attr('disabled', null); this.sliderElem.attr('disabled', null);
} }
}, },
/** /**
...@@ -456,8 +514,7 @@ function throttle(func, wait, options) { ...@@ -456,8 +514,7 @@ function throttle(func, wait, options) {
* *
* @return {undefined} * @return {undefined}
*/ */
resetLabelsValue: function() resetLabelsValue: function() {
{
this.minLab.rzsv = undefined; this.minLab.rzsv = undefined;
this.maxLab.rzsv = undefined; this.maxLab.rzsv = undefined;
}, },
...@@ -469,18 +526,17 @@ function throttle(func, wait, options) { ...@@ -469,18 +526,17 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
initHandles: function() initHandles: function() {
{
this.updateLowHandle(this.valueToOffset(this.scope.rzSliderModel)); this.updateLowHandle(this.valueToOffset(this.scope.rzSliderModel));
/* /*
the order here is important since the selection bar should be the order here is important since the selection bar should be
updated after the high handle but before the combined label updated after the high handle but before the combined label
*/ */
if(this.range) if (this.range)
this.updateHighHandle(this.valueToOffset(this.scope.rzSliderHigh)); this.updateHighHandle(this.valueToOffset(this.scope.rzSliderHigh));
this.updateSelectionBar(); this.updateSelectionBar();
if(this.range) if (this.range)
this.updateCmbLabel(); this.updateCmbLabel();
this.updateTicksScale(); this.updateTicksScale();
...@@ -494,15 +550,13 @@ function throttle(func, wait, options) { ...@@ -494,15 +550,13 @@ function throttle(func, wait, options) {
* @param {boolean} [useCustomTr] * @param {boolean} [useCustomTr]
* @returns {undefined} * @returns {undefined}
*/ */
translateFn: function(value, label, useCustomTr) translateFn: function(value, label, useCustomTr) {
{
useCustomTr = useCustomTr === undefined ? true : useCustomTr; useCustomTr = useCustomTr === undefined ? true : useCustomTr;
var valStr = (useCustomTr ? this.customTrFn(value) : value).toString(), 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;
} }
...@@ -510,129 +564,33 @@ function throttle(func, wait, options) { ...@@ -510,129 +564,33 @@ function throttle(func, wait, options) {
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) { this.getWidth(label); } if (getWidth) {
}, this.getWidth(label);
/**
* Set maximum and minimum values for the slider
*
* @returns {undefined}
*/
setMinAndMax: function()
{
if(this.scope.rzSliderFloor)
{
this.minValue = +this.scope.rzSliderFloor;
}
else
{
this.minValue = this.scope.rzSliderFloor = 0;
}
if(this.scope.rzSliderCeil)
{
this.maxValue = +this.scope.rzSliderCeil;
} }
else
{
this.maxValue = this.scope.rzSliderCeil = this.range ? this.scope.rzSliderHigh : this.scope.rzSliderModel;
}
if(this.scope.rzSliderStep)
{
this.step = +this.scope.rzSliderStep;
}
this.valueRange = this.maxValue - this.minValue;
}, },
/** /**
* Set the slider children to variables for easy access * Set maximum and minimum values for the slider and ensure the model and high
* * value match these limits
* Run only once during initialization
*
* @returns {undefined} * @returns {undefined}
*/ */
initElemHandles: function() setMinAndMax: 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);
// Initialize offset cache properties
this.selBar.rzsl = 0;
this.minH.rzsl = 0;
this.maxH.rzsl = 0;
this.flrLab.rzsl = 0;
this.ceilLab.rzsl = 0;
this.minLab.rzsl = 0;
this.maxLab.rzsl = 0;
this.cmbLab.rzsl = 0;
// Hide limit labels
if(this.hideLimitLabels)
{
this.flrLab.rzAlwaysHide = true;
this.ceilLab.rzAlwaysHide = true;
this.hideEl(this.flrLab);
this.hideEl(this.ceilLab);
}
if(this.showTicksValue) { this.step = +this.options.step;
this.flrLab.rzAlwaysHide = true; this.precision = +this.options.precision;
this.ceilLab.rzAlwaysHide = true;
this.minLab.rzAlwaysHide = true;
this.maxLab.rzAlwaysHide = true;
this.cmbLab.rzAlwaysHide = true;
this.hideEl(this.flrLab);
this.hideEl(this.ceilLab);
this.hideEl(this.minLab);
this.hideEl(this.maxLab);
this.hideEl(this.cmbLab);
}
// Remove stuff not needed in single slider this.scope.rzSliderModel = this.roundStep(this.scope.rzSliderModel);
if(this.range === false) if (this.range)
{ this.scope.rzSliderHigh = this.roundStep(this.scope.rzSliderHigh);
this.cmbLab.remove();
this.maxLab.remove();
// Hide max handle this.minValue = this.roundStep(+this.options.floor);
this.maxH.rzAlwaysHide = true;
this.maxH[0].style.zIndex = '-1000';
this.hideEl(this.maxH);
}
// Show selection bar for single slider or not if (this.options.ceil != null)
if(this.range === false && this.alwaysShowBar === false) this.maxValue = this.roundStep(+this.options.ceil);
{ else
this.maxH.remove(); this.maxValue = this.options.ceil = this.range ? this.scope.rzSliderHigh : this.scope.rzSliderModel;
this.selBar.remove();
}
// If using draggable range, use appropriate cursor for this.selBar. this.valueRange = this.maxValue - this.minValue;
if (this.dragRange)
{
this.selBar.css('cursor', 'move');
this.selBar.addClass('rz-draggable');
}
}, },
/** /**
...@@ -642,8 +600,7 @@ function throttle(func, wait, options) { ...@@ -642,8 +600,7 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
addAccessibility: function () addAccessibility: function() {
{
this.sliderElem.attr("role", "slider"); this.sliderElem.attr("role", "slider");
}, },
...@@ -654,8 +611,7 @@ function throttle(func, wait, options) { ...@@ -654,8 +611,7 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
calcViewDimensions: function () calcViewDimensions: function() {
{
var handleWidth = this.getWidth(this.minH); var handleWidth = this.getWidth(this.minH);
this.handleHalfWidth = handleWidth / 2; this.handleHalfWidth = handleWidth / 2;
...@@ -666,8 +622,7 @@ function throttle(func, wait, options) { ...@@ -666,8 +622,7 @@ function throttle(func, wait, options) {
this.getWidth(this.sliderElem); this.getWidth(this.sliderElem);
this.sliderElem.rzsl = this.sliderElem[0].getBoundingClientRect().left; this.sliderElem.rzsl = this.sliderElem[0].getBoundingClientRect().left;
if(this.initHasRun) if (this.initHasRun) {
{
this.updateFloorLab(); this.updateFloorLab();
this.updateCeilLab(); this.updateCeilLab();
this.initHandles(); this.initHandles();
...@@ -680,27 +635,33 @@ function throttle(func, wait, options) { ...@@ -680,27 +635,33 @@ function throttle(func, wait, options) {
* @returns {undefined} * @returns {undefined}
*/ */
updateTicksScale: function() { updateTicksScale: function() {
if(!this.showTicks) return; if (!this.options.showTicks) return;
if(!this.step) return; //if step is 0, the following loop will be endless. if (!this.step) return; //if step is 0, the following loop will be endless.
var positions = '', var positions = '',
ticksCount = Math.round((this.maxValue - this.minValue) / this.step) + 1; ticksCount = Math.round((this.maxValue - this.minValue) / this.step) + 1;
for (var i = 0; i < ticksCount; i++) { for (var i = 0; i < ticksCount; i++) {
var value = this.roundStep(this.minValue + i * this.step); var value = this.roundStep(this.minValue + i * this.step);
var selectedClass = this.isTickSelected(value) ? 'selected': ''; var selectedClass = this.isTickSelected(value) ? 'selected' : '';
positions += '<li class="tick '+ selectedClass +'">'; positions += '<li class="tick ' + selectedClass + '">';
if(this.showTicksValue) if (this.options.showTicksValues) {
positions += '<span class="tick-value">'+ this.getDisplayValue(value) +'</span>'; var tooltip = '';
if (this.options.ticksValuesTooltip) {
tooltip = 'uib-tooltip="' + this.options.ticksValuesTooltip(value) + '"';
}
positions += '<span ' + tooltip + ' class="tick-value">' + this.getDisplayValue(value) + '</span>';
}
positions += '</li>'; positions += '</li>';
} }
this.ticks.html(positions); this.ticks.html(positions);
if (this.options.ticksValuesTooltip)
$compile(this.ticks.contents())(this.scope);
}, },
isTickSelected: function(value) { isTickSelected: function(value) {
var tickLeft = this.valueToOffset(value); if (!this.range && this.options.showSelectionBar && value <= this.scope.rzSliderModel)
if(!this.range && this.alwaysShowBar && value <= this.scope.rzSliderModel)
return true; return true;
if(this.range && value >= this.scope.rzSliderModel && value <= this.scope.rzSliderHigh) if (this.range && value >= this.scope.rzSliderModel && value <= this.scope.rzSliderHigh)
return true; return true;
return false; return false;
}, },
...@@ -710,9 +671,8 @@ function throttle(func, wait, options) { ...@@ -710,9 +671,8 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
updateCeilLab: function() updateCeilLab: function() {
{ this.translateFn(this.maxValue, this.ceilLab);
this.translateFn(this.scope.rzSliderCeil, this.ceilLab);
this.setLeft(this.ceilLab, this.barWidth - this.ceilLab.rzsw); this.setLeft(this.ceilLab, this.barWidth - this.ceilLab.rzsw);
this.getWidth(this.ceilLab); this.getWidth(this.ceilLab);
}, },
...@@ -722,9 +682,8 @@ function throttle(func, wait, options) { ...@@ -722,9 +682,8 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
updateFloorLab: function() updateFloorLab: function() {
{ this.translateFn(this.minValue, this.flrLab);
this.translateFn(this.scope.rzSliderFloor, this.flrLab);
this.getWidth(this.flrLab); this.getWidth(this.flrLab);
}, },
...@@ -734,10 +693,10 @@ function throttle(func, wait, options) { ...@@ -734,10 +693,10 @@ function throttle(func, wait, options) {
* @returns {undefined} * @returns {undefined}
*/ */
callOnStart: function() { callOnStart: function() {
if(this.scope.rzSliderOnStart) { if (this.options.onStart) {
var self = this; var self = this;
$timeout(function() { $timeout(function() {
self.scope.rzSliderOnStart(); self.options.onStart();
}); });
} }
}, },
...@@ -748,10 +707,10 @@ function throttle(func, wait, options) { ...@@ -748,10 +707,10 @@ function throttle(func, wait, options) {
* @returns {undefined} * @returns {undefined}
*/ */
callOnChange: function() { callOnChange: function() {
if(this.scope.rzSliderOnChange) { if (this.options.onChange) {
var self = this; var self = this;
$timeout(function() { $timeout(function() {
self.scope.rzSliderOnChange(); self.options.onChange();
}); });
} }
}, },
...@@ -762,10 +721,10 @@ function throttle(func, wait, options) { ...@@ -762,10 +721,10 @@ function throttle(func, wait, options) {
* @returns {undefined} * @returns {undefined}
*/ */
callOnEnd: function() { callOnEnd: function() {
if(this.scope.rzSliderOnEnd) { if (this.options.onEnd) {
var self = this; var self = this;
$timeout(function() { $timeout(function() {
self.scope.rzSliderOnEnd(); self.options.onEnd();
}); });
} }
}, },
...@@ -776,29 +735,24 @@ function throttle(func, wait, options) { ...@@ -776,29 +735,24 @@ function throttle(func, wait, options) {
* @param {string} which * @param {string} which
* @param {number} newOffset * @param {number} newOffset
*/ */
updateHandles: function(which, newOffset) updateHandles: function(which, newOffset) {
{ if (which === 'rzSliderModel') {
if(which === 'rzSliderModel')
{
this.updateLowHandle(newOffset); this.updateLowHandle(newOffset);
this.updateSelectionBar(); this.updateSelectionBar();
this.updateTicksScale(); this.updateTicksScale();
if(this.range) if (this.range) {
{
this.updateCmbLabel(); this.updateCmbLabel();
} }
return; return;
} }
if(which === 'rzSliderHigh') if (which === 'rzSliderHigh') {
{
this.updateHighHandle(newOffset); this.updateHighHandle(newOffset);
this.updateSelectionBar(); this.updateSelectionBar();
this.updateTicksScale(); this.updateTicksScale();
if(this.range) if (this.range) {
{
this.updateCmbLabel(); this.updateCmbLabel();
} }
return; return;
...@@ -818,8 +772,7 @@ function throttle(func, wait, options) { ...@@ -818,8 +772,7 @@ function throttle(func, wait, options) {
* @param {number} newOffset * @param {number} newOffset
* @returns {undefined} * @returns {undefined}
*/ */
updateLowHandle: function(newOffset) updateLowHandle: function(newOffset) {
{
this.setLeft(this.minH, newOffset); this.setLeft(this.minH, newOffset);
this.translateFn(this.scope.rzSliderModel, this.minLab); this.translateFn(this.scope.rzSliderModel, this.minLab);
this.setLeft(this.minLab, newOffset - this.minLab.rzsw / 2 + this.handleHalfWidth); this.setLeft(this.minLab, newOffset - this.minLab.rzsw / 2 + this.handleHalfWidth);
...@@ -833,8 +786,7 @@ function throttle(func, wait, options) { ...@@ -833,8 +786,7 @@ function throttle(func, wait, options) {
* @param {number} newOffset * @param {number} newOffset
* @returns {undefined} * @returns {undefined}
*/ */
updateHighHandle: function(newOffset) updateHighHandle: function(newOffset) {
{
this.setLeft(this.maxH, newOffset); this.setLeft(this.maxH, newOffset);
this.translateFn(this.scope.rzSliderHigh, this.maxLab); this.translateFn(this.scope.rzSliderHigh, this.maxLab);
this.setLeft(this.maxLab, newOffset - this.maxLab.rzsw / 2 + this.handleHalfWidth); this.setLeft(this.maxLab, newOffset - this.maxLab.rzsw / 2 + this.handleHalfWidth);
...@@ -847,50 +799,37 @@ function throttle(func, wait, options) { ...@@ -847,50 +799,37 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
shFloorCeil: function() shFloorCeil: function() {
{ var flHidden = false,
var flHidden = false, clHidden = false; clHidden = false;
if(this.minLab.rzsl <= this.flrLab.rzsl + this.flrLab.rzsw + 5) if (this.minLab.rzsl <= this.flrLab.rzsl + this.flrLab.rzsw + 5) {
{
flHidden = true; flHidden = true;
this.hideEl(this.flrLab); this.hideEl(this.flrLab);
} } else {
else
{
flHidden = false; flHidden = false;
this.showEl(this.flrLab); 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); this.hideEl(this.ceilLab);
} } else {
else
{
clHidden = false; clHidden = false;
this.showEl(this.ceilLab); this.showEl(this.ceilLab);
} }
if(this.range) if (this.range) {
{ if (this.maxLab.rzsl + this.maxLab.rzsw >= this.ceilLab.rzsl - 10) {
if(this.maxLab.rzsl + this.maxLab.rzsw >= this.ceilLab.rzsl - 10)
{
this.hideEl(this.ceilLab); this.hideEl(this.ceilLab);
} } else if (!clHidden) {
else if( ! clHidden)
{
this.showEl(this.ceilLab); this.showEl(this.ceilLab);
} }
// Hide or show floor label // Hide or show floor label
if(this.maxLab.rzsl <= this.flrLab.rzsl + this.flrLab.rzsw + this.handleHalfWidth) if (this.maxLab.rzsl <= this.flrLab.rzsl + this.flrLab.rzsw + this.handleHalfWidth) {
{
this.hideEl(this.flrLab); this.hideEl(this.flrLab);
} } else if (!flHidden) {
else if( ! flHidden)
{
this.showEl(this.flrLab); this.showEl(this.flrLab);
} }
} }
...@@ -901,8 +840,7 @@ function throttle(func, wait, options) { ...@@ -901,8 +840,7 @@ function throttle(func, wait, options) {
* *
* @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);
}, },
...@@ -912,12 +850,10 @@ function throttle(func, wait, options) { ...@@ -912,12 +850,10 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
updateCmbLabel: function() updateCmbLabel: function() {
{
var lowTr, highTr; var lowTr, highTr;
if(this.minLab.rzsl + this.minLab.rzsw + 10 >= this.maxLab.rzsl) if (this.minLab.rzsl + this.minLab.rzsw + 10 >= this.maxLab.rzsl) {
{
lowTr = this.getDisplayValue(this.scope.rzSliderModel); lowTr = this.getDisplayValue(this.scope.rzSliderModel);
highTr = this.getDisplayValue(this.scope.rzSliderHigh); highTr = this.getDisplayValue(this.scope.rzSliderHigh);
...@@ -926,9 +862,7 @@ function throttle(func, wait, options) { ...@@ -926,9 +862,7 @@ function throttle(func, wait, options) {
this.hideEl(this.minLab); this.hideEl(this.minLab);
this.hideEl(this.maxLab); this.hideEl(this.maxLab);
this.showEl(this.cmbLab); this.showEl(this.cmbLab);
} } else {
else
{
this.showEl(this.maxLab); this.showEl(this.maxLab);
this.showEl(this.minLab); this.showEl(this.minLab);
this.hideEl(this.cmbLab); this.hideEl(this.cmbLab);
...@@ -941,7 +875,7 @@ function throttle(func, wait, options) { ...@@ -941,7 +875,7 @@ function throttle(func, wait, options) {
* @returns {*} * @returns {*}
*/ */
getDisplayValue: function(value) { getDisplayValue: function(value) {
return this.customTrFn ? this.customTrFn(value): value; return this.customTrFn(value, this.options.id);
}, },
/** /**
...@@ -950,8 +884,7 @@ function throttle(func, wait, options) { ...@@ -950,8 +884,7 @@ function throttle(func, wait, options) {
* @param {number} value * @param {number} value
* @returns {number} * @returns {number}
*/ */
roundStep: function(value) roundStep: function(value) {
{
var step = this.step, var step = this.step,
remainder = +((value - this.minValue) % step).toFixed(3), remainder = +((value - this.minValue) % step).toFixed(3),
steppedValue = remainder > (step / 2) ? value + step - remainder : value - remainder; steppedValue = remainder > (step / 2) ? value + step - remainder : value - remainder;
...@@ -966,9 +899,10 @@ function throttle(func, wait, options) { ...@@ -966,9 +899,10 @@ function throttle(func, wait, options) {
* @param element * @param element
* @returns {jqLite} The jqLite wrapped DOM element * @returns {jqLite} The jqLite wrapped DOM element
*/ */
hideEl: function (element) hideEl: function(element) {
{ return element.css({
return element.css({opacity: 0}); opacity: 0
});
}, },
/** /**
...@@ -977,11 +911,14 @@ function throttle(func, wait, options) { ...@@ -977,11 +911,14 @@ function throttle(func, wait, options) {
* @param element The jqLite wrapped DOM element * @param element The jqLite wrapped DOM element
* @returns {jqLite} The jqLite * @returns {jqLite} The jqLite
*/ */
showEl: function (element) showEl: function(element) {
{ if (!!element.rzAlwaysHide) {
if(!!element.rzAlwaysHide) { return element; } return element;
}
return element.css({opacity: 1}); return element.css({
opacity: 1
});
}, },
/** /**
...@@ -991,10 +928,11 @@ function throttle(func, wait, options) { ...@@ -991,10 +928,11 @@ function throttle(func, wait, options) {
* @param {number} left * @param {number} left
* @returns {number} * @returns {number}
*/ */
setLeft: function (elem, left) setLeft: function(elem, left) {
{
elem.rzsl = left; elem.rzsl = left;
elem.css({left: left + 'px'}); elem.css({
left: left + 'px'
});
return left; return left;
}, },
...@@ -1004,10 +942,9 @@ function throttle(func, wait, options) { ...@@ -1004,10 +942,9 @@ function throttle(func, wait, options) {
* @param {jqLite} elem The jqLite wrapped DOM element * @param {jqLite} elem The jqLite wrapped DOM element
* @returns {number} * @returns {number}
*/ */
getWidth: function(elem) getWidth: function(elem) {
{
var val = elem[0].getBoundingClientRect(); var val = elem[0].getBoundingClientRect();
elem.rzsw = val.right - val.left; elem.rzsw = (val.right - val.left) * this.options.scale;
return elem.rzsw; return elem.rzsw;
}, },
...@@ -1018,10 +955,11 @@ function throttle(func, wait, options) { ...@@ -1018,10 +955,11 @@ function throttle(func, wait, options) {
* @param {number} width * @param {number} width
* @returns {number} * @returns {number}
*/ */
setWidth: function(elem, width) setWidth: function(elem, width) {
{
elem.rzsw = width; elem.rzsw = width;
elem.css({width: width + 'px'}); elem.css({
width: width + 'px'
});
return width; return width;
}, },
...@@ -1031,9 +969,18 @@ function throttle(func, wait, options) { ...@@ -1031,9 +969,18 @@ function throttle(func, wait, options) {
* @param {number} val * @param {number} val
* @returns {number} * @returns {number}
*/ */
valueToOffset: function(val) valueToOffset: function(val) {
{ return (this.sanitizeOffsetValue(val) - this.minValue) * this.maxLeft / this.valueRange || 0;
return (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);
}, },
/** /**
...@@ -1042,8 +989,7 @@ function throttle(func, wait, options) { ...@@ -1042,8 +989,7 @@ function throttle(func, wait, options) {
* @param {number} offset * @param {number} offset
* @returns {number} * @returns {number}
*/ */
offsetToValue: function(offset) offsetToValue: function(offset) {
{
return (offset / this.maxLeft) * this.valueRange + this.minValue; return (offset / this.maxLeft) * this.valueRange + this.minValue;
}, },
...@@ -1055,18 +1001,15 @@ function throttle(func, wait, options) { ...@@ -1055,18 +1001,15 @@ function throttle(func, wait, options) {
* @param {Object} event The event * @param {Object} event The event
* @returns {number} * @returns {number}
*/ */
getEventX: function(event) getEventX: function(event) {
{
/* http://stackoverflow.com/a/12336075/282882 */ /* http://stackoverflow.com/a/12336075/282882 */
//noinspection JSLint //noinspection JSLint
if('clientX' in event) if ('clientX' in event) {
{
return event.clientX; return event.clientX;
} }
return event.originalEvent === undefined ? return event.originalEvent === undefined ?
event.touches[0].clientX event.touches[0].clientX : event.originalEvent.touches[0].clientX;
: event.originalEvent.touches[0].clientX;
}, },
/** /**
...@@ -1075,10 +1018,11 @@ function throttle(func, wait, options) { ...@@ -1075,10 +1018,11 @@ function throttle(func, wait, options) {
* @param event {Event} The event * @param event {Event} The event
* @returns {jqLite} The handle closest to the event. * @returns {jqLite} The handle closest to the event.
*/ */
getNearestHandle: function(event) getNearestHandle: function(event) {
{ if (!this.range) {
if (!this.range) { return this.minH; } return this.minH;
var offset = this.getEventX(event) - this.sliderElem.rzsl - this.handleHalfWidth; }
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; return Math.abs(offset - this.minH.rzsl) < Math.abs(offset - this.maxH.rzsl) ? this.minH : this.maxH;
}, },
...@@ -1087,26 +1031,24 @@ function throttle(func, wait, options) { ...@@ -1087,26 +1031,24 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
bindEvents: function() bindEvents: function() {
{ if (this.options.readOnly || this.options.disabled) return;
if(this.presentOnly || this.disabled) return;
var barTracking, barStart, barMove; var barTracking, barStart, barMove;
if (this.dragRange) if (this.options.draggableRange) {
{
barTracking = 'rzSliderDrag'; barTracking = 'rzSliderDrag';
barStart = this.onDragStart; barStart = this.onDragStart;
barMove = this.onDragMove; barMove = this.onDragMove;
} } else {
else
{
barTracking = 'rzSliderModel'; barTracking = 'rzSliderModel';
barStart = this.onStart; barStart = this.onStart;
barMove = this.onMove; barMove = this.onMove;
} }
this.minH.on('mousedown', angular.bind(this, this.onStart, this.minH, 'rzSliderModel')); this.minH.on('mousedown', angular.bind(this, this.onStart, this.minH, 'rzSliderModel'));
if(this.range) { this.maxH.on('mousedown', angular.bind(this, this.onStart, this.maxH, 'rzSliderHigh')); } if (this.range) {
this.maxH.on('mousedown', angular.bind(this, this.onStart, this.maxH, 'rzSliderHigh'));
}
this.fullBar.on('mousedown', angular.bind(this, this.onStart, null, null)); this.fullBar.on('mousedown', angular.bind(this, this.onStart, null, null));
this.fullBar.on('mousedown', angular.bind(this, this.onMove, this.fullBar)); this.fullBar.on('mousedown', angular.bind(this, this.onMove, this.fullBar));
this.selBar.on('mousedown', angular.bind(this, barStart, null, barTracking)); this.selBar.on('mousedown', angular.bind(this, barStart, null, barTracking));
...@@ -1115,7 +1057,9 @@ function throttle(func, wait, options) { ...@@ -1115,7 +1057,9 @@ function throttle(func, wait, options) {
this.ticks.on('mousedown', angular.bind(this, this.onMove, this.ticks)); this.ticks.on('mousedown', angular.bind(this, this.onMove, this.ticks));
this.minH.on('touchstart', angular.bind(this, this.onStart, this.minH, 'rzSliderModel')); this.minH.on('touchstart', angular.bind(this, this.onStart, this.minH, 'rzSliderModel'));
if(this.range) { this.maxH.on('touchstart', angular.bind(this, this.onStart, this.maxH, 'rzSliderHigh')); } if (this.range) {
this.maxH.on('touchstart', angular.bind(this, this.onStart, this.maxH, 'rzSliderHigh'));
}
this.fullBar.on('touchstart', angular.bind(this, this.onStart, null, null)); this.fullBar.on('touchstart', angular.bind(this, this.onStart, null, null));
this.fullBar.on('touchstart', angular.bind(this, this.onMove, this.fullBar)); 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, barStart, null, barTracking));
...@@ -1129,8 +1073,7 @@ function throttle(func, wait, options) { ...@@ -1129,8 +1073,7 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
unbindEvents: function() unbindEvents: function() {
{
this.minH.off(); this.minH.off();
this.maxH.off(); this.maxH.off();
this.fullBar.off(); this.fullBar.off();
...@@ -1146,26 +1089,24 @@ function throttle(func, wait, options) { ...@@ -1146,26 +1089,24 @@ function throttle(func, wait, options) {
* @param {Event} event The event * @param {Event} event The event
* @returns {undefined} * @returns {undefined}
*/ */
onStart: function (pointer, ref, event) onStart: function(pointer, ref, event) {
{
var ehMove, ehEnd, var ehMove, ehEnd,
eventNames = this.getEventNames(event); eventNames = this.getEventNames(event);
event.stopPropagation(); event.stopPropagation();
event.preventDefault(); event.preventDefault();
if(this.tracking !== '') { return; } if (this.tracking !== '') {
return;
}
// We have to do this in case the HTML where the sliders are on // We have to do this in case the HTML where the sliders are on
// have been animated into view. // have been animated into view.
this.calcViewDimensions(); this.calcViewDimensions();
if(pointer) if (pointer) {
{
this.tracking = ref; this.tracking = ref;
} } else {
else
{
pointer = this.getNearestHandle(event); pointer = this.getNearestHandle(event);
this.tracking = pointer === this.minH ? 'rzSliderModel' : 'rzSliderHigh'; this.tracking = pointer === this.minH ? 'rzSliderModel' : 'rzSliderHigh';
} }
...@@ -1187,29 +1128,24 @@ function throttle(func, wait, options) { ...@@ -1187,29 +1128,24 @@ function throttle(func, wait, options) {
* @param {Event} event The event * @param {Event} event The event
* @returns {undefined} * @returns {undefined}
*/ */
onMove: function (pointer, event) onMove: function(pointer, event) {
{
var eventX = this.getEventX(event), var eventX = this.getEventX(event),
sliderLO, newOffset, newValue; sliderLO, newOffset, newValue;
sliderLO = this.sliderElem.rzsl; sliderLO = this.sliderElem.rzsl;
newOffset = eventX - sliderLO - this.handleHalfWidth; newOffset = (eventX - sliderLO - this.handleHalfWidth) * this.options.scale;
if(newOffset <= 0) if (newOffset <= 0) {
{ if (pointer.rzsl === 0)
if(pointer.rzsl === 0)
return; return;
newValue = this.minValue; newValue = this.minValue;
newOffset = 0; newOffset = 0;
} } else if (newOffset >= this.maxLeft) {
else if(newOffset >= this.maxLeft) if (pointer.rzsl === this.maxLeft)
{
if(pointer.rzsl === this.maxLeft)
return; return;
newValue = this.maxValue; newValue = this.maxValue;
newOffset = this.maxLeft; newOffset = this.maxLeft;
} } else {
else {
newValue = this.offsetToValue(newOffset); newValue = this.offsetToValue(newOffset);
newValue = this.roundStep(newValue); newValue = this.roundStep(newValue);
newOffset = this.valueToOffset(newValue); newOffset = this.valueToOffset(newValue);
...@@ -1227,8 +1163,7 @@ function throttle(func, wait, options) { ...@@ -1227,8 +1163,7 @@ function throttle(func, wait, options) {
* @param {Event} event The event * @param {Event} event The event
* @returns {undefined} * @returns {undefined}
*/ */
onDragStart: function(pointer, ref, event) onDragStart: function(pointer, ref, event) {
{
var offset = this.getEventX(event) - this.sliderElem.rzsl - this.handleHalfWidth; var offset = this.getEventX(event) - this.sliderElem.rzsl - this.handleHalfWidth;
this.dragging = { this.dragging = {
active: true, active: true,
...@@ -1253,30 +1188,28 @@ function throttle(func, wait, options) { ...@@ -1253,30 +1188,28 @@ function throttle(func, wait, options) {
* @param {Event} event The event * @param {Event} event The event
* @returns {undefined} * @returns {undefined}
*/ */
onDragMove: function(pointer, event) onDragMove: function(pointer, event) {
{
var newOffset = this.getEventX(event) - this.sliderElem.rzsl - this.handleHalfWidth, var newOffset = this.getEventX(event) - this.sliderElem.rzsl - this.handleHalfWidth,
newMinOffset, newMaxOffset, newMinOffset, newMaxOffset,
newMinValue, newMaxValue; newMinValue, newMaxValue;
if (newOffset <= this.dragging.lowDist) if (newOffset <= this.dragging.lowDist) {
{ if (pointer.rzsl === this.dragging.lowDist) {
if (pointer.rzsl === this.dragging.lowDist) { return; } return;
}
newMinValue = this.minValue; newMinValue = this.minValue;
newMinOffset = 0; newMinOffset = 0;
newMaxValue = this.dragging.difference; newMaxValue = this.minValue + this.dragging.difference;
newMaxOffset = this.valueToOffset(newMaxValue); newMaxOffset = this.valueToOffset(newMaxValue);
} else if (newOffset >= this.maxLeft - this.dragging.highDist) {
if (pointer.rzsl === this.dragging.highDist) {
return;
} }
else if (newOffset >= this.maxLeft - this.dragging.highDist)
{
if (pointer.rzsl === this.dragging.highDist) { return; }
newMaxValue = this.maxValue; newMaxValue = this.maxValue;
newMaxOffset = this.maxLeft; newMaxOffset = this.maxLeft;
newMinValue = this.maxValue - this.dragging.difference; newMinValue = this.maxValue - this.dragging.difference;
newMinOffset = this.valueToOffset(newMinValue); newMinOffset = this.valueToOffset(newMinValue);
} } else {
else
{
newMinValue = this.offsetToValue(newOffset - this.dragging.lowDist); newMinValue = this.offsetToValue(newOffset - this.dragging.lowDist);
newMinValue = this.roundStep(newMinValue); newMinValue = this.roundStep(newMinValue);
newMinOffset = this.valueToOffset(newMinValue); newMinOffset = this.valueToOffset(newMinValue);
...@@ -1295,8 +1228,7 @@ function throttle(func, wait, options) { ...@@ -1295,8 +1228,7 @@ function throttle(func, wait, options) {
* @param {number} newMinOffset the new minimum offset * @param {number} newMinOffset the new minimum offset
* @param {number} newMaxOffset the new maximum offset * @param {number} newMaxOffset the new maximum offset
*/ */
positionTrackingBar: function(newMinValue, newMaxValue, newMinOffset, newMaxOffset) positionTrackingBar: function(newMinValue, newMaxValue, newMinOffset, newMaxOffset) {
{
this.scope.rzSliderModel = newMinValue; this.scope.rzSliderModel = newMinValue;
this.scope.rzSliderHigh = newMaxValue; this.scope.rzSliderHigh = newMaxValue;
this.updateHandles('rzSliderModel', newMinOffset); this.updateHandles('rzSliderModel', newMinOffset);
...@@ -1311,13 +1243,10 @@ function throttle(func, wait, options) { ...@@ -1311,13 +1243,10 @@ function throttle(func, wait, options) {
* @param {number} newValue new model value * @param {number} newValue new model value
* @param {number} newOffset new offset value * @param {number} newOffset new offset value
*/ */
positionTrackingHandle: function(newValue, newOffset) positionTrackingHandle: function(newValue, newOffset) {
{ if (this.range) {
if(this.range)
{
/* This is to check if we need to switch the min and max handles*/ /* This is to check if we need to switch the min and max handles*/
if (this.tracking === 'rzSliderModel' && newValue >= this.scope.rzSliderHigh) if (this.tracking === 'rzSliderModel' && newValue >= this.scope.rzSliderHigh) {
{
this.scope[this.tracking] = this.scope.rzSliderHigh; this.scope[this.tracking] = this.scope.rzSliderHigh;
this.updateHandles(this.tracking, this.maxH.rzsl); this.updateHandles(this.tracking, this.maxH.rzsl);
this.tracking = 'rzSliderHigh'; this.tracking = 'rzSliderHigh';
...@@ -1326,9 +1255,7 @@ function throttle(func, wait, options) { ...@@ -1326,9 +1255,7 @@ function throttle(func, wait, options) {
/* We need to apply here because we are not sure that we will enter the next block */ /* 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();
} } else if (this.tracking === 'rzSliderHigh' && newValue <= this.scope.rzSliderModel) {
else if(this.tracking === 'rzSliderHigh' && newValue <= this.scope.rzSliderModel)
{
this.scope[this.tracking] = this.scope.rzSliderModel; this.scope[this.tracking] = this.scope.rzSliderModel;
this.updateHandles(this.tracking, this.minH.rzsl); this.updateHandles(this.tracking, this.minH.rzsl);
this.tracking = 'rzSliderModel'; this.tracking = 'rzSliderModel';
...@@ -1340,8 +1267,7 @@ function throttle(func, wait, options) { ...@@ -1340,8 +1267,7 @@ function throttle(func, wait, options) {
} }
} }
if(this.scope[this.tracking] !== newValue) if (this.scope[this.tracking] !== newValue) {
{
this.scope[this.tracking] = newValue; this.scope[this.tracking] = newValue;
this.updateHandles(this.tracking, newOffset); this.updateHandles(this.tracking, newOffset);
this.scope.$apply(); this.scope.$apply();
...@@ -1356,8 +1282,7 @@ function throttle(func, wait, options) { ...@@ -1356,8 +1282,7 @@ function throttle(func, wait, options) {
* @param {Function} ehMove The the bound move event handler * @param {Function} ehMove The the bound move event handler
* @returns {undefined} * @returns {undefined}
*/ */
onEnd: function(ehMove, event) onEnd: function(ehMove, event) {
{
var moveEventName = this.getEventNames(event).moveEvent; var moveEventName = this.getEventNames(event).moveEvent;
this.minH.removeClass('rz-active'); this.minH.removeClass('rz-active');
...@@ -1379,17 +1304,16 @@ function throttle(func, wait, options) { ...@@ -1379,17 +1304,16 @@ function throttle(func, wait, options) {
* *
* @return {{moveEvent: string, endEvent: string}} * @return {{moveEvent: string, endEvent: string}}
*/ */
getEventNames: function(event) getEventNames: function(event) {
{ var eventNames = {
var eventNames = {moveEvent: '', endEvent: ''}; moveEvent: '',
endEvent: ''
};
if(event.touches || (event.originalEvent !== undefined && event.originalEvent.touches)) if (event.touches || (event.originalEvent !== undefined && event.originalEvent.touches)) {
{
eventNames.moveEvent = 'touchmove'; eventNames.moveEvent = 'touchmove';
eventNames.endEvent = 'touchend'; eventNames.endEvent = 'touchend';
} } else {
else
{
eventNames.moveEvent = 'mousemove'; eventNames.moveEvent = 'mousemove';
eventNames.endEvent = 'mouseup'; eventNames.endEvent = 'mouseup';
} }
...@@ -1399,33 +1323,18 @@ function throttle(func, wait, options) { ...@@ -1399,33 +1323,18 @@ function throttle(func, wait, options) {
}; };
return Slider; return Slider;
}]) }])
.directive('rzslider', ['RzSlider', function(RzSlider) .directive('rzslider', ['RzSlider', function(RzSlider) {
{
'use strict'; 'use strict';
return { return {
restrict: 'E', restrict: 'E',
scope: { scope: {
rzSliderFloor: '=?',
rzSliderCeil: '=?',
rzSliderStep: '@',
rzSliderPrecision: '@',
rzSliderModel: '=?', rzSliderModel: '=?',
rzSliderHigh: '=?', rzSliderHigh: '=?',
rzSliderDraggable: '@', rzSliderOptions: '=?',
rzSliderTranslate: '&', rzSliderTplUrl: '@'
rzSliderHideLimitLabels: '=?',
rzSliderAlwaysShowBar: '=?',
rzSliderPresentOnly: '@',
rzSliderOnStart: '&',
rzSliderOnChange: '&',
rzSliderOnEnd: '&',
rzSliderShowTicks: '=?',
rzSliderShowTicksValue: '=?',
rzSliderDisabled: '=?',
rzSliderInterval: '=?',
}, },
/** /**
...@@ -1440,24 +1349,23 @@ function throttle(func, wait, options) { ...@@ -1440,24 +1349,23 @@ function throttle(func, wait, options) {
return attrs.rzSliderTplUrl || 'rzSliderTpl.html'; return attrs.rzSliderTplUrl || 'rzSliderTpl.html';
}, },
link: function(scope, elem, attr) link: function(scope, elem) {
{ return new RzSlider(scope, elem);
return new RzSlider(scope, elem, attr);
} }
}; };
}]); }]);
// IDE assist // IDE assist
/** /**
* @name ngScope * @name ngScope
* *
* @property {number} rzSliderModel * @property {number} rzSliderModel
* @property {number} rzSliderHigh * @property {number} rzSliderHigh
* @property {number} rzSliderCeil * @property {Object} rzSliderOptions
*/ */
/** /**
* @name jqLite * @name jqLite
* *
* @property {number|undefined} rzsl rzslider label left offset * @property {number|undefined} rzsl rzslider label left offset
...@@ -1467,13 +1375,13 @@ function throttle(func, wait, options) { ...@@ -1467,13 +1375,13 @@ function throttle(func, wait, options) {
* @property {Function} text * @property {Function} text
*/ */
/** /**
* @name Event * @name Event
* @property {Array} touches * @property {Array} touches
* @property {Event} originalEvent * @property {Event} originalEvent
*/ */
/** /**
* @name ThrottleOptions * @name ThrottleOptions
* *
* @property {boolean} leading * @property {boolean} leading
......
/*! angularjs-slider - v1.1.0 - (c) Rafal Zajac <rzajac@gmail.com>, Valentin Hervieu <valentin@hervieu.me>, Jussi Saarivirta <jusasi@gmail.com>, Angelin Sirbu <angelin.sirbu@gmail.com>, https://github.com/rzajac/angularjs-slider.git - 2015-11-07 */ /*! angularjs-slider - v2.0.0 - (c) Rafal Zajac <rzajac@gmail.com>, Valentin Hervieu <valentin@hervieu.me>, Jussi Saarivirta <jusasi@gmail.com>, Angelin Sirbu <angelin.sirbu@gmail.com>, https://github.com/rzajac/angularjs-slider.git - 2015-11-12 */
rzslider{position:relative;display:inline-block;width:100%;height:4px;margin:30px 0 15px 0;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}rzslider[disabled]{cursor:not-allowed}rzslider[disabled] .rz-pointer{cursor:not-allowed;background-color:#d8e0f3}rzslider span{position:absolute;display:inline-block;white-space:nowrap}rzslider .rz-base{width:100%;height:100%;padding:0}rzslider .rz-bar-wrapper{left:0;z-index:1;width:100%;height:32px;padding-top:16px;margin-top:-16px;box-sizing:border-box}rzslider .rz-bar{left:0;z-index:1;width:100%;height:4px;background:#d8e0f3;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}rzslider .rz-bar.rz-selection{z-index:2;background:#0db9f0;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}rzslider .rz-pointer{top:-14px;z-index:3;width:32px;height:32px;cursor:pointer;background-color:#0db9f0;-webkit-border-radius:16px;-moz-border-radius:16px;border-radius:16px}rzslider .rz-pointer:after{position:absolute;top:12px;left:12px;width:8px;height:8px;background:#fff;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;content:''}rzslider .rz-pointer:hover:after{background-color:#fff}rzslider .rz-pointer.rz-active:after{background-color:#451aff}rzslider .rz-bubble{bottom:16px;padding:1px 3px;color:#55637d;cursor:default}rzslider .rz-bubble.rz-selection{top:16px}rzslider .rz-bubble.rz-limit{color:#55637d}rzslider .rz-ticks{position:absolute;top:-3px;left:0;z-index:1;display:flex;width:100%;padding:0 11px;margin:0;list-style:none;box-sizing:border-box;justify-content:space-between}rzslider .rz-ticks .tick{width:10px;height:10px;text-align:center;cursor:pointer;background:#d8e0f3;border-radius:50%}rzslider .rz-ticks .tick.selected{background:#0db9f0}rzslider .rz-ticks .tick .tick-value{position:absolute;top:-30px;transform:translate(-50%,0)} rzslider{position:relative;display:inline-block;width:100%;height:4px;margin:35px 0 15px 0;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}rzslider[disabled]{cursor:not-allowed}rzslider[disabled] .rz-pointer{cursor:not-allowed;background-color:#d8e0f3}rzslider span{position:absolute;display:inline-block;white-space:nowrap}rzslider .rz-base{width:100%;height:100%;padding:0}rzslider .rz-bar-wrapper{left:0;z-index:1;width:100%;height:32px;padding-top:16px;margin-top:-16px;box-sizing:border-box}rzslider .rz-bar-wrapper.rz-draggable{cursor:move}rzslider .rz-bar{left:0;z-index:1;width:100%;height:4px;background:#d8e0f3;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}rzslider .rz-bar.rz-selection{z-index:2;background:#0db9f0;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}rzslider .rz-pointer{top:-14px;z-index:3;width:32px;height:32px;cursor:pointer;background-color:#0db9f0;-webkit-border-radius:16px;-moz-border-radius:16px;border-radius:16px}rzslider .rz-pointer:after{position:absolute;top:12px;left:12px;width:8px;height:8px;background:#fff;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;content:''}rzslider .rz-pointer:hover:after{background-color:#fff}rzslider .rz-pointer.rz-active:after{background-color:#451aff}rzslider .rz-bubble{bottom:16px;padding:1px 3px;color:#55637d;cursor:default}rzslider .rz-bubble.rz-selection{top:16px}rzslider .rz-bubble.rz-limit{color:#55637d}rzslider .rz-ticks{position:absolute;top:-3px;left:0;z-index:1;display:flex;width:100%;padding:0 11px;margin:0;list-style:none;box-sizing:border-box;justify-content:space-between}rzslider .rz-ticks .tick{width:10px;height:10px;text-align:center;cursor:pointer;background:#d8e0f3;border-radius:50%}rzslider .rz-ticks .tick.selected{background:#0db9f0}rzslider .rz-ticks .tick .tick-value{position:absolute;top:-30px;transform:translate(-50%,0)}
\ No newline at end of file \ No newline at end of file
/*! angularjs-slider - v1.1.0 - (c) Rafal Zajac <rzajac@gmail.com>, Valentin Hervieu <valentin@hervieu.me>, Jussi Saarivirta <jusasi@gmail.com>, Angelin Sirbu <angelin.sirbu@gmail.com>, https://github.com/rzajac/angularjs-slider.git - 2015-11-07 */ /*! angularjs-slider - v2.0.0 - (c) Rafal Zajac <rzajac@gmail.com>, Valentin Hervieu <valentin@hervieu.me>, Jussi Saarivirta <jusasi@gmail.com>, Angelin Sirbu <angelin.sirbu@gmail.com>, https://github.com/rzajac/angularjs-slider.git - 2015-11-12 */
!function(a,b){"use strict";"function"==typeof define&&define.amd?define(["angular"],b):"object"==typeof module&&module.exports?module.exports=b(require("angular")):b(a.angular)}(this,function(a){"use strict";var b=a.module("rzModule",[]).value("throttle",function(a,b,c){var d,e,f,g=Date.now||function(){return(new Date).getTime()},h=null,i=0;c=c||{};var j=function(){i=c.leading===!1?0:g(),h=null,f=a.apply(d,e),d=e=null};return function(){var k=g();i||c.leading!==!1||(i=k);var l=b-(k-i);return d=this,e=arguments,0>=l?(clearTimeout(h),h=null,i=k,f=a.apply(d,e),d=e=null):h||c.trailing===!1||(h=setTimeout(j,l)),f}}).factory("RzSlider",["$timeout","$document","$window","throttle",function(b,c,d,e){var f=function(a,b,c){this.scope=a,this.attributes=c,this.sliderElem=b,this.range=void 0!==c.rzSliderHigh&&void 0!==c.rzSliderModel,this.dragRange=this.range&&"true"===c.rzSliderDraggableRange,this.dragging={active:!1,value:0,difference:0,offset:0,lowDist:0,highDist:0},this.handleHalfWidth=0,this.alwaysShowBar=!!c.rzSliderAlwaysShowBar,this.maxLeft=0,this.precision=0,this.step=0,this.tracking="",this.minValue=0,this.maxValue=0,this.hideLimitLabels=!!c.rzSliderHideLimitLabels,this.presentOnly="true"===c.rzSliderPresentOnly,this.showTicks=c.rzSliderShowTicks||c.rzSliderShowTicksValue,this.showTicksValue=c.rzSliderShowTicksValue,this.disabled=this.scope.rzSliderDisabled,this.interval=null!==this.scope.rzSliderInterval?this.scope.rzSliderInterval:350,this.valueRange=0,this.initHasRun=!1,this.customTrFn=this.scope.rzSliderTranslate()||function(a){return String(a)},this.deRegFuncs=[],this.fullBar=null,this.selBar=null,this.minH=null,this.maxH=null,this.flrLab=null,this.ceilLab=null,this.minLab=null,this.maxLab=null,this.cmbLab=null,this.ticks=null,this.init()};return f.prototype={init:function(){var c,f,g,h=a.bind(this,this.calcViewDimensions),i=this;this.initElemHandles(),this.addAccessibility(),this.setDisabledState(),this.calcViewDimensions(),this.setMinAndMax(),this.precision=void 0===this.scope.rzSliderPrecision?0:+this.scope.rzSliderPrecision,this.step=void 0===this.scope.rzSliderStep?1:+this.scope.rzSliderStep,b(function(){i.updateCeilLab(),i.updateFloorLab(),i.initHandles(),i.bindEvents()}),g=this.scope.$on("reCalcViewDimensions",h),this.deRegFuncs.push(g),a.element(d).on("resize",h),this.initHasRun=!0,c=e(function(){i.setMinAndMax(),i.updateLowHandle(i.valueToOffset(i.scope.rzSliderModel)),i.updateSelectionBar(),i.updateTicksScale(),i.range&&i.updateCmbLabel()},i.interval),f=e(function(){i.setMinAndMax(),i.updateHighHandle(i.valueToOffset(i.scope.rzSliderHigh)),i.updateSelectionBar(),i.updateTicksScale(),i.updateCmbLabel()},i.interval),this.scope.$on("rzSliderForceRender",function(){i.resetLabelsValue(),c(),i.range&&f(),i.resetSlider()}),g=this.scope.$watch("rzSliderModel",function(a,b){a!==b&&c()}),this.deRegFuncs.push(g),g=this.scope.$watch("rzSliderHigh",function(a,b){a!==b&&f()}),this.deRegFuncs.push(g),this.scope.$watch("rzSliderFloor",function(a,b){a!==b&&i.resetSlider()}),this.deRegFuncs.push(g),g=this.scope.$watch("rzSliderCeil",function(a,b){a!==b&&i.resetSlider()}),this.deRegFuncs.push(g),g=this.scope.$watch("rzSliderShowTicks",function(a,b){a!==b&&i.resetSlider()}),this.deRegFuncs.push(g),g=this.scope.$watch("rzSliderShowTicksValue",function(a,b){a!==b&&i.resetSlider()}),this.deRegFuncs.push(g),g=this.scope.$watch("rzSliderDisabled",function(a,b){a!==b&&(i.resetSlider(),i.disabled?i.unbindEvents():i.bindEvents())}),this.deRegFuncs.push(g),this.scope.$on("$destroy",function(){i.unbindEvents(),a.element(d).off("resize",h),i.deRegFuncs.map(function(a){a()})})},resetSlider:function(){this.setMinAndMax(),this.updateCeilLab(),this.updateFloorLab(),this.setDisabledState(),this.calcViewDimensions()},setDisabledState:function(){this.disabled=this.scope.rzSliderDisabled,this.disabled?this.sliderElem.attr("disabled","disabled"):this.sliderElem.attr("disabled",null)},resetLabelsValue:function(){this.minLab.rzsv=void 0,this.maxLab.rzsv=void 0},initHandles:function(){this.updateLowHandle(this.valueToOffset(this.scope.rzSliderModel)),this.range&&this.updateHighHandle(this.valueToOffset(this.scope.rzSliderHigh)),this.updateSelectionBar(),this.range&&this.updateCmbLabel(),this.updateTicksScale()},translateFn:function(a,b,c){c=void 0===c?!0:c;var d=(c?this.customTrFn(a):a).toString(),e=!1;(void 0===b.rzsv||b.rzsv.length!==d.length||b.rzsv.length>0&&0===b.rzsw)&&(e=!0,b.rzsv=d),b.text(d),e&&this.getWidth(b)},setMinAndMax:function(){this.scope.rzSliderFloor?this.minValue=+this.scope.rzSliderFloor:this.minValue=this.scope.rzSliderFloor=0,this.scope.rzSliderCeil?this.maxValue=+this.scope.rzSliderCeil:this.maxValue=this.scope.rzSliderCeil=this.range?this.scope.rzSliderHigh:this.scope.rzSliderModel,this.scope.rzSliderStep&&(this.step=+this.scope.rzSliderStep),this.valueRange=this.maxValue-this.minValue},initElemHandles:function(){a.forEach(this.sliderElem.children(),function(b,c){var d=a.element(b);switch(c){case 0:this.fullBar=d;break;case 1:this.selBar=d;break;case 2:this.minH=d;break;case 3:this.maxH=d;break;case 4:this.flrLab=d;break;case 5:this.ceilLab=d;break;case 6:this.minLab=d;break;case 7:this.maxLab=d;break;case 8:this.cmbLab=d;break;case 9:this.ticks=d}},this),this.selBar.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,this.hideLimitLabels&&(this.flrLab.rzAlwaysHide=!0,this.ceilLab.rzAlwaysHide=!0,this.hideEl(this.flrLab),this.hideEl(this.ceilLab)),this.showTicksValue&&(this.flrLab.rzAlwaysHide=!0,this.ceilLab.rzAlwaysHide=!0,this.minLab.rzAlwaysHide=!0,this.maxLab.rzAlwaysHide=!0,this.cmbLab.rzAlwaysHide=!0,this.hideEl(this.flrLab),this.hideEl(this.ceilLab),this.hideEl(this.minLab),this.hideEl(this.maxLab),this.hideEl(this.cmbLab)),this.range===!1&&(this.cmbLab.remove(),this.maxLab.remove(),this.maxH.rzAlwaysHide=!0,this.maxH[0].style.zIndex="-1000",this.hideEl(this.maxH)),this.range===!1&&this.alwaysShowBar===!1&&(this.maxH.remove(),this.selBar.remove()),this.dragRange&&(this.selBar.css("cursor","move"),this.selBar.addClass("rz-draggable"))},addAccessibility:function(){this.sliderElem.attr("role","slider")},calcViewDimensions:function(){var a=this.getWidth(this.minH);this.handleHalfWidth=a/2,this.barWidth=this.getWidth(this.fullBar),this.maxLeft=this.barWidth-a,this.getWidth(this.sliderElem),this.sliderElem.rzsl=this.sliderElem[0].getBoundingClientRect().left,this.initHasRun&&(this.updateFloorLab(),this.updateCeilLab(),this.initHandles())},updateTicksScale:function(){if(this.showTicks&&this.step){for(var a="",b=Math.round((this.maxValue-this.minValue)/this.step)+1,c=0;b>c;c++){var d=this.roundStep(this.minValue+c*this.step),e=this.isTickSelected(d)?"selected":"";a+='<li class="tick '+e+'">',this.showTicksValue&&(a+='<span class="tick-value">'+this.getDisplayValue(d)+"</span>"),a+="</li>"}this.ticks.html(a)}},isTickSelected:function(a){this.valueToOffset(a);return!this.range&&this.alwaysShowBar&&a<=this.scope.rzSliderModel?!0:this.range&&a>=this.scope.rzSliderModel&&a<=this.scope.rzSliderHigh?!0:!1},updateCeilLab:function(){this.translateFn(this.scope.rzSliderCeil,this.ceilLab),this.setLeft(this.ceilLab,this.barWidth-this.ceilLab.rzsw),this.getWidth(this.ceilLab)},updateFloorLab:function(){this.translateFn(this.scope.rzSliderFloor,this.flrLab),this.getWidth(this.flrLab)},callOnStart:function(){if(this.scope.rzSliderOnStart){var a=this;b(function(){a.scope.rzSliderOnStart()})}},callOnChange:function(){if(this.scope.rzSliderOnChange){var a=this;b(function(){a.scope.rzSliderOnChange()})}},callOnEnd:function(){if(this.scope.rzSliderOnEnd){var a=this;b(function(){a.scope.rzSliderOnEnd()})}},updateHandles:function(a,b){return"rzSliderModel"===a?(this.updateLowHandle(b),this.updateSelectionBar(),this.updateTicksScale(),void(this.range&&this.updateCmbLabel())):"rzSliderHigh"===a?(this.updateHighHandle(b),this.updateSelectionBar(),this.updateTicksScale(),void(this.range&&this.updateCmbLabel())):(this.updateLowHandle(b),this.updateHighHandle(b),this.updateSelectionBar(),this.updateTicksScale(),void this.updateCmbLabel())},updateLowHandle:function(a){this.setLeft(this.minH,a),this.translateFn(this.scope.rzSliderModel,this.minLab),this.setLeft(this.minLab,a-this.minLab.rzsw/2+this.handleHalfWidth),this.shFloorCeil()},updateHighHandle:function(a){this.setLeft(this.maxH,a),this.translateFn(this.scope.rzSliderHigh,this.maxLab),this.setLeft(this.maxLab,a-this.maxLab.rzsw/2+this.handleHalfWidth),this.shFloorCeil()},shFloorCeil:function(){var a=!1,b=!1;this.minLab.rzsl<=this.flrLab.rzsl+this.flrLab.rzsw+5?(a=!0,this.hideEl(this.flrLab)):(a=!1,this.showEl(this.flrLab)),this.minLab.rzsl+this.minLab.rzsw>=this.ceilLab.rzsl-this.handleHalfWidth-10?(b=!0,this.hideEl(this.ceilLab)):(b=!1,this.showEl(this.ceilLab)),this.range&&(this.maxLab.rzsl+this.maxLab.rzsw>=this.ceilLab.rzsl-10?this.hideEl(this.ceilLab):b||this.showEl(this.ceilLab),this.maxLab.rzsl<=this.flrLab.rzsl+this.flrLab.rzsw+this.handleHalfWidth?this.hideEl(this.flrLab):a||this.showEl(this.flrLab))},updateSelectionBar:function(){this.setWidth(this.selBar,Math.abs(this.maxH.rzsl-this.minH.rzsl)+this.handleHalfWidth),this.setLeft(this.selBar,this.range?this.minH.rzsl+this.handleHalfWidth:0)},updateCmbLabel:function(){var a,b;this.minLab.rzsl+this.minLab.rzsw+10>=this.maxLab.rzsl?(a=this.getDisplayValue(this.scope.rzSliderModel),b=this.getDisplayValue(this.scope.rzSliderHigh),this.translateFn(a+" - "+b,this.cmbLab,!1),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)):(this.showEl(this.maxLab),this.showEl(this.minLab),this.hideEl(this.cmbLab))},getDisplayValue:function(a){return this.customTrFn?this.customTrFn(a):a},roundStep:function(a){var b=this.step,c=+((a-this.minValue)%b).toFixed(3),d=c>b/2?a+b-c:a-c;return d=d.toFixed(this.precision),+d},hideEl:function(a){return a.css({opacity:0})},showEl:function(a){return a.rzAlwaysHide?a:a.css({opacity:1})},setLeft:function(a,b){return a.rzsl=b,a.css({left:b+"px"}),b},getWidth:function(a){var b=a[0].getBoundingClientRect();return a.rzsw=b.right-b.left,a.rzsw},setWidth:function(a,b){return a.rzsw=b,a.css({width:b+"px"}),b},valueToOffset:function(a){return(a-this.minValue)*this.maxLeft/this.valueRange||0},offsetToValue:function(a){return a/this.maxLeft*this.valueRange+this.minValue},getEventX:function(a){return"clientX"in a?a.clientX:void 0===a.originalEvent?a.touches[0].clientX:a.originalEvent.touches[0].clientX},getNearestHandle:function(a){if(!this.range)return this.minH;var b=this.getEventX(a)-this.sliderElem.rzsl-this.handleHalfWidth;return Math.abs(b-this.minH.rzsl)<Math.abs(b-this.maxH.rzsl)?this.minH:this.maxH},bindEvents:function(){if(!this.presentOnly&&!this.disabled){var b,c,d;this.dragRange?(b="rzSliderDrag",c=this.onDragStart,d=this.onDragMove):(b="rzSliderModel",c=this.onStart,d=this.onMove),this.minH.on("mousedown",a.bind(this,this.onStart,this.minH,"rzSliderModel")),this.range&&this.maxH.on("mousedown",a.bind(this,this.onStart,this.maxH,"rzSliderHigh")),this.fullBar.on("mousedown",a.bind(this,this.onStart,null,null)),this.fullBar.on("mousedown",a.bind(this,this.onMove,this.fullBar)),this.selBar.on("mousedown",a.bind(this,c,null,b)),this.selBar.on("mousedown",a.bind(this,d,this.selBar)),this.ticks.on("mousedown",a.bind(this,this.onStart,null,null)),this.ticks.on("mousedown",a.bind(this,this.onMove,this.ticks)),this.minH.on("touchstart",a.bind(this,this.onStart,this.minH,"rzSliderModel")),this.range&&this.maxH.on("touchstart",a.bind(this,this.onStart,this.maxH,"rzSliderHigh")),this.fullBar.on("touchstart",a.bind(this,this.onStart,null,null)),this.fullBar.on("touchstart",a.bind(this,this.onMove,this.fullBar)),this.selBar.on("touchstart",a.bind(this,c,null,b)),this.selBar.on("touchstart",a.bind(this,d,this.selBar)),this.ticks.on("touchstart",a.bind(this,this.onStart,null,null)),this.ticks.on("touchstart",a.bind(this,this.onMove,this.ticks))}},unbindEvents:function(){this.minH.off(),this.maxH.off(),this.fullBar.off(),this.selBar.off(),this.ticks.off()},onStart:function(b,d,e){var f,g,h=this.getEventNames(e);e.stopPropagation(),e.preventDefault(),""===this.tracking&&(this.calcViewDimensions(),b?this.tracking=d:(b=this.getNearestHandle(e),this.tracking=b===this.minH?"rzSliderModel":"rzSliderHigh"),b.addClass("rz-active"),f=a.bind(this,this.dragging.active?this.onDragMove:this.onMove,b),g=a.bind(this,this.onEnd,f),c.on(h.moveEvent,f),c.one(h.endEvent,g),this.callOnStart())},onMove:function(a,b){var c,d,e,f=this.getEventX(b);if(c=this.sliderElem.rzsl,d=f-c-this.handleHalfWidth,0>=d){if(0===a.rzsl)return;e=this.minValue,d=0}else if(d>=this.maxLeft){if(a.rzsl===this.maxLeft)return;e=this.maxValue,d=this.maxLeft}else e=this.offsetToValue(d),e=this.roundStep(e),d=this.valueToOffset(e);this.positionTrackingHandle(e,d)},onDragStart:function(a,b,c){var d=this.getEventX(c)-this.sliderElem.rzsl-this.handleHalfWidth;this.dragging={active:!0,value:this.offsetToValue(d),difference:this.scope.rzSliderHigh-this.scope.rzSliderModel,offset:d,lowDist:d-this.minH.rzsl,highDist:this.maxH.rzsl-d},this.minH.addClass("rz-active"),this.maxH.addClass("rz-active"),this.onStart(a,b,c)},onDragMove:function(a,b){var c,d,e,f,g=this.getEventX(b)-this.sliderElem.rzsl-this.handleHalfWidth;if(g<=this.dragging.lowDist){if(a.rzsl===this.dragging.lowDist)return;e=this.minValue,c=0,f=this.dragging.difference,d=this.valueToOffset(f)}else if(g>=this.maxLeft-this.dragging.highDist){if(a.rzsl===this.dragging.highDist)return;f=this.maxValue,d=this.maxLeft,e=this.maxValue-this.dragging.difference,c=this.valueToOffset(e)}else e=this.offsetToValue(g-this.dragging.lowDist),e=this.roundStep(e),c=this.valueToOffset(e),f=e+this.dragging.difference,d=this.valueToOffset(f);this.positionTrackingBar(e,f,c,d)},positionTrackingBar:function(a,b,c,d){this.scope.rzSliderModel=a,this.scope.rzSliderHigh=b,this.updateHandles("rzSliderModel",c),this.updateHandles("rzSliderHigh",d),this.scope.$apply(),this.callOnChange()},positionTrackingHandle:function(a,b){this.range&&("rzSliderModel"===this.tracking&&a>=this.scope.rzSliderHigh?(this.scope[this.tracking]=this.scope.rzSliderHigh,this.updateHandles(this.tracking,this.maxH.rzsl),this.tracking="rzSliderHigh",this.minH.removeClass("rz-active"),this.maxH.addClass("rz-active"),this.scope.$apply(),this.callOnChange()):"rzSliderHigh"===this.tracking&&a<=this.scope.rzSliderModel&&(this.scope[this.tracking]=this.scope.rzSliderModel,this.updateHandles(this.tracking,this.minH.rzsl),this.tracking="rzSliderModel",this.maxH.removeClass("rz-active"),this.minH.addClass("rz-active"),this.scope.$apply(),this.callOnChange())),this.scope[this.tracking]!==a&&(this.scope[this.tracking]=a,this.updateHandles(this.tracking,b),this.scope.$apply(),this.callOnChange())},onEnd:function(a,b){var d=this.getEventNames(b).moveEvent;this.minH.removeClass("rz-active"),this.maxH.removeClass("rz-active"),c.off(d,a),this.scope.$emit("slideEnded"),this.tracking="",this.dragging.active=!1,this.callOnEnd()},getEventNames:function(a){var b={moveEvent:"",endEvent:""};return a.touches||void 0!==a.originalEvent&&a.originalEvent.touches?(b.moveEvent="touchmove",b.endEvent="touchend"):(b.moveEvent="mousemove",b.endEvent="mouseup"),b}},f}]).directive("rzslider",["RzSlider",function(a){return{restrict:"E",scope:{rzSliderFloor:"=?",rzSliderCeil:"=?",rzSliderStep:"@",rzSliderPrecision:"@",rzSliderModel:"=?",rzSliderHigh:"=?",rzSliderDraggable:"@",rzSliderTranslate:"&",rzSliderHideLimitLabels:"=?",rzSliderAlwaysShowBar:"=?",rzSliderPresentOnly:"@",rzSliderOnStart:"&",rzSliderOnChange:"&",rzSliderOnEnd:"&",rzSliderShowTicks:"=?",rzSliderShowTicksValue:"=?",rzSliderDisabled:"=?",rzSliderInterval:"=?"},templateUrl:function(a,b){return b.rzSliderTplUrl||"rzSliderTpl.html"},link:function(b,c,d){return new a(b,c,d)}}}]);return b.run(["$templateCache",function(a){a.put("rzSliderTpl.html",'<span class=rz-bar-wrapper><span class=rz-bar></span></span> <span class=rz-bar-wrapper><span class="rz-bar rz-selection"></span></span> <span class=rz-pointer></span> <span class=rz-pointer></span> <span class="rz-bubble rz-limit"></span> <span class="rz-bubble rz-limit"></span> <span class=rz-bubble></span> <span class=rz-bubble></span> <span class=rz-bubble></span><ul class=rz-ticks></ul>')}]),b}); !function(a,b){"use strict";"function"==typeof define&&define.amd?define(["angular"],b):"object"==typeof module&&module.exports?module.exports=b(require("angular")):b(a.angular)}(this,function(a){"use strict";var b=a.module("rzModule",[]).factory("RzSliderOptions",function(){var b={floor:0,ceil:null,step:1,precision:0,id:null,translate:null,stepsArray:null,draggableRange:!1,showSelectionBar:!1,hideLimitLabels:!1,readOnly:!1,disabled:!1,interval:350,showTicks:!1,showTicksValues:!1,ticksValuesTooltip:null,scale:1,onStart:null,onChange:null,onEnd:null},c={},d={};return d.options=function(b){a.extend(c,b)},d.getOptions=function(d){return a.extend({},b,c,d)},d}).value("rzThrottle",function(a,b,c){var d,e,f,g=Date.now||function(){return(new Date).getTime()},h=null,i=0;c=c||{};var j=function(){i=c.leading===!1?0:g(),h=null,f=a.apply(d,e),d=e=null};return function(){var k=g();i||c.leading!==!1||(i=k);var l=b-(k-i);return d=this,e=arguments,0>=l?(clearTimeout(h),h=null,i=k,f=a.apply(d,e),d=e=null):h||c.trailing===!1||(h=setTimeout(j,l)),f}}).factory("RzSlider",["$timeout","$document","$window","$compile","RzSliderOptions","rzThrottle",function(b,c,d,e,f,g){var h=function(a,b){this.scope=a,this.sliderElem=b,this.range=void 0!==this.scope.rzSliderModel&&void 0!==this.scope.rzSliderHigh,this.dragging={active:!1,value:0,difference:0,offset:0,lowDist:0,highDist:0},this.handleHalfWidth=0,this.maxLeft=0,this.precision=0,this.step=0,this.tracking="",this.minValue=0,this.maxValue=0,this.valueRange=0,this.initHasRun=!1,this.fullBar=null,this.selBar=null,this.minH=null,this.maxH=null,this.flrLab=null,this.ceilLab=null,this.minLab=null,this.maxLab=null,this.cmbLab=null,this.ticks=null,this.init()};return h.prototype={init:function(){var c,e,f=a.bind(this,this.calcViewDimensions),h=this;this.applyOptions(),this.initElemHandles(),this.manageElementsStyle(),this.addAccessibility(),this.manageEventsBindings(),this.setDisabledState(),this.calcViewDimensions(),this.setMinAndMax(),b(function(){h.updateCeilLab(),h.updateFloorLab(),h.initHandles(),h.bindEvents()}),this.scope.$on("reCalcViewDimensions",f),a.element(d).on("resize",f),this.initHasRun=!0,c=g(function(){h.setMinAndMax(),h.updateLowHandle(h.valueToOffset(h.scope.rzSliderModel)),h.updateSelectionBar(),h.updateTicksScale(),h.range&&h.updateCmbLabel()},h.options.interval),e=g(function(){h.setMinAndMax(),h.updateHighHandle(h.valueToOffset(h.scope.rzSliderHigh)),h.updateSelectionBar(),h.updateTicksScale(),h.updateCmbLabel()},h.options.interval),this.scope.$on("rzSliderForceRender",function(){h.resetLabelsValue(),c(),h.range&&e(),h.resetSlider()}),this.scope.$watch("rzSliderModel",function(a,b){a!==b&&c()}),this.scope.$watch("rzSliderHigh",function(a,b){a!==b&&(null!=a&&e(),(h.range&&null==a||!h.range&&null!=a)&&(h.applyOptions(),h.resetSlider()))}),this.scope.$watch("rzSliderOptions",function(a,b){a!==b&&(h.applyOptions(),h.resetSlider())},!0),this.scope.$on("$destroy",function(){h.unbindEvents(),a.element(d).off("resize",f)})},applyOptions:function(){this.options=f.getOptions(this.scope.rzSliderOptions),this.options.step<=0&&(this.options.step=1),this.range=void 0!==this.scope.rzSliderModel&&void 0!==this.scope.rzSliderHigh,this.options.draggableRange=this.range&&this.options.draggableRange,this.options.showTicks=this.options.showTicks||this.options.showTicksValues,this.options.stepsArray?(this.options.floor=0,this.options.ceil=this.options.stepsArray.length-1,this.options.step=1,this.customTrFn=function(a){return this.options.stepsArray[a]}):this.options.translate?this.customTrFn=this.options.translate:this.customTrFn=function(a){return String(a)}},resetSlider:function(){this.manageElementsStyle(),this.setMinAndMax(),this.updateCeilLab(),this.updateFloorLab(),this.unbindEvents(),this.manageEventsBindings(),this.setDisabledState(),this.calcViewDimensions()},initElemHandles:function(){a.forEach(this.sliderElem.children(),function(b,c){var d=a.element(b);switch(c){case 0:this.fullBar=d;break;case 1:this.selBar=d;break;case 2:this.minH=d;break;case 3:this.maxH=d;break;case 4:this.flrLab=d;break;case 5:this.ceilLab=d;break;case 6:this.minLab=d;break;case 7:this.maxLab=d;break;case 8:this.cmbLab=d;break;case 9:this.ticks=d}},this),this.selBar.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},manageElementsStyle:function(){this.range?this.maxH.css("display",null):this.maxH.css("display","none"),this.alwaysHide(this.flrLab,this.options.showTicksValues||this.options.hideLimitLabels),this.alwaysHide(this.ceilLab,this.options.showTicksValues||this.options.hideLimitLabels),this.alwaysHide(this.minLab,this.options.showTicksValues),this.alwaysHide(this.maxLab,this.options.showTicksValues||!this.range),this.alwaysHide(this.cmbLab,this.options.showTicksValues||!this.range),this.alwaysHide(this.selBar,!this.range&&!this.options.showSelectionBar),this.options.showTicks||this.ticks.html(""),this.options.draggableRange?this.selBar.addClass("rz-draggable"):this.selBar.removeClass("rz-draggable")},alwaysHide:function(a,b){a.rzAlwaysHide=b,b?this.hideEl(a):this.showEl(a)},manageEventsBindings:function(){this.options.disabled||this.options.readOnly?this.unbindEvents():this.options.disabled&&this.options.readOnly||this.bindEvents()},setDisabledState:function(){this.options.disabled?this.sliderElem.attr("disabled","disabled"):this.sliderElem.attr("disabled",null)},resetLabelsValue:function(){this.minLab.rzsv=void 0,this.maxLab.rzsv=void 0},initHandles:function(){this.updateLowHandle(this.valueToOffset(this.scope.rzSliderModel)),this.range&&this.updateHighHandle(this.valueToOffset(this.scope.rzSliderHigh)),this.updateSelectionBar(),this.range&&this.updateCmbLabel(),this.updateTicksScale()},translateFn:function(a,b,c){c=void 0===c?!0:c;var d=String(c?this.customTrFn(a,this.options.id):a),e=!1;(void 0===b.rzsv||b.rzsv.length!==d.length||b.rzsv.length>0&&0===b.rzsw)&&(e=!0,b.rzsv=d),b.text(d),e&&this.getWidth(b)},setMinAndMax:function(){this.step=+this.options.step,this.precision=+this.options.precision,this.scope.rzSliderModel=this.roundStep(this.scope.rzSliderModel),this.range&&(this.scope.rzSliderHigh=this.roundStep(this.scope.rzSliderHigh)),this.minValue=this.roundStep(+this.options.floor),null!=this.options.ceil?this.maxValue=this.roundStep(+this.options.ceil):this.maxValue=this.options.ceil=this.range?this.scope.rzSliderHigh:this.scope.rzSliderModel,this.valueRange=this.maxValue-this.minValue},addAccessibility:function(){this.sliderElem.attr("role","slider")},calcViewDimensions:function(){var a=this.getWidth(this.minH);this.handleHalfWidth=a/2,this.barWidth=this.getWidth(this.fullBar),this.maxLeft=this.barWidth-a,this.getWidth(this.sliderElem),this.sliderElem.rzsl=this.sliderElem[0].getBoundingClientRect().left,this.initHasRun&&(this.updateFloorLab(),this.updateCeilLab(),this.initHandles())},updateTicksScale:function(){if(this.options.showTicks&&this.step){for(var a="",b=Math.round((this.maxValue-this.minValue)/this.step)+1,c=0;b>c;c++){var d=this.roundStep(this.minValue+c*this.step),f=this.isTickSelected(d)?"selected":"";if(a+='<li class="tick '+f+'">',this.options.showTicksValues){var g="";this.options.ticksValuesTooltip&&(g='uib-tooltip="'+this.options.ticksValuesTooltip(d)+'"'),a+="<span "+g+' class="tick-value">'+this.getDisplayValue(d)+"</span>"}a+="</li>"}this.ticks.html(a),this.options.ticksValuesTooltip&&e(this.ticks.contents())(this.scope)}},isTickSelected:function(a){return!this.range&&this.options.showSelectionBar&&a<=this.scope.rzSliderModel?!0:this.range&&a>=this.scope.rzSliderModel&&a<=this.scope.rzSliderHigh?!0:!1},updateCeilLab:function(){this.translateFn(this.maxValue,this.ceilLab),this.setLeft(this.ceilLab,this.barWidth-this.ceilLab.rzsw),this.getWidth(this.ceilLab)},updateFloorLab:function(){this.translateFn(this.minValue,this.flrLab),this.getWidth(this.flrLab)},callOnStart:function(){if(this.options.onStart){var a=this;b(function(){a.options.onStart()})}},callOnChange:function(){if(this.options.onChange){var a=this;b(function(){a.options.onChange()})}},callOnEnd:function(){if(this.options.onEnd){var a=this;b(function(){a.options.onEnd()})}},updateHandles:function(a,b){return"rzSliderModel"===a?(this.updateLowHandle(b),this.updateSelectionBar(),this.updateTicksScale(),void(this.range&&this.updateCmbLabel())):"rzSliderHigh"===a?(this.updateHighHandle(b),this.updateSelectionBar(),this.updateTicksScale(),void(this.range&&this.updateCmbLabel())):(this.updateLowHandle(b),this.updateHighHandle(b),this.updateSelectionBar(),this.updateTicksScale(),void this.updateCmbLabel())},updateLowHandle:function(a){this.setLeft(this.minH,a),this.translateFn(this.scope.rzSliderModel,this.minLab),this.setLeft(this.minLab,a-this.minLab.rzsw/2+this.handleHalfWidth),this.shFloorCeil()},updateHighHandle:function(a){this.setLeft(this.maxH,a),this.translateFn(this.scope.rzSliderHigh,this.maxLab),this.setLeft(this.maxLab,a-this.maxLab.rzsw/2+this.handleHalfWidth),this.shFloorCeil()},shFloorCeil:function(){var a=!1,b=!1;this.minLab.rzsl<=this.flrLab.rzsl+this.flrLab.rzsw+5?(a=!0,this.hideEl(this.flrLab)):(a=!1,this.showEl(this.flrLab)),this.minLab.rzsl+this.minLab.rzsw>=this.ceilLab.rzsl-this.handleHalfWidth-10?(b=!0,this.hideEl(this.ceilLab)):(b=!1,this.showEl(this.ceilLab)),this.range&&(this.maxLab.rzsl+this.maxLab.rzsw>=this.ceilLab.rzsl-10?this.hideEl(this.ceilLab):b||this.showEl(this.ceilLab),this.maxLab.rzsl<=this.flrLab.rzsl+this.flrLab.rzsw+this.handleHalfWidth?this.hideEl(this.flrLab):a||this.showEl(this.flrLab))},updateSelectionBar:function(){this.setWidth(this.selBar,Math.abs(this.maxH.rzsl-this.minH.rzsl)+this.handleHalfWidth),this.setLeft(this.selBar,this.range?this.minH.rzsl+this.handleHalfWidth:0)},updateCmbLabel:function(){var a,b;this.minLab.rzsl+this.minLab.rzsw+10>=this.maxLab.rzsl?(a=this.getDisplayValue(this.scope.rzSliderModel),b=this.getDisplayValue(this.scope.rzSliderHigh),this.translateFn(a+" - "+b,this.cmbLab,!1),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)):(this.showEl(this.maxLab),this.showEl(this.minLab),this.hideEl(this.cmbLab))},getDisplayValue:function(a){return this.customTrFn(a,this.options.id)},roundStep:function(a){var b=this.step,c=+((a-this.minValue)%b).toFixed(3),d=c>b/2?a+b-c:a-c;return d=d.toFixed(this.precision),+d},hideEl:function(a){return a.css({opacity:0})},showEl:function(a){return a.rzAlwaysHide?a:a.css({opacity:1})},setLeft:function(a,b){return a.rzsl=b,a.css({left:b+"px"}),b},getWidth:function(a){var b=a[0].getBoundingClientRect();return a.rzsw=(b.right-b.left)*this.options.scale,a.rzsw},setWidth:function(a,b){return a.rzsw=b,a.css({width:b+"px"}),b},valueToOffset:function(a){return(this.sanitizeOffsetValue(a)-this.minValue)*this.maxLeft/this.valueRange||0},sanitizeOffsetValue:function(a){return Math.min(Math.max(a,this.minValue),this.maxValue)},offsetToValue:function(a){return a/this.maxLeft*this.valueRange+this.minValue},getEventX:function(a){return"clientX"in a?a.clientX:void 0===a.originalEvent?a.touches[0].clientX:a.originalEvent.touches[0].clientX},getNearestHandle:function(a){if(!this.range)return this.minH;var b=(this.getEventX(a)-this.sliderElem.rzsl-this.handleHalfWidth)*this.options.scale;return Math.abs(b-this.minH.rzsl)<Math.abs(b-this.maxH.rzsl)?this.minH:this.maxH},bindEvents:function(){if(!this.options.readOnly&&!this.options.disabled){var b,c,d;this.options.draggableRange?(b="rzSliderDrag",c=this.onDragStart,d=this.onDragMove):(b="rzSliderModel",c=this.onStart,d=this.onMove),this.minH.on("mousedown",a.bind(this,this.onStart,this.minH,"rzSliderModel")),this.range&&this.maxH.on("mousedown",a.bind(this,this.onStart,this.maxH,"rzSliderHigh")),this.fullBar.on("mousedown",a.bind(this,this.onStart,null,null)),this.fullBar.on("mousedown",a.bind(this,this.onMove,this.fullBar)),this.selBar.on("mousedown",a.bind(this,c,null,b)),this.selBar.on("mousedown",a.bind(this,d,this.selBar)),this.ticks.on("mousedown",a.bind(this,this.onStart,null,null)),this.ticks.on("mousedown",a.bind(this,this.onMove,this.ticks)),this.minH.on("touchstart",a.bind(this,this.onStart,this.minH,"rzSliderModel")),this.range&&this.maxH.on("touchstart",a.bind(this,this.onStart,this.maxH,"rzSliderHigh")),this.fullBar.on("touchstart",a.bind(this,this.onStart,null,null)),this.fullBar.on("touchstart",a.bind(this,this.onMove,this.fullBar)),this.selBar.on("touchstart",a.bind(this,c,null,b)),this.selBar.on("touchstart",a.bind(this,d,this.selBar)),this.ticks.on("touchstart",a.bind(this,this.onStart,null,null)),this.ticks.on("touchstart",a.bind(this,this.onMove,this.ticks))}},unbindEvents:function(){this.minH.off(),this.maxH.off(),this.fullBar.off(),this.selBar.off(),this.ticks.off()},onStart:function(b,d,e){var f,g,h=this.getEventNames(e);e.stopPropagation(),e.preventDefault(),""===this.tracking&&(this.calcViewDimensions(),b?this.tracking=d:(b=this.getNearestHandle(e),this.tracking=b===this.minH?"rzSliderModel":"rzSliderHigh"),b.addClass("rz-active"),f=a.bind(this,this.dragging.active?this.onDragMove:this.onMove,b),g=a.bind(this,this.onEnd,f),c.on(h.moveEvent,f),c.one(h.endEvent,g),this.callOnStart())},onMove:function(a,b){var c,d,e,f=this.getEventX(b);if(c=this.sliderElem.rzsl,d=(f-c-this.handleHalfWidth)*this.options.scale,0>=d){if(0===a.rzsl)return;e=this.minValue,d=0}else if(d>=this.maxLeft){if(a.rzsl===this.maxLeft)return;e=this.maxValue,d=this.maxLeft}else e=this.offsetToValue(d),e=this.roundStep(e),d=this.valueToOffset(e);this.positionTrackingHandle(e,d)},onDragStart:function(a,b,c){var d=this.getEventX(c)-this.sliderElem.rzsl-this.handleHalfWidth;this.dragging={active:!0,value:this.offsetToValue(d),difference:this.scope.rzSliderHigh-this.scope.rzSliderModel,offset:d,lowDist:d-this.minH.rzsl,highDist:this.maxH.rzsl-d},this.minH.addClass("rz-active"),this.maxH.addClass("rz-active"),this.onStart(a,b,c)},onDragMove:function(a,b){var c,d,e,f,g=this.getEventX(b)-this.sliderElem.rzsl-this.handleHalfWidth;if(g<=this.dragging.lowDist){if(a.rzsl===this.dragging.lowDist)return;e=this.minValue,c=0,f=this.minValue+this.dragging.difference,d=this.valueToOffset(f)}else if(g>=this.maxLeft-this.dragging.highDist){if(a.rzsl===this.dragging.highDist)return;f=this.maxValue,d=this.maxLeft,e=this.maxValue-this.dragging.difference,c=this.valueToOffset(e)}else e=this.offsetToValue(g-this.dragging.lowDist),e=this.roundStep(e),c=this.valueToOffset(e),f=e+this.dragging.difference,d=this.valueToOffset(f);this.positionTrackingBar(e,f,c,d)},positionTrackingBar:function(a,b,c,d){this.scope.rzSliderModel=a,this.scope.rzSliderHigh=b,this.updateHandles("rzSliderModel",c),this.updateHandles("rzSliderHigh",d),this.scope.$apply(),this.callOnChange()},positionTrackingHandle:function(a,b){this.range&&("rzSliderModel"===this.tracking&&a>=this.scope.rzSliderHigh?(this.scope[this.tracking]=this.scope.rzSliderHigh,this.updateHandles(this.tracking,this.maxH.rzsl),this.tracking="rzSliderHigh",this.minH.removeClass("rz-active"),this.maxH.addClass("rz-active"),this.scope.$apply(),this.callOnChange()):"rzSliderHigh"===this.tracking&&a<=this.scope.rzSliderModel&&(this.scope[this.tracking]=this.scope.rzSliderModel,this.updateHandles(this.tracking,this.minH.rzsl),this.tracking="rzSliderModel",this.maxH.removeClass("rz-active"),this.minH.addClass("rz-active"),this.scope.$apply(),this.callOnChange())),this.scope[this.tracking]!==a&&(this.scope[this.tracking]=a,this.updateHandles(this.tracking,b),this.scope.$apply(),this.callOnChange())},onEnd:function(a,b){var d=this.getEventNames(b).moveEvent;this.minH.removeClass("rz-active"),this.maxH.removeClass("rz-active"),c.off(d,a),this.scope.$emit("slideEnded"),this.tracking="",this.dragging.active=!1,this.callOnEnd()},getEventNames:function(a){var b={moveEvent:"",endEvent:""};return a.touches||void 0!==a.originalEvent&&a.originalEvent.touches?(b.moveEvent="touchmove",b.endEvent="touchend"):(b.moveEvent="mousemove",b.endEvent="mouseup"),b}},h}]).directive("rzslider",["RzSlider",function(a){return{restrict:"E",scope:{rzSliderModel:"=?",rzSliderHigh:"=?",rzSliderOptions:"=?",rzSliderTplUrl:"@"},templateUrl:function(a,b){return b.rzSliderTplUrl||"rzSliderTpl.html"},link:function(b,c){return new a(b,c)}}}]);return b.run(["$templateCache",function(a){a.put("rzSliderTpl.html",'<span class=rz-bar-wrapper><span class=rz-bar></span></span> <span class=rz-bar-wrapper><span class="rz-bar rz-selection"></span></span> <span class=rz-pointer></span> <span class=rz-pointer></span> <span class="rz-bubble rz-limit"></span> <span class="rz-bubble rz-limit"></span> <span class=rz-bubble></span> <span class=rz-bubble></span> <span class=rz-bubble></span><ul class=rz-ticks></ul>')}]),b});
\ No newline at end of file \ No newline at end of file
{ {
"name": "angularjs-slider", "name": "angularjs-slider",
"version": "1.1.0", "version": "2.0.0",
"description": "AngularJS slider directive with no external dependencies. Mobile friendly!.", "description": "AngularJS slider directive with no external dependencies. Mobile friendly!.",
"main": "dist/rzslider.js", "main": "dist/rzslider.js",
"repository": { "repository": {
......
...@@ -4,14 +4,14 @@ ...@@ -4,14 +4,14 @@
* (c) Rafal Zajac <rzajac@gmail.com> * (c) Rafal Zajac <rzajac@gmail.com>
* http://github.com/rzajac/angularjs-slider * http://github.com/rzajac/angularjs-slider
* *
* Version: v1.1.0 * Version: v1.0.0
* *
* Licensed under the MIT license * Licensed under the MIT license
*/ */
/*jslint unparam: true */ /*jslint unparam: true */
/*global angular: false, console: false, define, module */ /*global angular: false, console: false, define, module */
(function (root, factory) { (function(root, factory) {
'use strict'; 'use strict';
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module. // AMD. Register as an anonymous module.
...@@ -27,13 +27,59 @@ ...@@ -27,13 +27,59 @@
factory(root.angular); factory(root.angular);
} }
}(this, function (angular) { }(this, function(angular) {
'use strict'; 'use strict';
var module = angular.module('rzModule', []) var module = angular.module('rzModule', [])
.factory('RzSliderOptions', function() {
var defaultOptions = {
floor: 0,
ceil: null, //defaults to rz-slider-model
step: 1,
precision: 0,
id: null,
translate: null,
stepsArray: null,
draggableRange: false,
showSelectionBar: false,
hideLimitLabels: false,
readOnly: false,
disabled: false,
interval: 350,
showTicks: false,
showTicksValues: false,
ticksValuesTooltip: null,
scale: 1,
onStart: null,
onChange: null,
onEnd: null
};
var globalOptions = {};
var factory = {};
/**
* `options({})` allows global configuration of all sliders in the
* application.
*
* var app = angular.module( 'App', ['rzModule'], function( RzSliderOptions ) {
* // show ticks for all sliders
* RzSliderOptions.options( { showTicks: true } );
* });
*/
factory.options = function(value) {
angular.extend(globalOptions, value);
};
factory.getOptions = function(options) {
return angular.extend({}, defaultOptions, globalOptions, options);
};
.value('throttle', return factory;
})
.value('rzThrottle',
/** /**
* throttle * rzThrottle
* *
* Taken from underscore project * Taken from underscore project
* *
...@@ -42,7 +88,7 @@ var module = angular.module('rzModule', []) ...@@ -42,7 +88,7 @@ var module = angular.module('rzModule', [])
* @param {ThrottleOptions} options * @param {ThrottleOptions} options
* @returns {Function} * @returns {Function}
*/ */
function throttle(func, wait, options) { function throttle(func, wait, options) {
'use strict'; 'use strict';
var getTime = (Date.now || function() { var getTime = (Date.now || function() {
return new Date().getTime(); return new Date().getTime();
...@@ -59,7 +105,9 @@ function throttle(func, wait, options) { ...@@ -59,7 +105,9 @@ function throttle(func, wait, options) {
}; };
return function() { return function() {
var now = getTime(); var now = getTime();
if (!previous && options.leading === false) { previous = now; } if (!previous && options.leading === false) {
previous = now;
}
var remaining = wait - (now - previous); var remaining = wait - (now - previous);
context = this; context = this;
args = arguments; args = arguments;
...@@ -74,10 +122,9 @@ function throttle(func, wait, options) { ...@@ -74,10 +122,9 @@ function throttle(func, wait, options) {
} }
return result; return result;
}; };
}) })
.factory('RzSlider', function($timeout, $document, $window, throttle) .factory('RzSlider', function($timeout, $document, $window, $compile, RzSliderOptions, rzThrottle) {
{
'use strict'; 'use strict';
/** /**
...@@ -85,11 +132,9 @@ function throttle(func, wait, options) { ...@@ -85,11 +132,9 @@ function throttle(func, wait, options) {
* *
* @param {ngScope} scope The AngularJS scope * @param {ngScope} scope The AngularJS scope
* @param {Element} sliderElem The slider directive element wrapped in jqLite * @param {Element} sliderElem The slider directive element wrapped in jqLite
* @param {*} attributes The slider directive attributes
* @constructor * @constructor
*/ */
var Slider = function(scope, sliderElem, attributes) var Slider = function(scope, sliderElem) {
{
/** /**
* The slider's scope * The slider's scope
* *
...@@ -97,13 +142,6 @@ function throttle(func, wait, options) { ...@@ -97,13 +142,6 @@ function throttle(func, wait, options) {
*/ */
this.scope = scope; this.scope = scope;
/**
* The slider attributes
*
* @type {Object}
*/
this.attributes = attributes;
/** /**
* Slider element wrapped in jqLite * Slider element wrapped in jqLite
* *
...@@ -116,14 +154,7 @@ function throttle(func, wait, options) { ...@@ -116,14 +154,7 @@ function throttle(func, wait, options) {
* *
* @type {boolean} Set to true for range slider * @type {boolean} Set to true for range slider
*/ */
this.range = attributes.rzSliderHigh !== undefined && attributes.rzSliderModel !== undefined; this.range = this.scope.rzSliderModel !== undefined && this.scope.rzSliderHigh !== undefined;
/**
* Whether to allow draggable range
*
* @type {boolean} Set to true for draggable range slider
*/
this.dragRange = this.range && attributes.rzSliderDraggableRange === 'true';
/** /**
* Values recorded when first dragging the bar * Values recorded when first dragging the bar
...@@ -146,13 +177,6 @@ function throttle(func, wait, options) { ...@@ -146,13 +177,6 @@ function throttle(func, wait, options) {
*/ */
this.handleHalfWidth = 0; this.handleHalfWidth = 0;
/**
* Always show selection bar
*
* @type {boolean}
*/
this.alwaysShowBar = !!attributes.rzSliderAlwaysShowBar;
/** /**
* Maximum left the slider handle can have * Maximum left the slider handle can have
* *
...@@ -195,50 +219,6 @@ function throttle(func, wait, options) { ...@@ -195,50 +219,6 @@ function throttle(func, wait, options) {
*/ */
this.maxValue = 0; this.maxValue = 0;
/**
* Hide limit labels
*
* @type {boolean}
*/
this.hideLimitLabels = !!attributes.rzSliderHideLimitLabels;
/**
* Only present model values
*
* Do not allow to change values
*
* @type {boolean}
*/
this.presentOnly = attributes.rzSliderPresentOnly === 'true';
/**
* Display ticks on each possible value.
*
* @type {boolean}
*/
this.showTicks = attributes.rzSliderShowTicks || attributes.rzSliderShowTicksValue;
/**
* Display the value on each tick.
*
* @type {boolean}
*/
this.showTicksValue = attributes.rzSliderShowTicksValue;
/**
* Disable the slider
*
* @type {boolean}
*/
this.disabled = this.scope.rzSliderDisabled;
/**
* The interval at which the slider updates when the model/high values
* are altered from outside the slider
*
* @type {number}
*/
this.interval = this.scope.rzSliderInterval !== null ? this.scope.rzSliderInterval : 350;
/** /**
* The delta between min and max value * The delta between min and max value
...@@ -254,20 +234,6 @@ function throttle(func, wait, options) { ...@@ -254,20 +234,6 @@ function throttle(func, wait, options) {
*/ */
this.initHasRun = false; this.initHasRun = false;
/**
* Custom translate function
*
* @type {function}
*/
this.customTrFn = this.scope.rzSliderTranslate() || function(value) { return String(value); };
/**
* Array of de-registration functions to call on $destroy
*
* @type {Array.<Function>}
*/
this.deRegFuncs = [];
// 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
...@@ -292,23 +258,21 @@ function throttle(func, wait, options) { ...@@ -292,23 +258,21 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
init: function() init: function() {
{ var thrLow, thrHigh,
var thrLow, thrHigh, unRegFn,
calcDimFn = angular.bind(this, this.calcViewDimensions), calcDimFn = angular.bind(this, this.calcViewDimensions),
self = this; self = this;
this.applyOptions();
this.initElemHandles(); this.initElemHandles();
this.manageElementsStyle();
this.addAccessibility(); this.addAccessibility();
this.manageEventsBindings();
this.setDisabledState(); this.setDisabledState();
this.calcViewDimensions(); this.calcViewDimensions();
this.setMinAndMax(); this.setMinAndMax();
this.precision = this.scope.rzSliderPrecision === undefined ? 0 : +this.scope.rzSliderPrecision; $timeout(function() {
this.step = this.scope.rzSliderStep === undefined ? 1 : +this.scope.rzSliderStep;
$timeout(function()
{
self.updateCeilLab(); self.updateCeilLab();
self.updateFloorLab(); self.updateFloorLab();
self.initHandles(); self.initHandles();
...@@ -316,8 +280,7 @@ function throttle(func, wait, options) { ...@@ -316,8 +280,7 @@ function throttle(func, wait, options) {
}); });
// Recalculate slider view dimensions // Recalculate slider view dimensions
unRegFn = this.scope.$on('reCalcViewDimensions', calcDimFn); this.scope.$on('reCalcViewDimensions', calcDimFn);
this.deRegFuncs.push(unRegFn);
// Recalculate stuff if view port dimensions have changed // Recalculate stuff if view port dimensions have changed
angular.element($window).on('resize', calcDimFn); angular.element($window).on('resize', calcDimFn);
...@@ -326,98 +289,91 @@ function throttle(func, wait, options) { ...@@ -326,98 +289,91 @@ function throttle(func, wait, options) {
// Watch for changes to the model // Watch for changes to the model
thrLow = throttle(function() thrLow = rzThrottle(function() {
{
self.setMinAndMax(); self.setMinAndMax();
self.updateLowHandle(self.valueToOffset(self.scope.rzSliderModel)); self.updateLowHandle(self.valueToOffset(self.scope.rzSliderModel));
self.updateSelectionBar(); self.updateSelectionBar();
self.updateTicksScale(); self.updateTicksScale();
if(self.range) if (self.range) {
{
self.updateCmbLabel(); self.updateCmbLabel();
} }
}, self.interval); }, self.options.interval);
thrHigh = throttle(function() thrHigh = rzThrottle(function() {
{
self.setMinAndMax(); self.setMinAndMax();
self.updateHighHandle(self.valueToOffset(self.scope.rzSliderHigh)); self.updateHighHandle(self.valueToOffset(self.scope.rzSliderHigh));
self.updateSelectionBar(); self.updateSelectionBar();
self.updateTicksScale(); self.updateTicksScale();
self.updateCmbLabel(); self.updateCmbLabel();
}, self.interval); }, self.options.interval);
this.scope.$on('rzSliderForceRender', function() this.scope.$on('rzSliderForceRender', function() {
{
self.resetLabelsValue(); self.resetLabelsValue();
thrLow(); thrLow();
if(self.range) { thrHigh(); } if (self.range) {
thrHigh();
}
self.resetSlider(); self.resetSlider();
}); });
// Watchers // Watchers
this.scope.$watch('rzSliderModel', function(newValue, oldValue) {
unRegFn = this.scope.$watch('rzSliderModel', function(newValue, oldValue) if (newValue === oldValue)
{ return;
if(newValue === oldValue) { return; }
thrLow(); thrLow();
}); });
this.deRegFuncs.push(unRegFn);
unRegFn = this.scope.$watch('rzSliderHigh', function(newValue, oldValue) this.scope.$watch('rzSliderHigh', function(newValue, oldValue) {
{ if (newValue === oldValue)
if(newValue === oldValue) { return; } return;
if (newValue != null)
thrHigh(); thrHigh();
}); if (self.range && newValue == null || !self.range && newValue != null) {
this.deRegFuncs.push(unRegFn); self.applyOptions();
this.scope.$watch('rzSliderFloor', function(newValue, oldValue)
{
if(newValue === oldValue) { return; }
self.resetSlider(); self.resetSlider();
}
}); });
this.deRegFuncs.push(unRegFn);
unRegFn = this.scope.$watch('rzSliderCeil', function(newValue, oldValue) this.scope.$watch('rzSliderOptions', function(newValue, oldValue) {
{ if (newValue === oldValue)
if(newValue === oldValue) { return; } return;
self.applyOptions();
self.resetSlider(); self.resetSlider();
}); }, true);
this.deRegFuncs.push(unRegFn);
unRegFn = this.scope.$watch('rzSliderShowTicks', function(newValue, oldValue) this.scope.$on('$destroy', function() {
{ self.unbindEvents();
if(newValue === oldValue) { return; } angular.element($window).off('resize', calcDimFn);
self.resetSlider();
}); });
this.deRegFuncs.push(unRegFn); },
unRegFn = this.scope.$watch('rzSliderShowTicksValue', function(newValue, oldValue) /**
{ * Read the user options and apply them to the slider model
if(newValue === oldValue) { return; } */
self.resetSlider(); applyOptions: function() {
}); this.options = RzSliderOptions.getOptions(this.scope.rzSliderOptions);
this.deRegFuncs.push(unRegFn);
unRegFn = this.scope.$watch('rzSliderDisabled', function(newValue, oldValue) if (this.options.step <= 0)
{ this.options.step = 1;
if(newValue === oldValue) { return; } this.range = this.scope.rzSliderModel !== undefined && this.scope.rzSliderHigh !== undefined;
self.resetSlider(); this.options.draggableRange = this.range && this.options.draggableRange;
if(self.disabled) this.options.showTicks = this.options.showTicks || this.options.showTicksValues;
self.unbindEvents();
else
self.bindEvents();
});
this.deRegFuncs.push(unRegFn);
this.scope.$on('$destroy', function() if (this.options.stepsArray) {
{ this.options.floor = 0;
self.unbindEvents(); this.options.ceil = this.options.stepsArray.length - 1;
angular.element($window).off('resize', calcDimFn); this.options.step = 1;
self.deRegFuncs.map(function(unbind) { unbind(); }); 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);
};
}, },
/** /**
...@@ -425,30 +381,132 @@ function throttle(func, wait, options) { ...@@ -425,30 +381,132 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
resetSlider: function() resetSlider: function() {
{ this.manageElementsStyle();
this.setMinAndMax(); this.setMinAndMax();
this.updateCeilLab(); this.updateCeilLab();
this.updateFloorLab(); this.updateFloorLab();
this.unbindEvents();
this.manageEventsBindings();
this.setDisabledState(); this.setDisabledState();
this.calcViewDimensions(); 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);
// Initialize offset cache properties
this.selBar.rzsl = 0;
this.minH.rzsl = 0;
this.maxH.rzsl = 0;
this.flrLab.rzsl = 0;
this.ceilLab.rzsl = 0;
this.minLab.rzsl = 0;
this.maxLab.rzsl = 0;
this.cmbLab.rzsl = 0;
},
/** Update each elements style based on options
*
*/
manageElementsStyle: function() {
if (!this.range)
this.maxH.css('display', 'none');
else
this.maxH.css('display', null);
this.alwaysHide(this.flrLab, this.options.showTicksValues || this.options.hideLimitLabels);
this.alwaysHide(this.ceilLab, this.options.showTicksValues || this.options.hideLimitLabels);
this.alwaysHide(this.minLab, this.options.showTicksValues);
this.alwaysHide(this.maxLab, this.options.showTicksValues || !this.range);
this.alwaysHide(this.cmbLab, this.options.showTicksValues || !this.range);
this.alwaysHide(this.selBar, !this.range && !this.options.showSelectionBar);
if (!this.options.showTicks)
this.ticks.html('');
if (this.options.draggableRange)
this.selBar.addClass('rz-draggable');
else
this.selBar.removeClass('rz-draggable');
},
alwaysHide: function(el, hide) {
el.rzAlwaysHide = hide;
if (hide)
this.hideEl(el);
else
this.showEl(el)
},
/**
* Manage the events bindings based on readOnly and disabled options
*
* @returns {undefined}
*/
manageEventsBindings: function() {
if (this.options.disabled || this.options.readOnly)
this.unbindEvents();
else if (!this.options.disabled || !this.options.readOnly)
this.bindEvents();
},
/** /**
* Set the disabled state based on rzSliderDisabled * Set the disabled state based on rzSliderDisabled
* *
* @returns {undefined} * @returns {undefined}
*/ */
setDisabledState: function() setDisabledState: function() {
{ if (this.options.disabled) {
this.disabled = this.scope.rzSliderDisabled;
if(this.disabled) {
this.sliderElem.attr('disabled', 'disabled'); this.sliderElem.attr('disabled', 'disabled');
} } else {
else {
this.sliderElem.attr('disabled', null); this.sliderElem.attr('disabled', null);
} }
}, },
/** /**
...@@ -456,8 +514,7 @@ function throttle(func, wait, options) { ...@@ -456,8 +514,7 @@ function throttle(func, wait, options) {
* *
* @return {undefined} * @return {undefined}
*/ */
resetLabelsValue: function() resetLabelsValue: function() {
{
this.minLab.rzsv = undefined; this.minLab.rzsv = undefined;
this.maxLab.rzsv = undefined; this.maxLab.rzsv = undefined;
}, },
...@@ -469,18 +526,17 @@ function throttle(func, wait, options) { ...@@ -469,18 +526,17 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
initHandles: function() initHandles: function() {
{
this.updateLowHandle(this.valueToOffset(this.scope.rzSliderModel)); this.updateLowHandle(this.valueToOffset(this.scope.rzSliderModel));
/* /*
the order here is important since the selection bar should be the order here is important since the selection bar should be
updated after the high handle but before the combined label updated after the high handle but before the combined label
*/ */
if(this.range) if (this.range)
this.updateHighHandle(this.valueToOffset(this.scope.rzSliderHigh)); this.updateHighHandle(this.valueToOffset(this.scope.rzSliderHigh));
this.updateSelectionBar(); this.updateSelectionBar();
if(this.range) if (this.range)
this.updateCmbLabel(); this.updateCmbLabel();
this.updateTicksScale(); this.updateTicksScale();
...@@ -494,15 +550,13 @@ function throttle(func, wait, options) { ...@@ -494,15 +550,13 @@ function throttle(func, wait, options) {
* @param {boolean} [useCustomTr] * @param {boolean} [useCustomTr]
* @returns {undefined} * @returns {undefined}
*/ */
translateFn: function(value, label, useCustomTr) translateFn: function(value, label, useCustomTr) {
{
useCustomTr = useCustomTr === undefined ? true : useCustomTr; useCustomTr = useCustomTr === undefined ? true : useCustomTr;
var valStr = (useCustomTr ? this.customTrFn(value) : value).toString(), 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;
} }
...@@ -510,129 +564,33 @@ function throttle(func, wait, options) { ...@@ -510,129 +564,33 @@ function throttle(func, wait, options) {
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) { this.getWidth(label); } if (getWidth) {
}, this.getWidth(label);
/**
* Set maximum and minimum values for the slider
*
* @returns {undefined}
*/
setMinAndMax: function()
{
if(this.scope.rzSliderFloor)
{
this.minValue = +this.scope.rzSliderFloor;
}
else
{
this.minValue = this.scope.rzSliderFloor = 0;
}
if(this.scope.rzSliderCeil)
{
this.maxValue = +this.scope.rzSliderCeil;
} }
else
{
this.maxValue = this.scope.rzSliderCeil = this.range ? this.scope.rzSliderHigh : this.scope.rzSliderModel;
}
if(this.scope.rzSliderStep)
{
this.step = +this.scope.rzSliderStep;
}
this.valueRange = this.maxValue - this.minValue;
}, },
/** /**
* Set the slider children to variables for easy access * Set maximum and minimum values for the slider and ensure the model and high
* * value match these limits
* Run only once during initialization
*
* @returns {undefined} * @returns {undefined}
*/ */
initElemHandles: function() setMinAndMax: 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);
// Initialize offset cache properties
this.selBar.rzsl = 0;
this.minH.rzsl = 0;
this.maxH.rzsl = 0;
this.flrLab.rzsl = 0;
this.ceilLab.rzsl = 0;
this.minLab.rzsl = 0;
this.maxLab.rzsl = 0;
this.cmbLab.rzsl = 0;
// Hide limit labels
if(this.hideLimitLabels)
{
this.flrLab.rzAlwaysHide = true;
this.ceilLab.rzAlwaysHide = true;
this.hideEl(this.flrLab);
this.hideEl(this.ceilLab);
}
if(this.showTicksValue) { this.step = +this.options.step;
this.flrLab.rzAlwaysHide = true; this.precision = +this.options.precision;
this.ceilLab.rzAlwaysHide = true;
this.minLab.rzAlwaysHide = true;
this.maxLab.rzAlwaysHide = true;
this.cmbLab.rzAlwaysHide = true;
this.hideEl(this.flrLab);
this.hideEl(this.ceilLab);
this.hideEl(this.minLab);
this.hideEl(this.maxLab);
this.hideEl(this.cmbLab);
}
// Remove stuff not needed in single slider this.scope.rzSliderModel = this.roundStep(this.scope.rzSliderModel);
if(this.range === false) if (this.range)
{ this.scope.rzSliderHigh = this.roundStep(this.scope.rzSliderHigh);
this.cmbLab.remove();
this.maxLab.remove();
// Hide max handle this.minValue = this.roundStep(+this.options.floor);
this.maxH.rzAlwaysHide = true;
this.maxH[0].style.zIndex = '-1000';
this.hideEl(this.maxH);
}
// Show selection bar for single slider or not if (this.options.ceil != null)
if(this.range === false && this.alwaysShowBar === false) this.maxValue = this.roundStep(+this.options.ceil);
{ else
this.maxH.remove(); this.maxValue = this.options.ceil = this.range ? this.scope.rzSliderHigh : this.scope.rzSliderModel;
this.selBar.remove();
}
// If using draggable range, use appropriate cursor for this.selBar. this.valueRange = this.maxValue - this.minValue;
if (this.dragRange)
{
this.selBar.css('cursor', 'move');
this.selBar.addClass('rz-draggable');
}
}, },
/** /**
...@@ -642,8 +600,7 @@ function throttle(func, wait, options) { ...@@ -642,8 +600,7 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
addAccessibility: function () addAccessibility: function() {
{
this.sliderElem.attr("role", "slider"); this.sliderElem.attr("role", "slider");
}, },
...@@ -654,8 +611,7 @@ function throttle(func, wait, options) { ...@@ -654,8 +611,7 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
calcViewDimensions: function () calcViewDimensions: function() {
{
var handleWidth = this.getWidth(this.minH); var handleWidth = this.getWidth(this.minH);
this.handleHalfWidth = handleWidth / 2; this.handleHalfWidth = handleWidth / 2;
...@@ -666,8 +622,7 @@ function throttle(func, wait, options) { ...@@ -666,8 +622,7 @@ function throttle(func, wait, options) {
this.getWidth(this.sliderElem); this.getWidth(this.sliderElem);
this.sliderElem.rzsl = this.sliderElem[0].getBoundingClientRect().left; this.sliderElem.rzsl = this.sliderElem[0].getBoundingClientRect().left;
if(this.initHasRun) if (this.initHasRun) {
{
this.updateFloorLab(); this.updateFloorLab();
this.updateCeilLab(); this.updateCeilLab();
this.initHandles(); this.initHandles();
...@@ -680,27 +635,33 @@ function throttle(func, wait, options) { ...@@ -680,27 +635,33 @@ function throttle(func, wait, options) {
* @returns {undefined} * @returns {undefined}
*/ */
updateTicksScale: function() { updateTicksScale: function() {
if(!this.showTicks) return; if (!this.options.showTicks) return;
if(!this.step) return; //if step is 0, the following loop will be endless. if (!this.step) return; //if step is 0, the following loop will be endless.
var positions = '', var positions = '',
ticksCount = Math.round((this.maxValue - this.minValue) / this.step) + 1; ticksCount = Math.round((this.maxValue - this.minValue) / this.step) + 1;
for (var i = 0; i < ticksCount; i++) { for (var i = 0; i < ticksCount; i++) {
var value = this.roundStep(this.minValue + i * this.step); var value = this.roundStep(this.minValue + i * this.step);
var selectedClass = this.isTickSelected(value) ? 'selected': ''; var selectedClass = this.isTickSelected(value) ? 'selected' : '';
positions += '<li class="tick '+ selectedClass +'">'; positions += '<li class="tick ' + selectedClass + '">';
if(this.showTicksValue) if (this.options.showTicksValues) {
positions += '<span class="tick-value">'+ this.getDisplayValue(value) +'</span>'; var tooltip = '';
if (this.options.ticksValuesTooltip) {
tooltip = 'uib-tooltip="' + this.options.ticksValuesTooltip(value) + '"';
}
positions += '<span ' + tooltip + ' class="tick-value">' + this.getDisplayValue(value) + '</span>';
}
positions += '</li>'; positions += '</li>';
} }
this.ticks.html(positions); this.ticks.html(positions);
if (this.options.ticksValuesTooltip)
$compile(this.ticks.contents())(this.scope);
}, },
isTickSelected: function(value) { isTickSelected: function(value) {
var tickLeft = this.valueToOffset(value); if (!this.range && this.options.showSelectionBar && value <= this.scope.rzSliderModel)
if(!this.range && this.alwaysShowBar && value <= this.scope.rzSliderModel)
return true; return true;
if(this.range && value >= this.scope.rzSliderModel && value <= this.scope.rzSliderHigh) if (this.range && value >= this.scope.rzSliderModel && value <= this.scope.rzSliderHigh)
return true; return true;
return false; return false;
}, },
...@@ -710,9 +671,8 @@ function throttle(func, wait, options) { ...@@ -710,9 +671,8 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
updateCeilLab: function() updateCeilLab: function() {
{ this.translateFn(this.maxValue, this.ceilLab);
this.translateFn(this.scope.rzSliderCeil, this.ceilLab);
this.setLeft(this.ceilLab, this.barWidth - this.ceilLab.rzsw); this.setLeft(this.ceilLab, this.barWidth - this.ceilLab.rzsw);
this.getWidth(this.ceilLab); this.getWidth(this.ceilLab);
}, },
...@@ -722,9 +682,8 @@ function throttle(func, wait, options) { ...@@ -722,9 +682,8 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
updateFloorLab: function() updateFloorLab: function() {
{ this.translateFn(this.minValue, this.flrLab);
this.translateFn(this.scope.rzSliderFloor, this.flrLab);
this.getWidth(this.flrLab); this.getWidth(this.flrLab);
}, },
...@@ -734,10 +693,10 @@ function throttle(func, wait, options) { ...@@ -734,10 +693,10 @@ function throttle(func, wait, options) {
* @returns {undefined} * @returns {undefined}
*/ */
callOnStart: function() { callOnStart: function() {
if(this.scope.rzSliderOnStart) { if (this.options.onStart) {
var self = this; var self = this;
$timeout(function() { $timeout(function() {
self.scope.rzSliderOnStart(); self.options.onStart();
}); });
} }
}, },
...@@ -748,10 +707,10 @@ function throttle(func, wait, options) { ...@@ -748,10 +707,10 @@ function throttle(func, wait, options) {
* @returns {undefined} * @returns {undefined}
*/ */
callOnChange: function() { callOnChange: function() {
if(this.scope.rzSliderOnChange) { if (this.options.onChange) {
var self = this; var self = this;
$timeout(function() { $timeout(function() {
self.scope.rzSliderOnChange(); self.options.onChange();
}); });
} }
}, },
...@@ -762,10 +721,10 @@ function throttle(func, wait, options) { ...@@ -762,10 +721,10 @@ function throttle(func, wait, options) {
* @returns {undefined} * @returns {undefined}
*/ */
callOnEnd: function() { callOnEnd: function() {
if(this.scope.rzSliderOnEnd) { if (this.options.onEnd) {
var self = this; var self = this;
$timeout(function() { $timeout(function() {
self.scope.rzSliderOnEnd(); self.options.onEnd();
}); });
} }
}, },
...@@ -776,29 +735,24 @@ function throttle(func, wait, options) { ...@@ -776,29 +735,24 @@ function throttle(func, wait, options) {
* @param {string} which * @param {string} which
* @param {number} newOffset * @param {number} newOffset
*/ */
updateHandles: function(which, newOffset) updateHandles: function(which, newOffset) {
{ if (which === 'rzSliderModel') {
if(which === 'rzSliderModel')
{
this.updateLowHandle(newOffset); this.updateLowHandle(newOffset);
this.updateSelectionBar(); this.updateSelectionBar();
this.updateTicksScale(); this.updateTicksScale();
if(this.range) if (this.range) {
{
this.updateCmbLabel(); this.updateCmbLabel();
} }
return; return;
} }
if(which === 'rzSliderHigh') if (which === 'rzSliderHigh') {
{
this.updateHighHandle(newOffset); this.updateHighHandle(newOffset);
this.updateSelectionBar(); this.updateSelectionBar();
this.updateTicksScale(); this.updateTicksScale();
if(this.range) if (this.range) {
{
this.updateCmbLabel(); this.updateCmbLabel();
} }
return; return;
...@@ -818,8 +772,7 @@ function throttle(func, wait, options) { ...@@ -818,8 +772,7 @@ function throttle(func, wait, options) {
* @param {number} newOffset * @param {number} newOffset
* @returns {undefined} * @returns {undefined}
*/ */
updateLowHandle: function(newOffset) updateLowHandle: function(newOffset) {
{
this.setLeft(this.minH, newOffset); this.setLeft(this.minH, newOffset);
this.translateFn(this.scope.rzSliderModel, this.minLab); this.translateFn(this.scope.rzSliderModel, this.minLab);
this.setLeft(this.minLab, newOffset - this.minLab.rzsw / 2 + this.handleHalfWidth); this.setLeft(this.minLab, newOffset - this.minLab.rzsw / 2 + this.handleHalfWidth);
...@@ -833,8 +786,7 @@ function throttle(func, wait, options) { ...@@ -833,8 +786,7 @@ function throttle(func, wait, options) {
* @param {number} newOffset * @param {number} newOffset
* @returns {undefined} * @returns {undefined}
*/ */
updateHighHandle: function(newOffset) updateHighHandle: function(newOffset) {
{
this.setLeft(this.maxH, newOffset); this.setLeft(this.maxH, newOffset);
this.translateFn(this.scope.rzSliderHigh, this.maxLab); this.translateFn(this.scope.rzSliderHigh, this.maxLab);
this.setLeft(this.maxLab, newOffset - this.maxLab.rzsw / 2 + this.handleHalfWidth); this.setLeft(this.maxLab, newOffset - this.maxLab.rzsw / 2 + this.handleHalfWidth);
...@@ -847,50 +799,37 @@ function throttle(func, wait, options) { ...@@ -847,50 +799,37 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
shFloorCeil: function() shFloorCeil: function() {
{ var flHidden = false,
var flHidden = false, clHidden = false; clHidden = false;
if(this.minLab.rzsl <= this.flrLab.rzsl + this.flrLab.rzsw + 5) if (this.minLab.rzsl <= this.flrLab.rzsl + this.flrLab.rzsw + 5) {
{
flHidden = true; flHidden = true;
this.hideEl(this.flrLab); this.hideEl(this.flrLab);
} } else {
else
{
flHidden = false; flHidden = false;
this.showEl(this.flrLab); 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); this.hideEl(this.ceilLab);
} } else {
else
{
clHidden = false; clHidden = false;
this.showEl(this.ceilLab); this.showEl(this.ceilLab);
} }
if(this.range) if (this.range) {
{ if (this.maxLab.rzsl + this.maxLab.rzsw >= this.ceilLab.rzsl - 10) {
if(this.maxLab.rzsl + this.maxLab.rzsw >= this.ceilLab.rzsl - 10)
{
this.hideEl(this.ceilLab); this.hideEl(this.ceilLab);
} } else if (!clHidden) {
else if( ! clHidden)
{
this.showEl(this.ceilLab); this.showEl(this.ceilLab);
} }
// Hide or show floor label // Hide or show floor label
if(this.maxLab.rzsl <= this.flrLab.rzsl + this.flrLab.rzsw + this.handleHalfWidth) if (this.maxLab.rzsl <= this.flrLab.rzsl + this.flrLab.rzsw + this.handleHalfWidth) {
{
this.hideEl(this.flrLab); this.hideEl(this.flrLab);
} } else if (!flHidden) {
else if( ! flHidden)
{
this.showEl(this.flrLab); this.showEl(this.flrLab);
} }
} }
...@@ -901,8 +840,7 @@ function throttle(func, wait, options) { ...@@ -901,8 +840,7 @@ function throttle(func, wait, options) {
* *
* @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);
}, },
...@@ -912,12 +850,10 @@ function throttle(func, wait, options) { ...@@ -912,12 +850,10 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
updateCmbLabel: function() updateCmbLabel: function() {
{
var lowTr, highTr; var lowTr, highTr;
if(this.minLab.rzsl + this.minLab.rzsw + 10 >= this.maxLab.rzsl) if (this.minLab.rzsl + this.minLab.rzsw + 10 >= this.maxLab.rzsl) {
{
lowTr = this.getDisplayValue(this.scope.rzSliderModel); lowTr = this.getDisplayValue(this.scope.rzSliderModel);
highTr = this.getDisplayValue(this.scope.rzSliderHigh); highTr = this.getDisplayValue(this.scope.rzSliderHigh);
...@@ -926,9 +862,7 @@ function throttle(func, wait, options) { ...@@ -926,9 +862,7 @@ function throttle(func, wait, options) {
this.hideEl(this.minLab); this.hideEl(this.minLab);
this.hideEl(this.maxLab); this.hideEl(this.maxLab);
this.showEl(this.cmbLab); this.showEl(this.cmbLab);
} } else {
else
{
this.showEl(this.maxLab); this.showEl(this.maxLab);
this.showEl(this.minLab); this.showEl(this.minLab);
this.hideEl(this.cmbLab); this.hideEl(this.cmbLab);
...@@ -941,7 +875,7 @@ function throttle(func, wait, options) { ...@@ -941,7 +875,7 @@ function throttle(func, wait, options) {
* @returns {*} * @returns {*}
*/ */
getDisplayValue: function(value) { getDisplayValue: function(value) {
return this.customTrFn ? this.customTrFn(value): value; return this.customTrFn(value, this.options.id);
}, },
/** /**
...@@ -950,8 +884,7 @@ function throttle(func, wait, options) { ...@@ -950,8 +884,7 @@ function throttle(func, wait, options) {
* @param {number} value * @param {number} value
* @returns {number} * @returns {number}
*/ */
roundStep: function(value) roundStep: function(value) {
{
var step = this.step, var step = this.step,
remainder = +((value - this.minValue) % step).toFixed(3), remainder = +((value - this.minValue) % step).toFixed(3),
steppedValue = remainder > (step / 2) ? value + step - remainder : value - remainder; steppedValue = remainder > (step / 2) ? value + step - remainder : value - remainder;
...@@ -966,9 +899,10 @@ function throttle(func, wait, options) { ...@@ -966,9 +899,10 @@ function throttle(func, wait, options) {
* @param element * @param element
* @returns {jqLite} The jqLite wrapped DOM element * @returns {jqLite} The jqLite wrapped DOM element
*/ */
hideEl: function (element) hideEl: function(element) {
{ return element.css({
return element.css({opacity: 0}); opacity: 0
});
}, },
/** /**
...@@ -977,11 +911,14 @@ function throttle(func, wait, options) { ...@@ -977,11 +911,14 @@ function throttle(func, wait, options) {
* @param element The jqLite wrapped DOM element * @param element The jqLite wrapped DOM element
* @returns {jqLite} The jqLite * @returns {jqLite} The jqLite
*/ */
showEl: function (element) showEl: function(element) {
{ if (!!element.rzAlwaysHide) {
if(!!element.rzAlwaysHide) { return element; } return element;
}
return element.css({opacity: 1}); return element.css({
opacity: 1
});
}, },
/** /**
...@@ -991,10 +928,11 @@ function throttle(func, wait, options) { ...@@ -991,10 +928,11 @@ function throttle(func, wait, options) {
* @param {number} left * @param {number} left
* @returns {number} * @returns {number}
*/ */
setLeft: function (elem, left) setLeft: function(elem, left) {
{
elem.rzsl = left; elem.rzsl = left;
elem.css({left: left + 'px'}); elem.css({
left: left + 'px'
});
return left; return left;
}, },
...@@ -1004,10 +942,9 @@ function throttle(func, wait, options) { ...@@ -1004,10 +942,9 @@ function throttle(func, wait, options) {
* @param {jqLite} elem The jqLite wrapped DOM element * @param {jqLite} elem The jqLite wrapped DOM element
* @returns {number} * @returns {number}
*/ */
getWidth: function(elem) getWidth: function(elem) {
{
var val = elem[0].getBoundingClientRect(); var val = elem[0].getBoundingClientRect();
elem.rzsw = val.right - val.left; elem.rzsw = (val.right - val.left) * this.options.scale;
return elem.rzsw; return elem.rzsw;
}, },
...@@ -1018,10 +955,11 @@ function throttle(func, wait, options) { ...@@ -1018,10 +955,11 @@ function throttle(func, wait, options) {
* @param {number} width * @param {number} width
* @returns {number} * @returns {number}
*/ */
setWidth: function(elem, width) setWidth: function(elem, width) {
{
elem.rzsw = width; elem.rzsw = width;
elem.css({width: width + 'px'}); elem.css({
width: width + 'px'
});
return width; return width;
}, },
...@@ -1031,9 +969,18 @@ function throttle(func, wait, options) { ...@@ -1031,9 +969,18 @@ function throttle(func, wait, options) {
* @param {number} val * @param {number} val
* @returns {number} * @returns {number}
*/ */
valueToOffset: function(val) valueToOffset: function(val) {
{ return (this.sanitizeOffsetValue(val) - this.minValue) * this.maxLeft / this.valueRange || 0;
return (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);
}, },
/** /**
...@@ -1042,8 +989,7 @@ function throttle(func, wait, options) { ...@@ -1042,8 +989,7 @@ function throttle(func, wait, options) {
* @param {number} offset * @param {number} offset
* @returns {number} * @returns {number}
*/ */
offsetToValue: function(offset) offsetToValue: function(offset) {
{
return (offset / this.maxLeft) * this.valueRange + this.minValue; return (offset / this.maxLeft) * this.valueRange + this.minValue;
}, },
...@@ -1055,18 +1001,15 @@ function throttle(func, wait, options) { ...@@ -1055,18 +1001,15 @@ function throttle(func, wait, options) {
* @param {Object} event The event * @param {Object} event The event
* @returns {number} * @returns {number}
*/ */
getEventX: function(event) getEventX: function(event) {
{
/* http://stackoverflow.com/a/12336075/282882 */ /* http://stackoverflow.com/a/12336075/282882 */
//noinspection JSLint //noinspection JSLint
if('clientX' in event) if ('clientX' in event) {
{
return event.clientX; return event.clientX;
} }
return event.originalEvent === undefined ? return event.originalEvent === undefined ?
event.touches[0].clientX event.touches[0].clientX : event.originalEvent.touches[0].clientX;
: event.originalEvent.touches[0].clientX;
}, },
/** /**
...@@ -1075,10 +1018,11 @@ function throttle(func, wait, options) { ...@@ -1075,10 +1018,11 @@ function throttle(func, wait, options) {
* @param event {Event} The event * @param event {Event} The event
* @returns {jqLite} The handle closest to the event. * @returns {jqLite} The handle closest to the event.
*/ */
getNearestHandle: function(event) getNearestHandle: function(event) {
{ if (!this.range) {
if (!this.range) { return this.minH; } return this.minH;
var offset = this.getEventX(event) - this.sliderElem.rzsl - this.handleHalfWidth; }
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; return Math.abs(offset - this.minH.rzsl) < Math.abs(offset - this.maxH.rzsl) ? this.minH : this.maxH;
}, },
...@@ -1087,26 +1031,24 @@ function throttle(func, wait, options) { ...@@ -1087,26 +1031,24 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
bindEvents: function() bindEvents: function() {
{ if (this.options.readOnly || this.options.disabled) return;
if(this.presentOnly || this.disabled) return;
var barTracking, barStart, barMove; var barTracking, barStart, barMove;
if (this.dragRange) if (this.options.draggableRange) {
{
barTracking = 'rzSliderDrag'; barTracking = 'rzSliderDrag';
barStart = this.onDragStart; barStart = this.onDragStart;
barMove = this.onDragMove; barMove = this.onDragMove;
} } else {
else
{
barTracking = 'rzSliderModel'; barTracking = 'rzSliderModel';
barStart = this.onStart; barStart = this.onStart;
barMove = this.onMove; barMove = this.onMove;
} }
this.minH.on('mousedown', angular.bind(this, this.onStart, this.minH, 'rzSliderModel')); this.minH.on('mousedown', angular.bind(this, this.onStart, this.minH, 'rzSliderModel'));
if(this.range) { this.maxH.on('mousedown', angular.bind(this, this.onStart, this.maxH, 'rzSliderHigh')); } if (this.range) {
this.maxH.on('mousedown', angular.bind(this, this.onStart, this.maxH, 'rzSliderHigh'));
}
this.fullBar.on('mousedown', angular.bind(this, this.onStart, null, null)); this.fullBar.on('mousedown', angular.bind(this, this.onStart, null, null));
this.fullBar.on('mousedown', angular.bind(this, this.onMove, this.fullBar)); this.fullBar.on('mousedown', angular.bind(this, this.onMove, this.fullBar));
this.selBar.on('mousedown', angular.bind(this, barStart, null, barTracking)); this.selBar.on('mousedown', angular.bind(this, barStart, null, barTracking));
...@@ -1115,7 +1057,9 @@ function throttle(func, wait, options) { ...@@ -1115,7 +1057,9 @@ function throttle(func, wait, options) {
this.ticks.on('mousedown', angular.bind(this, this.onMove, this.ticks)); this.ticks.on('mousedown', angular.bind(this, this.onMove, this.ticks));
this.minH.on('touchstart', angular.bind(this, this.onStart, this.minH, 'rzSliderModel')); this.minH.on('touchstart', angular.bind(this, this.onStart, this.minH, 'rzSliderModel'));
if(this.range) { this.maxH.on('touchstart', angular.bind(this, this.onStart, this.maxH, 'rzSliderHigh')); } if (this.range) {
this.maxH.on('touchstart', angular.bind(this, this.onStart, this.maxH, 'rzSliderHigh'));
}
this.fullBar.on('touchstart', angular.bind(this, this.onStart, null, null)); this.fullBar.on('touchstart', angular.bind(this, this.onStart, null, null));
this.fullBar.on('touchstart', angular.bind(this, this.onMove, this.fullBar)); 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, barStart, null, barTracking));
...@@ -1129,8 +1073,7 @@ function throttle(func, wait, options) { ...@@ -1129,8 +1073,7 @@ function throttle(func, wait, options) {
* *
* @returns {undefined} * @returns {undefined}
*/ */
unbindEvents: function() unbindEvents: function() {
{
this.minH.off(); this.minH.off();
this.maxH.off(); this.maxH.off();
this.fullBar.off(); this.fullBar.off();
...@@ -1146,26 +1089,24 @@ function throttle(func, wait, options) { ...@@ -1146,26 +1089,24 @@ function throttle(func, wait, options) {
* @param {Event} event The event * @param {Event} event The event
* @returns {undefined} * @returns {undefined}
*/ */
onStart: function (pointer, ref, event) onStart: function(pointer, ref, event) {
{
var ehMove, ehEnd, var ehMove, ehEnd,
eventNames = this.getEventNames(event); eventNames = this.getEventNames(event);
event.stopPropagation(); event.stopPropagation();
event.preventDefault(); event.preventDefault();
if(this.tracking !== '') { return; } if (this.tracking !== '') {
return;
}
// We have to do this in case the HTML where the sliders are on // We have to do this in case the HTML where the sliders are on
// have been animated into view. // have been animated into view.
this.calcViewDimensions(); this.calcViewDimensions();
if(pointer) if (pointer) {
{
this.tracking = ref; this.tracking = ref;
} } else {
else
{
pointer = this.getNearestHandle(event); pointer = this.getNearestHandle(event);
this.tracking = pointer === this.minH ? 'rzSliderModel' : 'rzSliderHigh'; this.tracking = pointer === this.minH ? 'rzSliderModel' : 'rzSliderHigh';
} }
...@@ -1187,29 +1128,24 @@ function throttle(func, wait, options) { ...@@ -1187,29 +1128,24 @@ function throttle(func, wait, options) {
* @param {Event} event The event * @param {Event} event The event
* @returns {undefined} * @returns {undefined}
*/ */
onMove: function (pointer, event) onMove: function(pointer, event) {
{
var eventX = this.getEventX(event), var eventX = this.getEventX(event),
sliderLO, newOffset, newValue; sliderLO, newOffset, newValue;
sliderLO = this.sliderElem.rzsl; sliderLO = this.sliderElem.rzsl;
newOffset = eventX - sliderLO - this.handleHalfWidth; newOffset = (eventX - sliderLO - this.handleHalfWidth) * this.options.scale;
if(newOffset <= 0) if (newOffset <= 0) {
{ if (pointer.rzsl === 0)
if(pointer.rzsl === 0)
return; return;
newValue = this.minValue; newValue = this.minValue;
newOffset = 0; newOffset = 0;
} } else if (newOffset >= this.maxLeft) {
else if(newOffset >= this.maxLeft) if (pointer.rzsl === this.maxLeft)
{
if(pointer.rzsl === this.maxLeft)
return; return;
newValue = this.maxValue; newValue = this.maxValue;
newOffset = this.maxLeft; newOffset = this.maxLeft;
} } else {
else {
newValue = this.offsetToValue(newOffset); newValue = this.offsetToValue(newOffset);
newValue = this.roundStep(newValue); newValue = this.roundStep(newValue);
newOffset = this.valueToOffset(newValue); newOffset = this.valueToOffset(newValue);
...@@ -1227,8 +1163,7 @@ function throttle(func, wait, options) { ...@@ -1227,8 +1163,7 @@ function throttle(func, wait, options) {
* @param {Event} event The event * @param {Event} event The event
* @returns {undefined} * @returns {undefined}
*/ */
onDragStart: function(pointer, ref, event) onDragStart: function(pointer, ref, event) {
{
var offset = this.getEventX(event) - this.sliderElem.rzsl - this.handleHalfWidth; var offset = this.getEventX(event) - this.sliderElem.rzsl - this.handleHalfWidth;
this.dragging = { this.dragging = {
active: true, active: true,
...@@ -1253,30 +1188,28 @@ function throttle(func, wait, options) { ...@@ -1253,30 +1188,28 @@ function throttle(func, wait, options) {
* @param {Event} event The event * @param {Event} event The event
* @returns {undefined} * @returns {undefined}
*/ */
onDragMove: function(pointer, event) onDragMove: function(pointer, event) {
{
var newOffset = this.getEventX(event) - this.sliderElem.rzsl - this.handleHalfWidth, var newOffset = this.getEventX(event) - this.sliderElem.rzsl - this.handleHalfWidth,
newMinOffset, newMaxOffset, newMinOffset, newMaxOffset,
newMinValue, newMaxValue; newMinValue, newMaxValue;
if (newOffset <= this.dragging.lowDist) if (newOffset <= this.dragging.lowDist) {
{ if (pointer.rzsl === this.dragging.lowDist) {
if (pointer.rzsl === this.dragging.lowDist) { return; } return;
}
newMinValue = this.minValue; newMinValue = this.minValue;
newMinOffset = 0; newMinOffset = 0;
newMaxValue = this.dragging.difference; newMaxValue = this.minValue + this.dragging.difference;
newMaxOffset = this.valueToOffset(newMaxValue); newMaxOffset = this.valueToOffset(newMaxValue);
} else if (newOffset >= this.maxLeft - this.dragging.highDist) {
if (pointer.rzsl === this.dragging.highDist) {
return;
} }
else if (newOffset >= this.maxLeft - this.dragging.highDist)
{
if (pointer.rzsl === this.dragging.highDist) { return; }
newMaxValue = this.maxValue; newMaxValue = this.maxValue;
newMaxOffset = this.maxLeft; newMaxOffset = this.maxLeft;
newMinValue = this.maxValue - this.dragging.difference; newMinValue = this.maxValue - this.dragging.difference;
newMinOffset = this.valueToOffset(newMinValue); newMinOffset = this.valueToOffset(newMinValue);
} } else {
else
{
newMinValue = this.offsetToValue(newOffset - this.dragging.lowDist); newMinValue = this.offsetToValue(newOffset - this.dragging.lowDist);
newMinValue = this.roundStep(newMinValue); newMinValue = this.roundStep(newMinValue);
newMinOffset = this.valueToOffset(newMinValue); newMinOffset = this.valueToOffset(newMinValue);
...@@ -1295,8 +1228,7 @@ function throttle(func, wait, options) { ...@@ -1295,8 +1228,7 @@ function throttle(func, wait, options) {
* @param {number} newMinOffset the new minimum offset * @param {number} newMinOffset the new minimum offset
* @param {number} newMaxOffset the new maximum offset * @param {number} newMaxOffset the new maximum offset
*/ */
positionTrackingBar: function(newMinValue, newMaxValue, newMinOffset, newMaxOffset) positionTrackingBar: function(newMinValue, newMaxValue, newMinOffset, newMaxOffset) {
{
this.scope.rzSliderModel = newMinValue; this.scope.rzSliderModel = newMinValue;
this.scope.rzSliderHigh = newMaxValue; this.scope.rzSliderHigh = newMaxValue;
this.updateHandles('rzSliderModel', newMinOffset); this.updateHandles('rzSliderModel', newMinOffset);
...@@ -1311,13 +1243,10 @@ function throttle(func, wait, options) { ...@@ -1311,13 +1243,10 @@ function throttle(func, wait, options) {
* @param {number} newValue new model value * @param {number} newValue new model value
* @param {number} newOffset new offset value * @param {number} newOffset new offset value
*/ */
positionTrackingHandle: function(newValue, newOffset) positionTrackingHandle: function(newValue, newOffset) {
{ if (this.range) {
if(this.range)
{
/* This is to check if we need to switch the min and max handles*/ /* This is to check if we need to switch the min and max handles*/
if (this.tracking === 'rzSliderModel' && newValue >= this.scope.rzSliderHigh) if (this.tracking === 'rzSliderModel' && newValue >= this.scope.rzSliderHigh) {
{
this.scope[this.tracking] = this.scope.rzSliderHigh; this.scope[this.tracking] = this.scope.rzSliderHigh;
this.updateHandles(this.tracking, this.maxH.rzsl); this.updateHandles(this.tracking, this.maxH.rzsl);
this.tracking = 'rzSliderHigh'; this.tracking = 'rzSliderHigh';
...@@ -1326,9 +1255,7 @@ function throttle(func, wait, options) { ...@@ -1326,9 +1255,7 @@ function throttle(func, wait, options) {
/* We need to apply here because we are not sure that we will enter the next block */ /* 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();
} } else if (this.tracking === 'rzSliderHigh' && newValue <= this.scope.rzSliderModel) {
else if(this.tracking === 'rzSliderHigh' && newValue <= this.scope.rzSliderModel)
{
this.scope[this.tracking] = this.scope.rzSliderModel; this.scope[this.tracking] = this.scope.rzSliderModel;
this.updateHandles(this.tracking, this.minH.rzsl); this.updateHandles(this.tracking, this.minH.rzsl);
this.tracking = 'rzSliderModel'; this.tracking = 'rzSliderModel';
...@@ -1340,8 +1267,7 @@ function throttle(func, wait, options) { ...@@ -1340,8 +1267,7 @@ function throttle(func, wait, options) {
} }
} }
if(this.scope[this.tracking] !== newValue) if (this.scope[this.tracking] !== newValue) {
{
this.scope[this.tracking] = newValue; this.scope[this.tracking] = newValue;
this.updateHandles(this.tracking, newOffset); this.updateHandles(this.tracking, newOffset);
this.scope.$apply(); this.scope.$apply();
...@@ -1356,8 +1282,7 @@ function throttle(func, wait, options) { ...@@ -1356,8 +1282,7 @@ function throttle(func, wait, options) {
* @param {Function} ehMove The the bound move event handler * @param {Function} ehMove The the bound move event handler
* @returns {undefined} * @returns {undefined}
*/ */
onEnd: function(ehMove, event) onEnd: function(ehMove, event) {
{
var moveEventName = this.getEventNames(event).moveEvent; var moveEventName = this.getEventNames(event).moveEvent;
this.minH.removeClass('rz-active'); this.minH.removeClass('rz-active');
...@@ -1379,17 +1304,16 @@ function throttle(func, wait, options) { ...@@ -1379,17 +1304,16 @@ function throttle(func, wait, options) {
* *
* @return {{moveEvent: string, endEvent: string}} * @return {{moveEvent: string, endEvent: string}}
*/ */
getEventNames: function(event) getEventNames: function(event) {
{ var eventNames = {
var eventNames = {moveEvent: '', endEvent: ''}; moveEvent: '',
endEvent: ''
};
if(event.touches || (event.originalEvent !== undefined && event.originalEvent.touches)) if (event.touches || (event.originalEvent !== undefined && event.originalEvent.touches)) {
{
eventNames.moveEvent = 'touchmove'; eventNames.moveEvent = 'touchmove';
eventNames.endEvent = 'touchend'; eventNames.endEvent = 'touchend';
} } else {
else
{
eventNames.moveEvent = 'mousemove'; eventNames.moveEvent = 'mousemove';
eventNames.endEvent = 'mouseup'; eventNames.endEvent = 'mouseup';
} }
...@@ -1399,33 +1323,18 @@ function throttle(func, wait, options) { ...@@ -1399,33 +1323,18 @@ function throttle(func, wait, options) {
}; };
return Slider; return Slider;
}) })
.directive('rzslider', function(RzSlider) .directive('rzslider', function(RzSlider) {
{
'use strict'; 'use strict';
return { return {
restrict: 'E', restrict: 'E',
scope: { scope: {
rzSliderFloor: '=?',
rzSliderCeil: '=?',
rzSliderStep: '@',
rzSliderPrecision: '@',
rzSliderModel: '=?', rzSliderModel: '=?',
rzSliderHigh: '=?', rzSliderHigh: '=?',
rzSliderDraggable: '@', rzSliderOptions: '=?',
rzSliderTranslate: '&', rzSliderTplUrl: '@'
rzSliderHideLimitLabels: '=?',
rzSliderAlwaysShowBar: '=?',
rzSliderPresentOnly: '@',
rzSliderOnStart: '&',
rzSliderOnChange: '&',
rzSliderOnEnd: '&',
rzSliderShowTicks: '=?',
rzSliderShowTicksValue: '=?',
rzSliderDisabled: '=?',
rzSliderInterval: '=?',
}, },
/** /**
...@@ -1440,24 +1349,23 @@ function throttle(func, wait, options) { ...@@ -1440,24 +1349,23 @@ function throttle(func, wait, options) {
return attrs.rzSliderTplUrl || 'rzSliderTpl.html'; return attrs.rzSliderTplUrl || 'rzSliderTpl.html';
}, },
link: function(scope, elem, attr) link: function(scope, elem) {
{ return new RzSlider(scope, elem);
return new RzSlider(scope, elem, attr);
} }
}; };
}); });
// IDE assist // IDE assist
/** /**
* @name ngScope * @name ngScope
* *
* @property {number} rzSliderModel * @property {number} rzSliderModel
* @property {number} rzSliderHigh * @property {number} rzSliderHigh
* @property {number} rzSliderCeil * @property {Object} rzSliderOptions
*/ */
/** /**
* @name jqLite * @name jqLite
* *
* @property {number|undefined} rzsl rzslider label left offset * @property {number|undefined} rzsl rzslider label left offset
...@@ -1467,13 +1375,13 @@ function throttle(func, wait, options) { ...@@ -1467,13 +1375,13 @@ function throttle(func, wait, options) {
* @property {Function} text * @property {Function} text
*/ */
/** /**
* @name Event * @name Event
* @property {Array} touches * @property {Array} touches
* @property {Event} originalEvent * @property {Event} originalEvent
*/ */
/** /**
* @name ThrottleOptions * @name ThrottleOptions
* *
* @property {boolean} leading * @property {boolean} leading
......
...@@ -14,7 +14,7 @@ rzslider { ...@@ -14,7 +14,7 @@ rzslider {
position: relative; position: relative;
height: @barHeight; height: @barHeight;
width: 100%; width: 100%;
margin: 30px 0 15px 0; margin: 35px 0 15px 0;
vertical-align: middle; vertical-align: middle;
-webkit-user-select: none; -webkit-user-select: none;
-moz-user-select: none; -moz-user-select: none;
...@@ -49,6 +49,9 @@ rzslider { ...@@ -49,6 +49,9 @@ rzslider {
width: 100%; width: 100%;
height: @handleSize; height: @handleSize;
z-index: 1; z-index: 1;
&.rz-draggable {
cursor: move;
}
} }
.rz-bar { .rz-bar {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment