我正在尝试创建输入文本指令,它只接受特定范围内的数字。我尝试将值解析为整数,当然min
和max
不起作用。
我不想使用输入[type =“number”]。
最终,我正在尝试创建一个免费输入文本字段的出生日期。
如下所示:
我已经改编的指令[我现在正试图使用] - 原件可以在angularjs: allows only numbers to be typed into a text box
找到app.directive('onlyDigits', function () {
return {
restrict: 'A',
require: '?ngModel',
link: function (scope, element, attrs, modelCtrl) {
modelCtrl.$parsers.push(function (inputValue) {
if (inputValue == undefined) return '';
var transformedInput = inputValue.replace(/[^0-9]/g, '');
var theInt = parseInt(transformedInput);
if (transformedInput !== inputValue) {
modelCtrl.$setViewValue(transformedInput);
modelCtrl.$render();
}
return theInt;
});
}
};
在我解决这个问题后,我希望做的是做一个条件ng-show
,以显示一个span元素的错误 - 当用户输入的值超过31(当天)时12( (等)。等等。
我欢迎任何建议。
谢谢。
答案 0 :(得分:3)
我遇到了完全相同的问题。我尝试了“一切”,使其既方便用户又不接受无效值。最后,我放弃了显而易见的解决方案,例如ng-pattern
,在朋友@Teemu Turkia的帮助下,我们提出了integers-only
指令。
它使用type="text"
,同时支持min
和max
,不接受超出数字的字符,-
(作为第一个字符,如果最小值为负)则为键入。
此外,ng-model
永远不会分配无效值,例如空字符串或NaN
,只能指定给定范围或null
之间的值。
我知道,起初它看起来相当令人生畏;)
HTML
// note: uses underscore.js
<body>
<form name="form">
<header>DD / MM / YYYY</header>
<section>
<input type="text"
name="day"
ng-model="day"
min="1"
max="31"
integers-only>
<input type="text"
name="month"
ng-model="month"
min="1"
max="12"
integers-only>
<input type="text"
name="year"
ng-model="year"
min="1900"
max="2016"
integers-only>
</section>
<section>
<span ng-show="form.day.$invalid">Invalid day</span>
<span ng-show="form.month.$invalid">Invalid month</span>
<span ng-show="form.year.$invalid">Invalid year</span>
</section>
</form>
</body>
<强>的JavaScript 强>
/**
* numeric input
* <input type="text" name="name" ng-model="model" min="0" max="100" integers-only>
*/
angular.module('app', [])
.directive('integersOnly', function() {
return {
restrict: 'A',
require: 'ngModel',
scope: {
min: '=',
max: '='
},
link: function(scope, element, attrs, modelCtrl) {
function isInvalid(value) {
return (value === null || typeof value === 'undefined' || !value.length);
}
function replace(value) {
if (isInvalid(value)) {
return null;
}
var newValue = [];
var chrs = value.split('');
var allowedChars = ['0','1','2','3','4','5','6','7','8','9','-'];
for (var index = 0; index < chrs.length; index++) {
if (_.contains(allowedChars, chrs[index])) {
if (index > 0 && chrs[index] === '-') {
break;
}
newValue.push(chrs[index]);
}
}
return newValue.join('') || null;
}
modelCtrl.$parsers.push(function(value) {
var originalValue = value;
value = replace(value);
if (value !== originalValue) {
modelCtrl.$setViewValue(value);
modelCtrl.$render();
}
return value && isFinite(value) ? parseInt(value) : value;
});
modelCtrl.$formatters.push(function(value) {
if (value === null || typeof value === 'undefined') {
return null;
}
return parseInt(value);
});
modelCtrl.$validators.min = function(modelValue) {
if (scope.min !== null && modelValue !== null && modelValue < scope.min) { return false; }
return true;
};
modelCtrl.$validators.max = function(modelValue) {
if (scope.max !== null && modelValue !== null && modelValue > scope.max) { return false; }
return true;
};
modelCtrl.$validators.hasOnlyChar = function(modelValue) {
if (!isInvalid(modelValue) && modelValue === '-') { return false; }
return true;
};
}
};
});
<强>结果强>
此处相关的plunker http://plnkr.co/edit/mIiKuw
答案 1 :(得分:2)
这是没有任何自定义指令的解决方案。它仍然是input type="number"
,但实现了所需的功能。
这是plunker
<!DOCTYPE html>
<html>
<head></head>
<body ng-app="app" ng-controller="dobController as dob">
<h3>Date of birth form</h3>
<form name="dobForm" class="form" novalidate="">
<div>
<label for="date">DD</label>
<input type="number" ng-model="dob.date" name="date" min="1" max="31" integer />
<label for="month">MM</label>
<input type="number" ng-model="dob.month" name="month" min="1" max="12" integer />
<label for="year">YYYY</label>
<input type="number" ng-model="dob.year" name="year" min="1900" max="2016" integer />
<div style="color: red;" ng-if="dobForm.$invalid">
<p ng-show="dobForm.date.$error.min || dobForm.date.$error.max">
date must be in range 1 to 31!
</p>
<p ng-show="dobForm.month.$error.min || dobForm.month.$error.max">
month must be in range 1 to 12!
</p>
<p ng-show="dobForm.year.$error.min || dobForm.year.$error.max">
year must be in range 1900 to 2016!
</p>
</div>
</div>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular-messages.js"></script>
<script>
var app = angular.module('app', []);
app.controller('dobController', function($scope) {});
</script>
<style>
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
</style>
</body>
</html>
&#13;
答案 2 :(得分:0)
此解决方案使用min和max属性来限制输入字段的值。它还使用ngModelOptions仅在定义的时间间隔后更新模型值。这是为了允许用户在模型解析器对输入进行操作之前键入值。
angular.module("app", []);
angular.module("app").directive('onlyDigits', function() {
return {
restrict: 'A',
require: '?ngModel',
scope: {
min: "@",
max: "@"
},
link: function(scope, element, attrs, modelCtrl) {
modelCtrl.$parsers.push(function(inputValue) {
if (inputValue == undefined) return '';
var transformedInput = inputValue.replace(/[^0-9]/g, '');
var theInt = parseInt(transformedInput);
var max = scope.max;
var min = scope.min;
if (theInt > max) {
theInt = max;
} else if (theInt < min) {
theInt = min;
}
modelCtrl.$setViewValue(theInt.toString());
modelCtrl.$render();
return theInt;
});
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<body ng-app="app">
<input type="text" ng-model="month" ng-model-options="{ debounce: 200 }" only-digits min="1" max="12">
<input type="text" ng-model="day" ng-model-options="{ debounce: 200 }" min="1" max="30" only-digits>
<input type="text" ng-model="year" ng-model-options="{ debounce: 500 }" only-digits min="1900" max="2050">
</body>