Reputation: 5191
I am working on an angular directive for number stepper. Here is the directive:
.directive('rnStepper', function() {
return {
restrict: 'AE',
require: 'ngModel',
scope: {
min: '=',
max: '='
},
template: '<div class="spinner-buttons input-group-btn"><button ng-click="decrement();" class="btn spinner-down" type="button">- </button></div>' +
'<input type="text" style="text-align: center;" maxlength="3" class="spinner-input form-control ng-pristine ng-untouched ng-valid ng-valid-maxlength"/>' +
'<div class="spinner-buttons input-group-btn"><button ng-click="increment();" class="btn spinner-down" type="button">+</button></div>',
link: function(scope, iElement, iAttrs, ngModelController) {
ngModelController.$render = function() {
iElement.find('input').val(ngModelController.$viewValue);
// update the validation status
checkValidity();
};
// when model change, cast to integer
ngModelController.$formatters.push(function(value) {
return parseInt(value, 10);
});
// when view change, cast to integer
ngModelController.$parsers.push(function(value) {
return parseInt(value, 10);
});
function checkValidity() {
// check if min/max defined to check validity
var valid = !(scope.isOverMin(true) || scope.isOverMax(true));
// set our model validity
// the outOfBounds is an arbitrary key for the error.
// will be used to generate the CSS class names for the errors
ngModelController.$setValidity('outOfBounds', valid);
}
function updateModel(offset) {
// update the model, call $parsers pipeline...
ngModelController.$setViewValue(ngModelController.$viewValue + offset);
// update the local view
ngModelController.$render();
}
scope.isOverMin = function(strict) {
var offset = strict?0:1;
return (angular.isDefined(scope.min) && (ngModelController.$viewValue - offset) < parseInt(scope.min, 10));
};
scope.isOverMax = function(strict) {
var offset = strict?0:1;
return (angular.isDefined(scope.max) && (ngModelController.$viewValue + offset) > parseInt(scope.max, 10));
};
// update the value when user clicks the buttons
scope.increment = function() {
updateModel(+1);
};
scope.decrement = function() {
updateModel(-1);
};
// check validity on start, in case we're directly out of bounds
checkValidity();
// watch out min/max and recheck validity when they change
scope.$watch('min+max', function() {
checkValidity();
});
}
};
});
The '+' and '-' seems to be working fine. However, whenever you modify the value in input text box, then model does not seems to be updated. After modifying value in input text box, whenever you try to increase and decrease then it does not work as expected.
Here is the codepen.
UPD:
As per @Michael answer, I used a ngModel on input text box inside directive.
'<input ng-model="ngModel" type="text" style="text-align: center;" class="spinner-input form-control"/>' +
The model is updated, however ng-change is not being triggered.
However on clicking + or '-', the ng-change is being triggered whenever I edit the input text box!!
Here is my updated codepen
Upvotes: 0
Views: 2613
Reputation: 3104
The text inputfield doesn't have a binding, so angular won't recognice if you enter a number directly. You need to add a change listener or simply use a ng-model directive.
Upvotes: 1