숫자 (숫자 및 소수점) 만 입력하도록 허용하는 방법은 무엇입니까?
저는 angularjs를 처음 사용합니다. 텍스트 상자에 입력 된 유효한 숫자 만 허용하는 방법이 궁금합니다. 예를 들어 사용자는 "1.25"를 입력 할 수 있지만 "1.a"또는 "1 .."은 입력 할 수 없습니다. 사용자가 유효하지 않은 숫자로 만드는 다음 문자를 입력하려고하면 입력 할 수 없습니다.
미리 감사드립니다.
이 지시문을 사용하여 유효하지 않은 문자가 입력 필드에 입력되지 않도록 할 수 있습니다. ( 업데이트 : 이것은 재사용에 이상적이지 않은 모델에 대한 명시적인 지식을 가진 지침에 의존합니다. 재사용 가능한 예는 아래를 참조하십시오.)
app.directive('isNumber', function () {
return {
require: 'ngModel',
link: function (scope) {
scope.$watch('wks.number', function(newValue,oldValue) {
var arr = String(newValue).split("");
if (arr.length === 0) return;
if (arr.length === 1 && (arr[0] == '-' || arr[0] === '.' )) return;
if (arr.length === 2 && newValue === '-.') return;
if (isNaN(newValue)) {
scope.wks.number = oldValue;
}
});
}
};
});
또한 다음 시나리오를 설명합니다.
- 비어 있지 않은 유효한 문자열에서 빈 문자열로 이동
- 음수 값
- 음수 십진수 값
어떻게 작동하는지 볼 수 있도록 여기 에 jsFiddle 을 만들었습니다 .
최신 정보
지시문 내부에 모델 참조를 직접 포함하지 않는 것에 대한 Adam Thomas의 피드백에 따라 (또한 최선의 접근 방식이라고 생각합니다) jsFiddle 을 업데이트 하여 이에 의존하지 않는 메서드를 제공했습니다.
지시문은 부모 범위에 대한 로컬 범위 의 양방향 바인딩 을 사용 합니다. 지시문 내의 변수에 대한 변경 사항은 부모 범위에 반영되며 그 반대의 경우도 마찬가지입니다.
HTML :
<form ng-app="myapp" name="myform" novalidate>
<div ng-controller="Ctrl">
<number-only-input input-value="wks.number" input-name="wks.name"/>
</div>
</form>
각도 코드 :
var app = angular.module('myapp', []);
app.controller('Ctrl', function($scope) {
$scope.wks = {number: 1, name: 'testing'};
});
app.directive('numberOnlyInput', function () {
return {
restrict: 'EA',
template: '<input name="{{inputName}}" ng-model="inputValue" />',
scope: {
inputValue: '=',
inputName: '='
},
link: function (scope) {
scope.$watch('inputValue', function(newValue,oldValue) {
var arr = String(newValue).split("");
if (arr.length === 0) return;
if (arr.length === 1 && (arr[0] == '-' || arr[0] === '.' )) return;
if (arr.length === 2 && newValue === '-.') return;
if (isNaN(newValue)) {
scope.inputValue = oldValue;
}
});
}
};
});
숫자 사용자 입력을 필터링하는 훌륭한 방법을 보여주기 위해 작동하는 CodePen 예제 를 작성했습니다 . 지시문은 현재 양의 정수만 허용하지만 원하는 숫자 형식을 지원하도록 정규식을 쉽게 업데이트 할 수 있습니다.
내 지시문은 사용하기 쉽습니다.
<input type="text" ng-model="employee.age" valid-number />
이 지침은 매우 이해하기 쉽습니다.
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
});
app.directive('validNumber', function() {
return {
require: '?ngModel',
link: function(scope, element, attrs, ngModelCtrl) {
if(!ngModelCtrl) {
return;
}
ngModelCtrl.$parsers.push(function(val) {
if (angular.isUndefined(val)) {
var val = '';
}
var clean = val.replace( /[^0-9]+/g, '');
if (val !== clean) {
ngModelCtrl.$setViewValue(clean);
ngModelCtrl.$render();
}
return clean;
});
element.bind('keypress', function(event) {
if(event.keyCode === 32) {
event.preventDefault();
}
});
}
};
});
지침에서 모델 참조 를 유지하는 것이 중요하다는 점 을 강조하고 싶습니다 .
도움이 되었기를 바랍니다.
ngModelController 를 소개 해주신 Sean Christe 와 Chris Grimes에게 감사드립니다.
우선 Adam thomas 덕분에 저는 소수 값을 받아들이 기 위해 약간의 수정으로 동일한 Adam의 논리를 사용했습니다.
참고 : 소수 2 자리 만 허용됩니다.
다음은 내 작업 예입니다.
HTML
<input type="text" ng-model="salary" valid-number />
자바 스크립트
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
});
app.directive('validNumber', function() {
return {
require: '?ngModel',
link: function(scope, element, attrs, ngModelCtrl) {
if(!ngModelCtrl) {
return;
}
ngModelCtrl.$parsers.push(function(val) {
if (angular.isUndefined(val)) {
var val = '';
}
var clean = val.replace(/[^0-9\.]/g, '');
var decimalCheck = clean.split('.');
if(!angular.isUndefined(decimalCheck[1])) {
decimalCheck[1] = decimalCheck[1].slice(0,2);
clean =decimalCheck[0] + '.' + decimalCheck[1];
}
if (val !== clean) {
ngModelCtrl.$setViewValue(clean);
ngModelCtrl.$render();
}
return clean;
});
element.bind('keypress', function(event) {
if(event.keyCode === 32) {
event.preventDefault();
}
});
}
};
});
단계 태그를 사용하여 변경 가능한 최소 값을 10 진수로 설정합니다.
예 : step = "0.01"
<input type="number" step="0.01" min="0" class="form-control"
name="form_name" id="your_id" placeholder="Please Input a decimal number" required>
여기에 몇 가지 문서가 있습니다.
http://blog.isotoma.com/2012/03/html5-input-typenumber-and-decimalsfloats-in-chrome/
DEMO - - jsFiddle
지령
.directive('onlyNum', function() {
return function(scope, element, attrs) {
var keyCode = [8,9,37,39,48,49,50,51,52,53,54,55,56,57,96,97,98,99,100,101,102,103,104,105,110];
element.bind("keydown", function(event) {
console.log($.inArray(event.which,keyCode));
if($.inArray(event.which,keyCode) == -1) {
scope.$apply(function(){
scope.$eval(attrs.onlyNum);
event.preventDefault();
});
event.preventDefault();
}
});
};
});
HTML
<input type="number" only-num>
참고 : 각도 js와 함께 jQuery를 포함하는 것을 잊지 마십시오
ng-pattern을 쉽게 사용할 수 있습니다.
ng-pattern="/^[1-9][0-9]{0,2}(?:,?[0-9]{3}){0,3}(?:\.[0-9]{1,2})?$/"
내가 원하는 것을 할 수 있다고 믿는 입력 번호 지시문이 있습니다.
<input type="number"
ng-model="{string}"
[name="{string}"]
[min="{string}"]
[max="{string}"]
[required]
[ng-required="{string}"]
[ng-minlength="{number}"]
[ng-maxlength="{number}"]
[ng-pattern="{string}"]
[ng-change="{string}"]>
공식 문서는 여기에 있습니다 : http://docs.angularjs.org/api/ng.directive:input.number
HTML
<input type="text" name="number" only-digits>
// 123을 입력하십시오.
.directive('onlyDigits', function () {
return {
require: 'ngModel',
restrict: 'A',
link: function (scope, element, attr, ctrl) {
function inputValue(val) {
if (val) {
var digits = val.replace(/[^0-9]/g, '');
if (digits !== val) {
ctrl.$setViewValue(digits);
ctrl.$render();
}
return parseInt(digits,10);
}
return undefined;
}
ctrl.$parsers.push(inputValue);
}
};
// 입력 : 123 또는 123.45
.directive('onlyDigits', function () {
return {
require: 'ngModel',
restrict: 'A',
link: function (scope, element, attr, ctrl) {
function inputValue(val) {
if (val) {
var digits = val.replace(/[^0-9.]/g, '');
if (digits !== val) {
ctrl.$setViewValue(digits);
ctrl.$render();
}
return parseFloat(digits);
}
return undefined;
}
ctrl.$parsers.push(inputValue);
}
};
범위 min
와 max
속성이 다음과 같이 제한 될 수있는 지시문을 원했습니다 .
<input type="text" integer min="1" max="10" />
그래서 다음과 같이 썼습니다.
.directive('integer', function() {
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, elem, attr, ngModel) {
if (!ngModel)
return;
function isValid(val) {
if (val === "")
return true;
var asInt = parseInt(val, 10);
if (asInt === NaN || asInt.toString() !== val) {
return false;
}
var min = parseInt(attr.min);
if (min !== NaN && asInt < min) {
return false;
}
var max = parseInt(attr.max);
if (max !== NaN && max < asInt) {
return false;
}
return true;
}
var prev = scope.$eval(attr.ngModel);
ngModel.$parsers.push(function (val) {
// short-circuit infinite loop
if (val === prev)
return val;
if (!isValid(val)) {
ngModel.$setViewValue(prev);
ngModel.$render();
return prev;
}
prev = val;
return val;
});
}
};
});
여기 내 정말 빠르고 더러운 것이 있습니다.
<!-- HTML file -->
<html ng-app="num">
<head></head>
<body ng-controller="numCtrl">
<form class="digits" name="digits" ng-submit="getGrades()" novalidate >
<input type="text" placeholder="digits here plz" name="nums" ng-model="nums" required ng-pattern="/^(\d)+$/" />
<p class="alert" ng-show="digits.nums.$error.pattern">Numbers only, please.</p>
<br>
<input type="text" placeholder="txt here plz" name="alpha" ng-model="alpha" required ng-pattern="/^(\D)+$/" />
<p class="alert" ng-show="digits.alpha.$error.pattern">Text only, please.</p>
<br>
<input class="btn" type="submit" value="Do it!" ng-disabled="!digits.$valid" />
</form>
</body>
</html>
// Javascript file
var app = angular.module('num', ['ngResource']);
app.controller('numCtrl', function($scope, $http){
$scope.digits = {};
});
이를 위해서는 유효성 검사를 위해 필드에 대한 영구 바인딩을위한 angular-resource 라이브러리를 포함해야합니다.
1.2.0-rc.3 +에서 챔피언처럼 작동합니다. 정규식을 수정하면 모든 설정이 완료됩니다. 아마도 뭔가 /^(\d|\.)+$/
? 항상 그렇듯이 완료되면 서버 측의 유효성을 검사하십시오.
이것은 나에게 가장 쉬운 것 같습니다 : http://jsfiddle.net/thomporter/DwKZh/
(코드는 내 것이 아닙니다, 실수로 우연히 발견했습니다)
angular.module('myApp', []).directive('numbersOnly', function(){
return {
require: 'ngModel',
link: function(scope, element, attrs, modelCtrl) {
modelCtrl.$parsers.push(function (inputValue) {
// this next if is necessary for when using ng-required on your input.
// In such cases, when a letter is typed first, this parser will be called
// again, and the 2nd time, the value will be undefined
if (inputValue == undefined) return ''
var transformedInput = inputValue.replace(/[^0-9]/g, '');
if (transformedInput!=inputValue) {
modelCtrl.$setViewValue(transformedInput);
modelCtrl.$render();
}
return transformedInput;
});
}
};
});
위의 Alan의 대답을 수정하여 숫자를 지정된 최소 / 최대로 제한했습니다. 범위 밖의 숫자를 입력하면 1500ms 후에 최소 또는 최대 값이 설정됩니다. 필드를 완전히 지우면 아무것도 설정되지 않습니다.
HTML :
<input type="text" ng-model="employee.age" min="18" max="99" valid-number />
자바 스크립트 :
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {});
app.directive('validNumber', function($timeout) {
return {
require: '?ngModel',
link: function(scope, element, attrs, ngModelCtrl) {
if (!ngModelCtrl) {
return;
}
var min = +attrs.min;
var max = +attrs.max;
var lastValue = null;
var lastTimeout = null;
var delay = 1500;
ngModelCtrl.$parsers.push(function(val) {
if (angular.isUndefined(val)) {
val = '';
}
if (lastTimeout) {
$timeout.cancel(lastTimeout);
}
if (!lastValue) {
lastValue = ngModelCtrl.$modelValue;
}
if (val.length) {
var value = +val;
var cleaned = val.replace( /[^0-9]+/g, '');
// This has no non-numeric characters
if (val.length === cleaned.length) {
var clean = +cleaned;
if (clean < min) {
clean = min;
} else if (clean > max) {
clean = max;
}
if (value !== clean || value !== lastValue) {
lastTimeout = $timeout(function () {
lastValue = clean;
ngModelCtrl.$setViewValue(clean);
ngModelCtrl.$render();
}, delay);
}
// This has non-numeric characters, filter them out
} else {
ngModelCtrl.$setViewValue(lastValue);
ngModelCtrl.$render();
}
}
return lastValue;
});
element.bind('keypress', function(event) {
if (event.keyCode === 32) {
event.preventDefault();
}
});
element.on('$destroy', function () {
element.unbind('keypress');
});
}
};
});
비슷한 문제가 있었고 input[type="number"]
십진수 정밀도로 작업하기 위해 각도 문서 의 예제를 업데이트 했으며이 접근 방식을 사용하여 해결하고 있습니다.
추신 : 브라우저가 입력 [type = "number"]에서 'e'와 'E'문자를 지원한다는 점을 간단히 상기시켜줍니다 keypress
. 이벤트가 필요 하기 때문입니다 .
angular.module('numfmt-error-module', [])
.directive('numbersOnly', function() {
return {
require: 'ngModel',
scope: {
precision: '@'
},
link: function(scope, element, attrs, modelCtrl) {
var currencyDigitPrecision = scope.precision;
var currencyDigitLengthIsInvalid = function(inputValue) {
return countDecimalLength(inputValue) > currencyDigitPrecision;
};
var parseNumber = function(inputValue) {
if (!inputValue) return null;
inputValue.toString().match(/-?(\d+|\d+.\d+|.\d+)([eE][-+]?\d+)?/g).join('');
var precisionNumber = Math.round(inputValue.toString() * 100) % 100;
if (!!currencyDigitPrecision && currencyDigitLengthIsInvalid(inputValue)) {
inputValue = inputValue.toFixed(currencyDigitPrecision);
modelCtrl.$viewValue = inputValue;
}
return inputValue;
};
var countDecimalLength = function (number) {
var str = '' + number;
var index = str.indexOf('.');
if (index >= 0) {
return str.length - index - 1;
} else {
return 0;
}
};
element.on('keypress', function(evt) {
var charCode, isACommaEventKeycode, isADotEventKeycode, isANumberEventKeycode;
charCode = String.fromCharCode(evt.which || event.keyCode);
isANumberEventKeycode = '0123456789'.indexOf(charCode) !== -1;
isACommaEventKeycode = charCode === ',';
isADotEventKeycode = charCode === '.';
var forceRenderComponent = false;
if (modelCtrl.$viewValue != null && !!currencyDigitPrecision) {
forceRenderComponent = currencyDigitLengthIsInvalid(modelCtrl.$viewValue);
}
var isAnAcceptedCase = isANumberEventKeycode || isACommaEventKeycode || isADotEventKeycode;
if (!isAnAcceptedCase) {
evt.preventDefault();
}
if (forceRenderComponent) {
modelCtrl.$render(modelCtrl.$viewValue);
}
return isAnAcceptedCase;
});
modelCtrl.$render = function(inputValue) {
return element.val(parseNumber(inputValue));
};
modelCtrl.$parsers.push(function(inputValue) {
if (!inputValue) {
return inputValue;
}
var transformedInput;
modelCtrl.$setValidity('number', true);
transformedInput = parseNumber(inputValue);
if (transformedInput !== inputValue) {
modelCtrl.$viewValue = transformedInput;
modelCtrl.$commitViewValue();
modelCtrl.$render(transformedInput);
}
return transformedInput;
});
}
};
});
그리고 HTML에서이 접근 방식을 사용할 수 있습니다.
<input
type="number"
numbers-only
precision="2"
ng-model="model.value"
step="0.10" />
Gordy의 답변에서 확장 :
잘 했어 btw. 그러나 그것은 또한 전면에 +를 허용했습니다. 이것은 그것을 제거합니다.
scope.$watch('inputValue', function (newValue, oldValue) {
var arr = String(newValue).split("");
if (arr.length === 0) return;
if (arr.length === 1 && (arr[0] == '-' || arr[0] === '.')) return;
if (arr.length === 2 && newValue === '-.') return;
if (isNaN(newValue)) {
scope.inputValue = oldValue;
}
if (arr.length > 0) {
if (arr[0] === "+") {
scope.inputValue = oldValue;
}
}
});
여기에 두 번 입력되는 소수점을 차단하는 미분이 있습니다.
HTML
<input tabindex="1" type="text" placeholder="" name="salary" id="salary" data-ng-model="salary" numbers-only="numbers-only" required="required">
모난
var app = angular.module("myApp", []);
app.directive('numbersOnly', function() {
return {
require : 'ngModel', link : function(scope, element, attrs, modelCtrl) {
modelCtrl.$parsers.push(function(inputValue) {
if (inputValue == undefined) {
return ''; //If value is required
}
// Regular expression for everything but [.] and [1 - 10] (Replace all)
var transformedInput = inputValue.replace(/[a-z!@#$%^&*()_+\-=\[\]{};':"\\|,<>\/?]/g, '');
// Now to prevent duplicates of decimal point
var arr = transformedInput.split('');
count = 0; //decimal counter
for ( var i = 0; i < arr.length; i++) {
if (arr[i] == '.') {
count++; // how many do we have? increment
}
}
// if we have more than 1 decimal point, delete and leave only one at the end
while (count > 1) {
for ( var i = 0; i < arr.length; i++) {
if (arr[i] == '.') {
arr[i] = '';
count = 0;
break;
}
}
}
// convert the array back to string by relacing the commas
transformedInput = arr.toString().replace(/,/g, '');
if (transformedInput != inputValue) {
modelCtrl.$setViewValue(transformedInput);
modelCtrl.$render();
}
return transformedInput;
});
}
};
});
Adam Thomas 답변을 확장하면 사용자 정의 regexp로 입력 인수를 추가 하여이 지시문을 더 일반적으로 쉽게 만들 수 있습니다.
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
});
app.directive('validInput', function() {
return {
require: '?ngModel',
scope: {
"inputPattern": '@'
},
link: function(scope, element, attrs, ngModelCtrl) {
var regexp = null;
if (scope.inputPattern !== undefined) {
regexp = new RegExp(scope.inputPattern, "g");
}
if(!ngModelCtrl) {
return;
}
ngModelCtrl.$parsers.push(function(val) {
if (regexp) {
var clean = val.replace(regexp, '');
if (val !== clean) {
ngModelCtrl.$setViewValue(clean);
ngModelCtrl.$render();
}
return clean;
}
else {
return val;
}
});
element.bind('keypress', function(event) {
if(event.keyCode === 32) {
event.preventDefault();
}
});
}
}});
HTML
<input type="text" ng-model="employee.age" valid-input
input-pattern="[^0-9]+" placeholder="Enter an age" />
</label>
CodePen에서 라이브
특정 데이터 유형 만 허용하는 데 도움이되는 내 구성 요소를 확인하십시오. 현재 정수, 십진수, 문자열 및 시간 (HH : MM)을 지원합니다.
string
-문자열은 선택 가능한 최대 길이로 허용됩니다.integer
- Integer only allowed with optional max valuedecimal
- Decimal only allowed with optional decimal points and max value (by default 2 decimal points)time
- 24 hr Time format(HH:MM) only allowed
https://github.com/ksnimmy/txDataType
Hope that helps.
DECIMAL
directive('decimal', function() {
return {
require: 'ngModel',
restrict: 'A',
link: function(scope, element, attr, ctrl) {
function inputValue(val) {
if (val) {
var digits = val.replace(/[^0-9.]/g, '');
if (digits.split('.').length > 2) {
digits = digits.substring(0, digits.length - 1);
}
if (digits !== val) {
ctrl.$setViewValue(digits);
ctrl.$render();
}
return parseFloat(digits);
}
return "";
}
ctrl.$parsers.push(inputValue);
}
};
});
DIGITS
directive('entero', function() {
return {
require: 'ngModel',
restrict: 'A',
link: function(scope, element, attr, ctrl) {
function inputValue(val) {
if (val) {
var value = val + ''; //convert to string
var digits = value.replace(/[^0-9]/g, '');
if (digits !== value) {
ctrl.$setViewValue(digits);
ctrl.$render();
}
return parseInt(digits);
}
return "";
}
ctrl.$parsers.push(inputValue);
}
};
});
'development' 카테고리의 다른 글
PHP에서 두 datetime 사이의 간격 초를 얻습니까? (0) | 2020.12.13 |
---|---|
자바 스크립트를 사용하여 24 시간 시간을 오전 및 오후 12 시간 시간으로 변환 (0) | 2020.12.13 |
PHP에서 숫자 기호 변경? (0) | 2020.12.13 |
json_decode는 웹 서비스 호출 후 NULL을 반환합니다. (0) | 2020.12.13 |
“Invariant Violation : Application AwesomeProject가 등록되지 않았습니다.”정적 jsbundle로 iOS 장치 용으로 빌드 할 때 (0) | 2020.12.13 |