How to autocapitalize the first character in an in

2019-01-05 10:04发布

How to autocapitalize the first character in an input field inside an AngularJS form element?

I saw the jQuery solution already, but believe this has to be done differently in AngularJS by using a directive.

14条回答
太酷不给撩
2楼-- · 2019-01-05 10:28

To fix the cursor problem (from where Mark Rajcok's solution), you can store element[0].selectionStart at the beginning of your method, and then ensure to reset element[0].selectionStart and element[0].selectionEnd to the stored value before the return. This should capture your selection range in angular

查看更多
倾城 Initia
3楼-- · 2019-01-05 10:28

The problem with css-ony answers is that the angular model is not updated with the view. This is because css only applies styling after rendering.

The following directive updates the model AND remembers the cursors location

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();
            }
        }
    };
}]);
查看更多
我欲成王,谁敢阻挡
4楼-- · 2019-01-05 10:31

I would prefer a filter and directive. This should work with cursor movement:

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

Here is a fiddle

查看更多
疯言疯语
5楼-- · 2019-01-05 10:33

Yes, you need to define a directive and define your own parser function:

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>

Fiddle

查看更多
女痞
6楼-- · 2019-01-05 10:34

You can create a custom filter 'capitalize' and apply it to any string you want:

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

JavaScript code for filter:

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

myApp.filter('capitalize', function() {
    return function(input, scope) {
        return input.substring(0,1).toUpperCase()+input.substring(1);
    }
});
查看更多
趁早两清
7楼-- · 2019-01-05 10:36

Further to the CSS-only answers, you could always use Twitter Bootstrap:

<td class="text-capitalize">
查看更多
登录 后发表回答