Issue
here on stackoverflow I found a directive made by an user for angularJS, for a input number spinner, and I was just looking for it!
All working good, but one thing is not, when you manually enter a number in the input field, and press MINUS, it s gonna subtract 1 from that number, all good here,
but when you input a number and as first thing you press PLUS, instead of adding 1, it's gonna add a "1"
next to the number you wrote!
Only going "minus" once fixes it,
can someone help me fix the code to avoid this? I want that when I put the number manually, you can press on "plus" and get +1
on that number!
http://jsfiddle.net/Legendary/84qxvgm8/
Solution
That's because input type="text"
will return a string as a model value, and as was mentioned by @AlekseySolovey - you'll have to cast it to a Number (since "10" + 1
will give you "101" as a result). As you are using numericOnly
directive as well, it seems to be the right place to do the conversion, since you'll wave to do it only in the one place. Here is an example:
(function () {
"use strict";
var app = angular
.module("app", []);
app.controller('AppController', ['$scope', function ($scope) {
var vm = this;
vm.testNumber = 10;
}]);
app.directive('numericOnly', function () {
return {
require: 'ngModel',
link: function (scope, element, attrs, modelCtrl) {
modelCtrl.$parsers.push(function (inputValue) {
if (angular.isNumber(inputValue)) {
return inputValue;
}
var transformedInput = inputValue ? Number(inputValue.replace(/[^\d.-]/g, '')) : null;
if (transformedInput != inputValue) {
modelCtrl.$setViewValue(transformedInput);
modelCtrl.$render();
}
return transformedInput;
});
}
};
});
app.directive('numberSpin', [function () {
return {
restrict: 'E',
scope: {
"ngModel": '='
},
template: '<div>' +
'<input numeric-only data-ng-model="ngModel" ng-pattern="onlyNumbers" type="text">' +
'<a class="ns-plus" data-ng-click="plus()">+</a>' +
'<a class="ns-minus"data-ng-click="minus()">-</a> </div>',
link: function (scope, elem, attrs) {
scope.onlyNumbers = /^\d+$/;
scope.plus = function () {
scope.ngModel = scope.ngModel + 1;
};
scope.minus = function () {
scope.ngModel = scope.ngModel - 1;
};
}
}
}])
}());
number-spin div {
position: relative;
width: 126px;
}
number-spin input {
height: 32px;
width: 100%;
text-align: right;
padding-right: 20px;
box-sizing: border-box;
font-size: 16px;
}
number-spin .ns-plus {
position: absolute;
text-align: center;
line-height: 16px;
top: 0;
right: 0;
height: 16px;
display: block;
border-left: 1px solid #ccc;
border-bottom: 1px solid #ccc;
width: 16px;
}
number-spin .ns-minus {
position: absolute;
text-align: center;
display: block;
line-height: 16px;
height: 16px;
border-left: 1px solid #ccc;
bottom: 0;
right: 0;
width: 16px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
<div ng-app="app" style="padding: 16px; "data-ng-controller="AppController as vm">
<number-spin data-ng-model="vm.testNumber"></number-spin>
</div>
UPDATE: A bit simpler code that allows passing min
/max
into the directive:
(function () {
"use strict";
var app = angular
.module("app", []);
app.controller('AppController', ['$scope', function ($scope) {
var vm = this;
vm.testNumber = 10;
}]);
app.directive('numberSpin', [function () {
return {
restrict: 'E',
scope: {
"ngModel": '=',
"min": '<',
"max": '<',
"step": '<'
},
template: '<div>' +
'<input data-ng-model="ngModel" type="number" ng-attr-min="{{min}}" ng-attr-max="{{max}}">' +
'<a class="btn ns-plus" data-ng-click="plus()">+</a>' +
'<a class="btn ns-minus"data-ng-click="minus()">-</a> </div>',
link: function (scope, elem, attrs) {
scope.plus = function () {
if (scope.ngModel >= scope.max) return;
scope.ngModel += (scope.step || 1);
checkModel()
};
scope.minus = function () {
if (scope.ngModel <= scope.min) return;
scope.ngModel -= (scope.step || 1);
checkModel();
};
function checkModel() {
if (!scope.ngModel) scope.ngModel = scope.min || 0;
}
}
}
}])
}());
number-spin div {
position: relative;
width: 126px;
}
number-spin input {
height: 32px;
width: 100%;
text-align: right;
padding-right: 20px;
box-sizing: border-box;
font-size: 16px;
}
number-spin .btn {
position: absolute;
text-align: center;
line-height: 16px;
display: block;
height: 16px;
right: 0;
border-left: 1px solid #ccc;
width: 16px;
cursor: pointer;
user-select: none;
}
number-spin .ns-plus {
top: 0;
border-bottom: 1px solid #ccc;
cursor: pointer;
user-select: none;
}
number-spin .ns-minus {
bottom: 0;
}
number-spin input[type=number]::-webkit-inner-spin-button,
number-spin input[type=number]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
<div ng-app="app" style="padding: 16px; "data-ng-controller="AppController as vm">
<number-spin data-ng-model="vm.testNumber" min="0" max="15"></number-spin>
</div>
Answered By - Stanislav Kvitash
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.