Saya menggunakan ngChange di AngularJS untuk memicu fungsi kustom yang akan menghapus semua huruf yang ditambahkan pengguna ke input.
<input type="text" name="inputName" data-ng-change="numbersOnly()"/>
Masalahnya adalah saya harus menargetkan masukan yang dipicu numbersOnly()
sehingga saya dapat menghapus huruf yang dimasukkan. Saya telah mencari lama dan keras di Google dan tidak dapat menemukan apa pun tentang ini.
Apa yang dapat saya?
javascript
angularjs
angularjs-directive
Chris Bier
sumber
sumber
Jawaban:
Cara mudah , gunakan type = "number" jika berfungsi untuk kasus penggunaan Anda:
<input type="number" ng-model="myText" name="inputName">
Cara mudah lainnya: ng-pattern juga dapat digunakan untuk mendefinisikan regex yang akan membatasi apa yang diperbolehkan di lapangan. Lihat juga halaman "buku masak" tentang formulir .
Hackish? cara , $ perhatikan ng-model di pengontrol Anda:
<input type="text" ng-model="myText" name="inputName">
Pengontrol:
$scope.$watch('myText', function() { // put numbersOnly() logic here, e.g.: if ($scope.myText ... regex to look for ... ) { // strip out the non-numbers } })
Cara terbaik , gunakan $ parser sebagai direktif. Saya tidak akan mengulangi jawaban yang sudah bagus yang diberikan oleh @ pkozlowski.opensource, jadi inilah tautannya: https://stackoverflow.com/a/14425022/215945
Semua solusi di atas melibatkan penggunaan ng-model, yang membuat pencarian
this
tidak perlu.Menggunakan ng-change akan menimbulkan masalah. Lihat AngularJS - reset $ scope.value tidak mengubah nilai di templat (perilaku acak)
sumber
type=number
secara otomatis akan menampilkan pemintal yang mungkin tidak diinginkan. Anda dapat menyembunyikan spinner melalui css, tetapi itu mungkin tidak berfungsi di semua browser.Menggunakan
ng-pattern
di bidang teks:<input type="text" ng-model="myText" name="inputName" ng-pattern="onlyNumbers">
Kemudian masukkan ini ke pengontrol Anda
$scope.onlyNumbers = /^\d+$/;
sumber
Tidak ada solusi yang diusulkan yang bekerja dengan baik untuk saya, dan setelah beberapa jam saya akhirnya menemukan jalannya.
Ini adalah arahan sudut:
angular.module('app').directive('restrictTo', function() { return { restrict: 'A', link: function (scope, element, attrs) { var re = RegExp(attrs.restrictTo); var exclude = /Backspace|Enter|Tab|Delete|Del|ArrowUp|Up|ArrowDown|Down|ArrowLeft|Left|ArrowRight|Right/; element[0].addEventListener('keydown', function(event) { if (!exclude.test(event.key) && !re.test(event.key)) { event.preventDefault(); } }); } } });
Dan masukannya akan terlihat seperti:
<input type="number" min="0" name="inputName" ng-model="myModel" restrict-to="[0-9]">
Ekspresi reguler mengevaluasi tombol yang ditekan, bukan nilainya .
Ia juga bekerja sempurna dengan masukan
type="number"
karena mencegah dari mengubah nilainya, sehingga kuncinya tidak pernah ditampilkan dan tidak mengacaukan model.sumber
restrict-to="[0-9\-]"
Inilah implementasi saya dari
$parser
solusi yang direkomendasikan @Mark Rajcok sebagai metode terbaik. Ini pada dasarnya adalah $ parser yang sangat baik dari @ pkozlowski.opensource untuk jawaban teks tetapi ditulis ulang untuk hanya mengizinkan numerik. Semua pujian diberikan kepadanya, ini hanya untuk menghemat 5 menit membaca jawaban itu dan kemudian menulis ulang jawaban Anda sendiri:app.directive('numericOnly', function(){ return { require: 'ngModel', link: function(scope, element, attrs, modelCtrl) { modelCtrl.$parsers.push(function (inputValue) { var transformedInput = inputValue ? inputValue.replace(/[^\d.-]/g,'') : null; if (transformedInput!=inputValue) { modelCtrl.$setViewValue(transformedInput); modelCtrl.$render(); } return transformedInput; }); } }; });
Dan Anda akan menggunakannya seperti ini:
<input type="text" name="number" ng-model="num_things" numeric-only>
Menariknya, spasi tidak pernah mencapai parser kecuali dikelilingi oleh alfanumerik, jadi Anda harus melakukannya
.trim()
sesuai kebutuhan. Juga, parser ini TIDAK berfungsi<input type="number">
. Untuk beberapa alasan, non-numerik tidak pernah membuat ke parser di mana mereka akan dihapus, tetapi mereka lakukan membuatnya menjadi kontrol input itu sendiri.sumber
var transformedInput = inputValue ? inputValue.replace(/[^\d.-]/g,'') : null;
ng-trim
untukfalse
memastikan spasi mencapai parser Anda.modelCtrl.$commitViewValue();
antara $ setViewValue (clean); dan $ render ();Ada beberapa cara untuk melakukan ini.
Anda bisa menggunakan
type="number"
:<input type="number" />
Atau - Saya membuat arahan yang dapat digunakan kembali untuk ini yang menggunakan ekspresi reguler.
Html
<div ng-app="myawesomeapp"> test: <input restrict-input="^[0-9-]*$" maxlength="20" type="text" class="test" /> </div>
Javascript
;(function(){ var app = angular.module('myawesomeapp',[]) .directive('restrictInput', [function(){ return { restrict: 'A', link: function (scope, element, attrs) { var ele = element[0]; var regex = RegExp(attrs.restrictInput); var value = ele.value; ele.addEventListener('keyup',function(e){ if (regex.test(ele.value)){ value = ele.value; }else{ ele.value = value; } }); } }; }]); }());
sumber
Berikut adalah solusi yang cukup bagus untuk membuat hanya izinkan masukkan nomor ke
input
:<input type="text" ng-model="myText" name="inputName" onkeypress='return event.charCode >= 48 && event.charCode <= 57'/>
sumber
Semua solusi di atas cukup besar, saya ingin memberikan 2 sen saya untuk ini.
Saya hanya memeriksa apakah nilai yang dimasukkan adalah angka atau tidak, dan memeriksa apakah tidak kosong, itu saja.
Ini html-nya:
<input type="text" ng-keypress="CheckNumber()"/>
Inilah JS:
$scope.CheckKey = function () { if (isNaN(event.key) || event.key === ' ' || event.key === '') { event.returnValue = ''; } };
Cukup sederhana.
Saya percaya ini tidak akan berhasil pada Tempel, asal diketahui saja.
Untuk Tempel, saya pikir Anda perlu menggunakan acara onChange dan mengurai seluruh string, binatang buas lain yang tamme. Ini khusus untuk mengetik.
UPDATE untuk Tempel : cukup tambahkan fungsi JS ini:
$scope.CheckPaste = function () { var paste = event.clipboardData.getData('text'); if (isNaN(paste)) { event.preventDefault(); return false; } };
Dan input html menambahkan pemicu:
<input type="text" ng-paste="CheckPaste()"/>
Saya harap ini membantu o /
sumber
Berikut ini adalah Plunker yang menangani situasi apa pun di atas proposisi tidak menangani.
Dengan menggunakan $ formatters dan $ parsers pipeline dan menghindari type = "number"
Dan berikut penjelasan masalah / solusinya (juga tersedia di Plunker):
/* * * Limit input text for floating numbers. * It does not display characters and can limit the Float value to X numbers of integers and X numbers of decimals. * min and max attributes can be added. They can be Integers as well as Floating values. * * value needed | directive * ------------------------------------ * 55 | max-integer="2" * 55.55 | max-integer="4" decimal="2" (decimals are substracted from total length. Same logic as database NUMBER type) * * * Input type="number" (HTML5) * * Browser compatibility for input type="number" : * Chrome : - if first letter is a String : allows everything * - if first letter is a Integer : allows [0-9] and "." and "e" (exponential) * Firefox : allows everything * Internet Explorer : allows everything * * Why you should not use input type="number" : * When using input type="number" the $parser pipeline of ngModel controller won't be able to access NaN values. * For example : viewValue = '1e' -> $parsers parameter value = "". * This is because undefined values are not allowes by default (which can be changed, but better not do it) * This makes it impossible to modify the view and model value; to get the view value, pop last character, apply to the view and return to the model. * * About the ngModel controller pipelines : * view value -> $parsers -> model value * model value -> $formatters -> view value * * About the $parsers pipeline : * It is an array of functions executed in ascending order. * When used with input type="number" : * This array has 2 default functions, one of them transforms the datatype of the value from String to Number. * To be able to change the value easier (substring), it is better to have access to a String rather than a Number. * To access a String, the custom function added to the $parsers pipeline should be unshifted rather than pushed. * Unshift gives the closest access to the view. * * About the $formatters pipeline : * It is executed in descending order * When used with input type="number" * Default function transforms the value datatype from Number to String. * To access a String, push to this pipeline. (push brings the function closest to the view value) * * The flow : * When changing ngModel where the directive stands : (In this case only the view has to be changed. $parsers returns the changed model) * -When the value do not has to be modified : * $parsers -> $render(); * -When the value has to be modified : * $parsers(view value) --(does view needs to be changed?) -> $render(); * | | * | $setViewValue(changedViewValue) * | | * --<-------<---------<--------<------ * * When changing ngModel where the directive does not stand : * - When the value does not has to be modified : * -$formatters(model value)-->-- view value * -When the value has to be changed * -$formatters(model vale)-->--(does the value has to be modified) -- (when loop $parsers loop is finished, return modified value)-->view value * | * $setViewValue(notChangedValue) giving back the non changed value allows the $parsers handle the 'bad' value * | and avoids it to think the value did not changed * Changed the model <----(the above $parsers loop occurs) * */
sumber
<input type="text" name="profileChildCount" id="profileChildCount" ng-model="profile.ChildCount" numeric-only maxlength="1" />
Anda dapat menggunakan atribut khusus numerik.
sumber
DESIMAL
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); } }; });
Digit
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); } }; });
arahan sudut untuk memvalidasi nomor
sumber
Saya tahu ini sudah tua, tetapi saya telah membuat arahan untuk tujuan ini jika ada yang mencari solusi yang mudah. Sangat mudah digunakan.
Anda bisa memeriksanya di sini .
sumber
Anda mungkin juga ingin menghapus 0 di awal masukan ... Saya cukup menambahkan blok if ke jawaban Mordred di atas karena saya belum bisa memberikan komentar ...
app.directive('numericOnly', function() { return { require: 'ngModel', link: function(scope, element, attrs, modelCtrl) { modelCtrl.$parsers.push(function (inputValue) { var transformedInput = inputValue ? inputValue.replace(/[^\d.-]/g,'') : null; if (transformedInput!=inputValue) { modelCtrl.$setViewValue(transformedInput); modelCtrl.$render(); } //clear beginning 0 if(transformedInput == 0){ modelCtrl.$setViewValue(null); modelCtrl.$render(); } return transformedInput; }); } }; })
sumber
Coba ini,
<input ng-keypress="validation($event)"> function validation(event) { var theEvent = event || window.event; var key = theEvent.keyCode || theEvent.which; key = String.fromCharCode(key); var regex = /[0-9]|\./; if (!regex.test(key)) { theEvent.returnValue = false; if (theEvent.preventDefault) theEvent.preventDefault(); } }
sumber
SOLUSI: Saya membuat arahan untuk semua input, angka, teks, atau apa pun, di aplikasi, sehingga Anda dapat memasukkan nilai dan mengubah acara. Buatlah sudut 6
import { Directive, ElementRef, HostListener, Input } from '@angular/core'; @Directive({ // tslint:disable-next-line:directive-selector selector: 'input[inputType]' }) export class InputTypeDirective { constructor(private _el: ElementRef) {} @Input() inputType: string; // tipos: number, letter, cuit, tel @HostListener('input', ['$event']) onInputChange(event) { if (!event.data) { return; } switch (this.inputType) { case 'number': { const initalValue = this._el.nativeElement.value; this._el.nativeElement.value = initalValue.replace(/[^0-9]*/g, ''); if (initalValue !== this._el.nativeElement.value) { event.stopPropagation(); } break; } case 'text': { const result = event.data.match(/[^a-zA-Z Ññ]*/g); if (result[0] !== '') { const initalValue = this._el.nativeElement.value; this._el.nativeElement.value = initalValue.replace( /[^a-zA-Z Ññ]*/g, '' ); event.stopPropagation(); } break; } case 'tel': case 'cuit': { const initalValue = this._el.nativeElement.value; this._el.nativeElement.value = initalValue.replace(/[^0-9-]*/g, ''); if (initalValue !== this._el.nativeElement.value) { event.stopPropagation(); } } } } }
HTML
<input matInput inputType="number" [formControlName]="field.name" [maxlength]="field.length" [placeholder]="field.label | translate" type="text" class="filter-input">
sumber
Saya akhirnya membuat arahan yang dimodifikasi dari kode di atas untuk menerima input dan mengubah format dengan cepat ...
.directive('numericOnly', function($filter) { return { require: 'ngModel', link: function(scope, element, attrs, modelCtrl) { element.bind('keyup', function (inputValue, e) { var strinput = modelCtrl.$$rawModelValue; //filter user input var transformedInput = strinput ? strinput.replace(/[^,\d.-]/g,'') : null; //remove trailing 0 if(transformedInput.charAt(0) <= '0'){ transformedInput = null; modelCtrl.$setViewValue(transformedInput); modelCtrl.$render(); }else{ var decimalSplit = transformedInput.split(".") var intPart = decimalSplit[0]; var decPart = decimalSplit[1]; //remove previously formated number intPart = intPart.replace(/,/g, ""); //split whole number into array of 3 digits if(intPart.length > 3){ var intDiv = Math.floor(intPart.length / 3); var strfraction = []; var i = intDiv, j = 3; while(intDiv > 0){ strfraction[intDiv] = intPart.slice(intPart.length-j,intPart.length - (j - 3)); j=j+3; intDiv--; } var k = j-3; if((intPart.length-k) > 0){ strfraction[0] = intPart.slice(0,intPart.length-k); } } //join arrays if(strfraction == undefined){ return;} var currencyformat = strfraction.join(','); //check for leading comma if(currencyformat.charAt(0)==','){ currencyformat = currencyformat.slice(1); } if(decPart == undefined){ modelCtrl.$setViewValue(currencyformat); modelCtrl.$render(); return; }else{ currencyformat = currencyformat + "." + decPart.slice(0,2); modelCtrl.$setViewValue(currencyformat); modelCtrl.$render(); } } }); } };
})
sumber
<input type="text" ng-model="employee.age" valid-input input-pattern="[^0-9]+" placeholder="Enter an age" /> <script> var app = angular.module('app', []); app.controller('dataCtrl', 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(); } }); } }}); </script>
sumber
HTML dasar
<input type="number" />
Bootstrap dasar
<input class="form-control" type="number" value="42" id="my-id">
sumber
<input class="form-control" type="number" >