¿Cómo autocapitalizar el primer carácter en un campo de entrada en AngularJS?

¿Cómo autocapitalizar el primer carácter en un campo de entrada dentro de un elemento de formulario AngularJS?

Ya vi la solución jQuery, pero creo que esto debe hacerse de manera diferente en AngularJS mediante el uso de una directiva.

Sí, necesita definir una directiva y definir su propia función de analizador:

myApp.directive('capitalizeFirst', function($parse) { return { require: 'ngModel', link: function(scope, element, attrs, modelCtrl) { var capitalize = function(inputValue) { if (inputValue === undefined) { inputValue = ''; } var capitalized = inputValue.charAt(0).toUpperCase() + inputValue.substring(1); if(capitalized !== inputValue) { modelCtrl.$setViewValue(capitalized); modelCtrl.$render(); } return capitalized; } modelCtrl.$parsers.push(capitalize); capitalize($parse(attrs.ngModel)(scope)); // capitalize initial value } }; }); 

HTML:

  

Violín

Recuerde que no todo necesita una solución Angular. Esto se ve mucho con la multitud jQuery; les gusta usar costosas funciones de jQuery para hacer cosas que son más simples o más fáciles de hacer con javascript puro.

Así que, si bien podría necesitar una función de capitalizar y las respuestas anteriores lo proporcionan, va a ser mucho más eficiente simplemente usar la regla css “text-transform: capitalize”

  {{key}} {{item}}  

Puede crear un filtro personalizado ‘capitalizar’ y aplicarlo a cualquier cadena que desee:

  
{{aString | capitalize}} !

Código JavaScript para filtro:

 var app = angular.module('myApp',[]); myApp.filter('capitalize', function() { return function(input, scope) { return input.substring(0,1).toUpperCase()+input.substring(1); } }); 

Use el CSS: primera clase de pseudo clase.

Debes poner todo en minúscula y luego aplicar la mayúscula solo a la primera letra

 p{ text-transform: lowercase; } p:first-letter{ text-transform: uppercase; } 

Aquí hay un ejemplo: http://jsfiddle.net/AlexCode/xu24h/

Modificó su código para capitalizar cada primer carácter de la palabra. Si le das ‘ john doe ‘, la salida es ‘ John Doe

 myApp.directive('capitalizeFirst', function() { return { require: 'ngModel', link: function(scope, element, attrs, modelCtrl) { var capitalize = function(inputValue) { var capitalized = inputValue.split(' ').reduce(function(prevValue, word){ return prevValue + word.substring(0, 1).toUpperCase() + word.substring(1) + ' '; }, ''); if(capitalized !== inputValue) { modelCtrl.$setViewValue(capitalized); modelCtrl.$render(); } return capitalized; } modelCtrl.$parsers.push(capitalize); capitalize(scope[attrs.ngModel]); // capitalize initial value } }; }); 

Yo preferiría un filtro y una directiva. Esto debería funcionar con el movimiento del cursor:

 app.filter('capitalizeFirst', function () { return function (input, scope) { var text = input.substring(0, 1).toUpperCase() + input.substring(1).toLowerCase(); return text; } }); app.directive('capitalizeFirst', ['$filter', function ($filter) { return { require: 'ngModel', link: function (scope, element, attrs, controller) { controller.$parsers.push(function (value) { var transformedInput = $filter('capitalizeFirst')(value); if (transformedInput !== value) { var el = element[0]; el.setSelectionRange(el.selectionStart, el.selectionEnd); controller.$setViewValue(transformedInput); controller.$render(); } return transformedInput; }); } }; }]); 

Aquí hay un violín

Para solucionar el problema del cursor (de donde es la solución de Mark Rajcok), puede almacenar el elemento [0] .selectionStart al principio de su método, y luego asegurarse de restablecer el elemento [0] .selectionStart y el elemento [0] .selectionEnd al almacenado valor antes del regreso. Esto debería capturar su rango de selección en angular

Comentario a la solución de Mark Rajcok: al usar $ setViewValue, activa de nuevo los analizadores y validadores. Si agrega una instrucción console.log al comienzo de su función de capitalizar, la verá impresa dos veces.

Propongo la siguiente solución directiva (donde ngModel es opcional):

 .directive('capitalize', function() { return { restrict: 'A', require: '?ngModel', link: function(scope, element, attrs, ngModel) { var capitalize = function (inputValue) { return (inputValue || '').toUpperCase(); } if(ngModel) { ngModel.$formatters.push(capitalize); ngModel._$setViewValue = ngModel.$setViewValue; ngModel.$setViewValue = function(val){ ngModel._$setViewValue(capitalize(val)); ngModel.$render(); }; }else { element.val(capitalize(element.val())); element.on("keypress keyup", function(){ scope.$evalAsync(function(){ element.val(capitalize(element.val())); }); }); } } }; }); 

Aquí hay un codepen para un filtro que escribe en mayúscula la primera letra: http://codepen.io/WinterJoey/pen/sfFaK

 angular.module('CustomFilter', []). filter('capitalize', function() { return function(input, all) { return (!!input) ? input.replace(/([^\W_]+[^\s-]*) */g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}) : ''; } }); 

Además de las respuestas exclusivas de CSS, siempre puedes usar Twitter Bootstrap :

  

Construyendo la solución de Mark Rajcok; Es importante considerar que la directiva solo evalúa cuando el campo de entrada está activado, de lo contrario, los mensajes de error se dispararán hasta que el campo de entrada tenga un 1er carácter. Solución fácil con algunos condicionales: un jsfiddle para ir con eso: https://jsfiddle.net/Ely_Liberov/Lze14z4g/2/

  .directive('capitalizeFirst', function(uppercaseFilter, $parse) { return { require: 'ngModel', link: function(scope, element, attrs, modelCtrl) { var capitalize = function(inputValue) { if (inputValue != null) { var capitalized = inputValue.charAt(0).toUpperCase() + inputValue.substring(1); if (capitalized !== inputValue) { modelCtrl.$setViewValue(capitalized); modelCtrl.$render(); } return capitalized; } }; var model = $parse(attrs.ngModel); modelCtrl.$parsers.push(capitalize); capitalize(model(scope)); } }; }); 

El problema con las respuestas css-ony es que el modelo angular no se actualiza con la vista. Esto se debe a que css solo aplica el estilo después del renderizado.

La siguiente directiva actualiza el modelo Y recuerda la ubicación de los cursores

 app.module.directive('myCapitalize', [ function () { 'use strict'; return { require: 'ngModel', restrict: "A", link: function (scope, elem, attrs, modelCtrl) { /* Watch the model value using a function */ scope.$watch(function () { return modelCtrl.$modelValue; }, function (value) { /** * Skip capitalize when: * - the value is not defined. * - the value is already capitalized. */ if (!isDefined(value) || isUpperCase(value)) { return; } /* Save selection position */ var start = elem[0].selectionStart; var end = elem[0].selectionEnd; /* uppercase the value */ value = value.toUpperCase(); /* set the new value in the modelControl */ modelCtrl.$setViewValue(value); /* update the view */ modelCtrl.$render(); /* Reset the position of the cursor */ elem[0].setSelectionRange(start, end); }); /** * Check if the string is defined, not null (in case of java object usage) and has a length. * @param str {string} The string to check * @return {boolean} true when the string is defined */ function isDefined(str) { return angular.isDefined(str) && str !== null && str.length > 0; } /** * Check if a string is upper case * @param str {string} The string to check * @return {boolean} true when the string is upper case */ function isUpperCase(str) { return str === str.toUpperCase(); } } }; }]); 

Puede usar el filtro en mayúsculas proporcionado.

http://docs.angularjs.org/api/ng.filter:uppercase

Puedes usar pure css:

input { text-transform: capitalize; }