Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@jimmont
Created November 2, 2014 00:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jimmont/f7060bd6dc5ad78dd62b to your computer and use it in GitHub Desktop.
Save jimmont/f7060bd6dc5ad78dd62b to your computer and use it in GitHub Desktop.
(function() {
'use strict';
angular.module('derModule')
.directive('inputRange', ['$parse', function ngRangeSlider($parse) {
/**
* @ngdoc directive
* @name input-range
* @description
dual-control range inputs
* @example
<input-range min=0 max=10 step=1 change="$root.range = range"></input-range>
* @src (bits borrowed via)
https://github.com/Wildhoney/ngRangeSlider/
*/
return {
restrict: 'E',
template: '<datalist id="datalist-{{$id}}"><option ng-repeat="i in list">{{i}}</option></datalist><input list="datalist-{{$id}}" type="range" ng-value="range.from" ng-change="change(0)" ng-model="range.from" min="{{min}}" max="{{max}}" step="{{step}}" /><input type="range" ng-value="range.to" ng-change="change(1)" ng-model="range.to" min="{{min}}" max="{{max}}" step="{{step}}" />',
scope: {
step: '=',
max: '=',
min: '='
},
link: function(scope, elem, attr){
var i, j;
var handler = $parse(attr.change);
scope.step = +scope.step || 1;
scope.range = {from: scope.min, to: scope.max};
scope.change = function(layer){
var range = scope.range;
// prevent overrun at either end
if(+range.from > +range.to){
// if(from max) shift the start
if(layer) range.from = range.to;
// else shift the max
else range.to = range.from;
};
handler(scope);
};
scope.change(0);
scope.list = [];
i = +scope.range.from, j = +scope.range.to;
do{
scope.list.push(i);
i += scope.step;
}while(i <= j);
}
};
}])
/*
input-range {
position: relative;
width: 200px;
height: 35px;
}
input-range input {
pointer-events: none;
position: absolute;
overflow: hidden;
left: 0;
top: 0;
width: 200px;
outline: none;
height: 18px;
}
input-range input::-webkit-slider-thumb {
pointer-events: all;
position: relative;
z-index: 1;
outline: 0;
}
input-range input::-moz-range-thumb {
pointer-events: all;
position: relative;
z-index: 10;
-moz-appearance: none;
background: linear-gradient(to bottom, #ededed 0%, #dedede 100%);
width: 11px;
}
input-range input::-moz-range-track {
position: relative;
z-index: -1;
background-color: rgba(0, 0, 0, .15);
border: 0;
}
input-range input:last-of-type::-moz-range-track {
-moz-appearance: none;
background: none transparent;
border: 0;
}
*/
describe('derModule', function(){
beforeEach(module('derModule'));
describe('inputRange', function(){
var elem, scope, ae = angular.element;
beforeEach(inject(function($rootScope, $compile){
scope = $rootScope.$new(true, $rootScope);
elem = $compile('<input-range min=0 max=10 step=1 change="$root.range = range"></input-range>')(scope);
// must be in the DOM tree for the change event to propagate
ae(document.body).append(elem);
scope.$digest();
}));
afterEach(function(){
scope.$destroy();
elem.remove();
elem.triggerHandler('$destroy');
});
it('should create a double range slider', function(){
var v, isolateScope, $0 = elem[0];
expect( $0.querySelectorAll('input').length ).toBe(2);
expect( $0.querySelectorAll('datalist').length ).toBe(1);
expect( $0.querySelectorAll('option').length ).toBe(11);
isolateScope = ae($0).isolateScope();
isolateScope.$apply();
expect( isolateScope.range.from.toString() ).toBe( '0' );
expect( isolateScope.range.to.toString() ).toBe( '10' );
expect( isolateScope.step ).toBe( 1 );
$0 = elem[0].querySelectorAll('input');
expect( $0[0].value ).toBe( '0' );
expect( $0[1].value ).toBe( '10' );
isolateScope.range.to = 4;
isolateScope.range.from = 5;
// max/range.to firing
isolateScope.change(1);
isolateScope.$apply();
expect(isolateScope.range.from).toBe(4);
expect(isolateScope.range.to).toBe(4);
isolateScope.range.to = 4;
isolateScope.range.from = 5;
// min/range.from firing
isolateScope.change(0);
isolateScope.$apply();
expect(isolateScope.range.from).toBe(5);
// change expression should work
expect(isolateScope.$root.range === isolateScope.range).toBe(true);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment