JSFiddle - React, Tailwind, and code Playground
by revolunet
HTML
<script src="http://code.angularjs.org/1.2.2/angular.js"></script>
<script src="http://fonts.googleapis.com/css?family=Roboto"></script>
<body ng-app="demo" ng-controller="DemoController">
<h3>rn-stepper demo (4/5)</h3>
Model value : {{ score }}<br>
Min value : <input ng-model="minScore"><br>
Max value : <input ng-model="maxScore"><br>
<hr>
<div min="minScore" max="maxScore" ng-model="score" rn-stepper></div>
</body>
SCSS
body {
font-family: 'Roboto', sans-serif;
}
$stepper-height: 40px;
$stepper-value-width: 40px;
$stepper-button-width: 40px;
$stepper-border-width: 1px;
$stepper-button-bg: #4D4DFF;
$stepper-value-bg: #eee;
div[rn-stepper] {
&.ng-invalid-out-of-bound {
div {
color: red;
}
}
border:1px solid #bbb;
display:inline-block;
height:$stepper-height + ($stepper-border-width * 2);
box-sizing:border-box;
button {
appearance:none;
-webkit-appearance:none;
margin:0;
border:0;
width: $stepper-button-width;
height:$stepper-height;
box-sizing:border-box;
background: $stepper-button-bg;
color: white;
font-weight:bold;
font-size:20px;
outline: none;
&:active {
box-shadow: inset 0 2px 2px rgba(0, 0, 0, 0.25);
background: darken($stepper-button-bg, 5%);
}
}
div {
vertical-align:top;
width:$stepper-value-width;
background:$stepper-value-bg;
text-align:center;
display:inline-block;
height:$stepper-height;
line-height:$stepper-height;
box-sizing:border-box;
}
}
JavaScript
angular.module('demo', [])
.controller('DemoController', function($scope) {
$scope.score = 50;
$scope.minScore = 40;
$scope.maxScore = 45;
})
.directive('rnStepper', function() {
return {
restrict: 'AE',
require: 'ngModel',
scope: {
value: '=ngModel',
min: '=',
max: '='
},
template: '<button ng-click="decrement()">-</button>' +
'<div>{{ value }}</div>' +
'<button ng-click="increment()">+</button>',
link: function(scope, iElement, iAttrs, ngModelController) {
function checkValue(newValue) {
if (!angular.isDefined(newValue)) newValue = scope.value;
var minRaised = angular.isDefined(scope.min) && newValue < parseInt(scope.min, 10);
var maxRaised = angular.isDefined(scope.max) && newValue > parseInt(scope.max, 10);
var valid = !(minRaised||maxRaised);
ngModelController.$setValidity('out-of-bound', valid);
ngModelController.$setViewValue(newValue);
// scope.value = newValue;
return valid;
}
scope.increment = function() {
checkValue(scope.value + 1);
}
scope.decrement = function() {
checkValue(scope.value - 1);
}
checkValue();
scope.$watch('min+max', function() {
checkValue();
});
}
};
});