' +
- '
' +
- '
' +
- '
' +
- '
' +
- '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '' +
+ '
' +
+ '
' +
'
' +
- '
' +
'
' +
'
',
compile: compile
@@ -74,17 +154,23 @@ function SliderDirective($$rAF, $window, $mdAria, $mdUtil, $mdConstant, $mdThemi
// **********************************************************
function compile (tElement, tAttrs) {
- if (!tAttrs.tabindex) tElement.attr('tabindex', 0);
- tElement.attr('role', 'slider');
+ var wrapper = angular.element(tElement[0].getElementsByClassName('_md-slider-wrapper'));
+
+ var tabIndex = tAttrs.tabindex || 0;
+ wrapper.attr('tabindex', tabIndex);
+
+ if (tAttrs.disabled || tAttrs.ngDisabled) wrapper.attr('tabindex', -1);
+
+ wrapper.attr('role', 'slider');
$mdAria.expect(tElement, 'aria-label');
return postLink;
}
- function postLink(scope, element, attr, ngModelCtrl) {
+ function postLink(scope, element, attr, ctrls) {
$mdTheming(element);
- ngModelCtrl = ngModelCtrl || {
+ var ngModelCtrl = ctrls[0] || {
// Mock ngModelController if it doesn't exist to give us
// the minimum functionality needed
$setViewValue: function(val) {
@@ -96,10 +182,14 @@ function SliderDirective($$rAF, $window, $mdAria, $mdUtil, $mdConstant, $mdThemi
$viewChangeListeners: []
};
- var isDisabledGetter = angular.noop;
- if (attr.disabled != null) {
- isDisabledGetter = function() { return true; };
- } else if (attr.ngDisabled) {
+ var containerCtrl = ctrls[1];
+
+ var container = angular.element($mdUtil.getClosest(element, '_md-slider-container', true));
+
+ var isDisabledGetter = function () {
+ return element[0].hasAttribute('disabled');
+ };
+ if (attr.ngDisabled) {
isDisabledGetter = angular.bind(null, $parse(attr.ngDisabled), scope.$parent);
}
@@ -109,12 +199,18 @@ function SliderDirective($$rAF, $window, $mdAria, $mdUtil, $mdConstant, $mdThemi
var trackContainer = angular.element(element[0].querySelector('._md-track-container'));
var activeTrack = angular.element(element[0].querySelector('._md-track-fill'));
var tickContainer = angular.element(element[0].querySelector('._md-track-ticks'));
+ var wrapper = angular.element(element[0].getElementsByClassName('_md-slider-wrapper'));
+ var content = angular.element(element[0].getElementsByClassName('_md-slider-content'));
var throttledRefreshDimensions = $mdUtil.throttle(refreshSliderDimensions, 5000);
// Default values, overridable by attrs
+ var DEFAULT_ROUND = 3;
+ var vertical = angular.isDefined(attr.mdVertical);
+ var discrete = angular.isDefined(attr.mdDiscrete);
angular.isDefined(attr.min) ? attr.$observe('min', updateMin) : updateMin(0);
angular.isDefined(attr.max) ? attr.$observe('max', updateMax) : updateMax(100);
angular.isDefined(attr.step)? attr.$observe('step', updateStep) : updateStep(1);
+ angular.isDefined(attr.round)? attr.$observe('round', updateRound) : updateRound(DEFAULT_ROUND);
// We have to manually stop the $watch on ngDisabled because it exists
// on the parent scope, and won't be automatically destroyed when
@@ -124,10 +220,15 @@ function SliderDirective($$rAF, $window, $mdAria, $mdUtil, $mdConstant, $mdThemi
stopDisabledWatch = scope.$parent.$watch(attr.ngDisabled, updateAriaDisabled);
}
- $mdGesture.register(element, 'drag');
+ $mdGesture.register(wrapper, 'drag', { horizontal: !vertical });
+
+ scope.mouseActive = false;
- element
+ wrapper
.on('keydown', keydownListener)
+ .on('mousedown', mouseDownListener)
+ .on('focus', focusListener)
+ .on('blur', blurListener)
.on('$md.pressdown', onPressDown)
.on('$md.pressup', onPressUp)
.on('$md.dragstart', onDragStart)
@@ -138,7 +239,6 @@ function SliderDirective($$rAF, $window, $mdAria, $mdUtil, $mdConstant, $mdThemi
function updateAll() {
refreshSliderDimensions();
ngModelRender();
- redrawTicks();
}
setTimeout(updateAll, 0);
@@ -161,6 +261,7 @@ function SliderDirective($$rAF, $window, $mdAria, $mdUtil, $mdConstant, $mdThemi
var min;
var max;
var step;
+ var round;
function updateMin(value) {
min = parseFloat(value);
element.attr('aria-valuemin', value);
@@ -173,7 +274,10 @@ function SliderDirective($$rAF, $window, $mdAria, $mdUtil, $mdConstant, $mdThemi
}
function updateStep(value) {
step = parseFloat(value);
- redrawTicks();
+ }
+ function updateRound(value) {
+ // Set max round digits to 6, after 6 the input uses scientific notation
+ round = minMaxValidator(parseInt(value), 0, 6);
}
function updateAriaDisabled(isDisabled) {
element.attr('aria-disabled', !!isDisabled);
@@ -184,7 +288,7 @@ function SliderDirective($$rAF, $window, $mdAria, $mdUtil, $mdConstant, $mdThemi
// which could quickly become a performance bottleneck.
var tickCanvas, tickCtx;
function redrawTicks() {
- if (!angular.isDefined(attr.mdDiscrete)) return;
+ if (!discrete || isDisabledGetter()) return;
if ( angular.isUndefined(step) ) return;
if ( step <= 0 ) {
@@ -198,22 +302,40 @@ function SliderDirective($$rAF, $window, $mdAria, $mdUtil, $mdConstant, $mdThemi
tickCanvas = angular.element('