Comment autocapitaliser le premier caractère d'un champ input dans AngularJS?

comment autocapitaliser le premier caractère dans un champ d'entrée à l'intérieur d'un élément de forme AngularJS?

j'ai déjà vu la solution jQuery, mais je crois que cela doit être fait différemment à AngularJS en utilisant une directive.

51
demandé sur Paul Sweatte 2013-03-06 12:44:32

14 réponses

Oui, vous devez définir une directive et définir votre propre fonction d'analyseur:

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:

<input type="text" ng-model="obj.name" capitalize-first>

Violon

97
répondu Mark Rajcok 2016-04-11 20:07:23

n'oubliez pas que tout n'a pas besoin d'une solution angulaire. Vous voyez cela beaucoup avec la foule de jQuery; ils aiment utiliser des fonctions jQuery coûteuses pour faire des choses qui sont plus simples ou plus faciles à faire avec pur javascript.

donc, bien que vous pourriez très bien avoir besoin d'une fonction capitaliser et les réponses ci-dessus fournir que, il va être beaucoup plus efficace d'utiliser simplement la règle css "text-transform: capitaliser"

<tr ng-repeat="(key, value) in item">
    <td style="text-transform: capitalize">{{key}}</td>
    <td>{{item}}</td>
</tr>
52
répondu beardedlinuxgeek 2013-06-04 15:46:49

vous pouvez créer un filtre personnalisé 'capitaliser' et l'appliquer à n'importe quelle chaîne de caractères que vous voulez:

 <div ng-controller="MyCtrl">
     {{aString | capitalize}} !
</div>

code JavaScript pour filtre:

var app = angular.module('myApp',[]);

myApp.filter('capitalize', function() {
    return function(input, scope) {
        return input.substring(0,1).toUpperCase()+input.substring(1);
    }
});
23
répondu Yuriy Shapovalov 2013-03-06 09:03:23

utiliser la classe CSS :first-letter pseudo.

vous devez mettre tout en minuscules et après appliquer le majuscule seulement à la première lettre

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

voici un exemple: http://jsfiddle.net/AlexCode/xu24h /

4
répondu AlexCode 2014-03-21 14:09:44

a modifié son code pour capitaliser chaque premier caractère du mot. Si vous donnez ' John doe ', la sortie est ' 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
     }
   };
});
4
répondu Pradeep Mahdevu 2014-06-05 02:16:56

je préférerais un filtre et une directive. Cela devrait fonctionner avec le déplacement du curseur:

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

voici un violon

4
répondu Yoggi 2014-12-04 09:56:58

pour corriger le problème du curseur (d'où la solution de Mark Rajcok), vous pouvez stocker l'élément[0].selectionStart au début de votre méthode, et puis assurez-vous de réinitialiser élément[0].selectionStart et element[0].selectionEnd à la valeur stockée avant le retour. Cela devrait capturer votre gamme de sélection en angle

3
répondu Barbara Hamde 2013-12-18 20:59:09

commentaire à Mark Rajcok solution: en utilisant $setViewValue, vous déclenchez à nouveau les analyseurs et validateurs. Si vous ajoutez une console.l'instruction de journal au début de votre fonction capitaliser, vous le verrez imprimé Deux fois.

je propose la solution de directive suivante (où ngModel est facultatif):

.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()));
                 });
             });
         }
     }
   };
});
2
répondu marc carreras 2015-04-22 11:47:19

voici un codepen pour un filtre qui capitalise la première lettre: 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();}) : '';
    }
  });
1
répondu Federico 2014-09-06 19:44:07

suite aux réponses uniquement CSS, vous pouvez toujours utiliser Bootstrap Twitter :

<td class="text-capitalize">
1
répondu dmvianna 2015-06-26 05:37:29

Construit à partir de la solution de Mark Rajcok; il est important de considérer que la directive n'évalue que lorsque le champ d'entrée est engagé, sinon vous obtiendrez des messages d'erreur s'allumant jusqu'à ce que le champ d'entrée ait un 1er caractère. Facile à fixer avec quelques conditions: Un jsfiddle pour aller avec ça: 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));
        }
       };
    });
0
répondu Ely Liberov 2015-05-16 21:08:32

le problème avec les réponses css-ony est que le modèle angulaire n'est pas mis à jour avec la vue. Cela est dû au fait que css n'applique le style qu'après le rendu.

la directive suivante met à jour le modèle et se souvient de l'emplacement du cursors

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} <code>true</code> 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} <code>true</code> when the string is upper case
             */
            function isUpperCase(str) {
                return str === str.toUpperCase();
            }
        }
    };
}]);
0
répondu Marcel 2016-08-18 08:52:24

vous pouvez utiliser le filtre en majuscules fourni.

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

-1
répondu Gregor 2013-03-06 08:47:02

vous pouvez utiliser CSS pur:

input { text-transform: capitalize; }

-3
répondu JSHowTo 2013-08-20 20:31:39