validar validacion vacios solo pattern numeros letras formularios formulario espacios ejemplos con campos javascript angularjs angularjs-directive

validacion - validar formulario javascript onclick



¿Cómo restrinjo una entrada para solo aceptar números? (14)

Estoy usando ngChange en AngularJS para activar una función personalizada que eliminará cualquier letra que el usuario agregue a la entrada.

<input type="text" name="inputName" data-ng-change="numbersOnly()"/>

El problema es que tengo que apuntar a la entrada que activó numbersOnly() para poder eliminar las letras ingresadas. He buscado mucho en Google y no he podido encontrar nada al respecto.

¿Que puedo hacer?


Aquí está mi implementación de la solución $parser que @Mark Rajcok recomienda como el mejor método. Es esencialmente el https://.com/a/14425022/215945 @ pkozlowski.opensource https://.com/a/14425022/215945 pero reescrito para permitir solo los números. Todo el mérito recae en él, esto es solo para ahorrarle los 5 minutos de leer esa respuesta y luego volver a escribir la suya:

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; }); } }; });

Y lo usarías así:

<input type="text" name="number" ng-model="num_things" numeric-only>

Curiosamente, los espacios nunca llegan al analizador a menos que estén rodeados por un alfanumérico, por lo que tendrías que .trim() según sea necesario. Además, este analizador NO funciona en <input type="number"> . Por alguna razón, los elementos no numéricos nunca llegan al analizador donde serían eliminados, pero sí lo hacen en el control de entrada.


Aquí hay un Plunker manejando cualquier situación arriba de la proposición.
Utilizando $ formateadores y $ analizadores de canalización y evitando type = "number"

Y aquí está la explicación de problemas / soluciones (también disponible en 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) * */


Aquí hay una solución bastante buena para que solo permita ingresar el número a la input :

<input type="text" ng-model="myText" name="inputName" onkeypress=''return event.charCode >= 48 && event.charCode <= 57''/>


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); } }; });

DÍGITOS

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); } }; });

directivas angulares para validar números


Hay algunas maneras de hacer esto.

Podría usar type="number" :

<input type="number" />

Alternativamente, creé una directive reutilizable para esto que usa una expresión regular.

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; } }); } }; }]); }());


Manera HTML básica y limpia

<input type="number" />


Ninguna de las soluciones propuestas funcionó bien para mí, y después de un par de horas finalmente encontré el camino.

Esta es la directiva angular:

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(); } }); } } });

Y la entrada se vería así:

<input type="number" min="0" name="inputName" ng-model="myModel" restrict-to="[0-9]">

La expresión regular evalúa la tecla presionada, no el valor .

También funciona perfectamente con las entradas type="number" porque evita cambiar su valor, por lo que la clave nunca se muestra y no se mezcla con el modelo.


Sé que esto es viejo, pero he creado una directiva para este propósito en caso de que alguien esté buscando una solución fácil. Muy simple de usar

Puedes consultarlo here .


Terminé creando una directiva modificada del código anterior para aceptar la entrada y cambiar el formato sobre la marcha ...

.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(); } } }); } };

})


Usando ng-pattern en el campo de texto:

<input type="text" ng-model="myText" name="inputName" ng-pattern="onlyNumbers">

Luego incluye esto en tu controlador

$scope.onlyNumbers = /^/d+$/;


es posible que también desee eliminar el 0 al principio de la entrada ... Simplemente agrego un bloque if a la respuesta anterior de Mordred porque aún no puedo hacer un comentario ...

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; }); } }; })


Manera fácil , utilice type="number" si funciona para su caso de uso:

<input type="number" ng-model="myText" name="inputName">

Otra manera fácil: type="number" también se puede usar para definir una expresión regular que limitará lo que está permitido en el campo. Consulte también la página "libro de recetas" sobre formularios .

Hackish? manera , $ mira el ng-modelo en su controlador:

<input type="text" ng-model="myText" name="inputName">

Controlador:

$scope.$watch(''myText'', function() { // put numbersOnly() logic here, e.g.: if ($scope.myText ... regex to look for ... ) { // strip out the non-numbers } })

Mejor manera , use un $ analizador en una directiva. No voy a repetir la buena respuesta proporcionada por @ pkozlowski.opensource, así que aquí está el enlace: https://.com/a/14425022/215945

Todas las soluciones anteriores implican el uso de ng-model, lo que hace que encontrar this innecesario.

Usar ng-change causará problemas. Ver AngularJS - el restablecimiento de $ scope.value no cambia el valor en la plantilla (comportamiento aleatorio)


<input type="text" name="profileChildCount" id="profileChildCount" ng-model="profile.ChildCount" numeric-only maxlength="1" />

puedes usar el atributo de solo numérico.


<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>