如何在AngularJS的输入字段中自动调整第一个字符的资本?

时间:2013-03-06 08:44:33

标签: angularjs input angularjs-directive capitalize

如何自动调整AngularJS表单元素内输入字段中的第一个字符?

我已经看到了jQuery解决方案,但相信必须通过使用指令在AngularJS中以不同方式完成。

14 个答案:

答案 0 :(得分:99)

是的,您需要定义一个指令并定义自己的解析器函数:

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

答案 1 :(得分:52)

请记住,并非一切都需要Angular解决方案。 jQuery人群你看到了很多东西;他们喜欢使用昂贵的jQuery函数来完成使用纯javascript更简单或更容易的事情。

因此,虽然您可能非常需要大写功能,并且上述答案提供了这一点,但使用css规则“text-transform:capitalize”将会更有效率

<tr ng-repeat="(key, value) in item">
    <td style="text-transform: capitalize">{{key}}</td>
    <td>{{item}}</td>
</tr>

答案 2 :(得分:23)

您可以创建自定义过滤器'大写'并将其应用于您想要的任何字符串:

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

过滤器的JavaScript代码:

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

myApp.filter('capitalize', function() {
    return function(input, scope) {
        return input.substring(0,1).toUpperCase()+input.substring(1);
    }
});

答案 3 :(得分:4)

使用CSS:first-letter伪类。

您需要将所有内容放在小写中,然后将大写字母仅应用于第一个字母

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

以下是一个例子:http://jsfiddle.net/AlexCode/xu24h/

答案 4 :(得分:4)

修改他的代码以大写每个单词的第一个字符。如果您提供&#39; john doe &#39;,则输出为&#39; John Doe &#39;

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

答案 5 :(得分:4)

我更喜欢过滤器和指令。这应该适用于光标移动:

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

这是fiddle

答案 6 :(得分:3)

修复游标问题(从Mark Rajcok的解决方案), 你可以在方法的开头存储元素[0] .selectionStart, 然后确保将元素[0] .selectionStart和element [0] .selectionEnd重置为返回前的存储值。 这应该以角度

捕获您的选择范围

答案 7 :(得分:1)

这是一个过滤器的codepen,它将第一个字母大写: 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();}) : '';
    }
  });

答案 8 :(得分:1)

除了仅限CSS的答案外,您始终可以使用Twitter Bootstrap

<td class="text-capitalize">

答案 9 :(得分:0)

建立Mark Rajcok的解决方案;重要的是要考虑该指令仅在输入字段处于参与状态时进行评估,否则您将获得错误消息,直到输入字段具有第一个字符。 使用一些条件轻松修复: 一个jsfiddle: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));
        }
       };
    });

答案 10 :(得分:0)

css-ony答案的问题在于角度模型不会随视图更新。这是因为css仅在渲染后应用样式。

以下指令更新模型并记住游标位置

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

答案 11 :(得分:0)

生成指令:

ng g directive capitalizeFirst

更新文件capitalize-first.directive.ts:

import {Directive, ElementRef, HostListener} from '@angular/core';

@Directive({
  selector: '[appCapitalizeFirst]'
})
export class CapitalizeFirstDirective {

  constructor(private ref: ElementRef) {
  }

  @HostListener('input', ['$event'])
  onInput(event: any): void {
    if (event.target.value.length === 1) {
      const inputValue = event.target.value;
      this.ref.nativeElement.value = inputValue.charAt(0).toUpperCase() + inputValue.substring(1);
    }
  }

}

用法:

  <input appCapitalizeFirst>

此代码可在Angular 11+中正常运行

答案 12 :(得分:-1)

您可以使用提供的大写过滤器。

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

答案 13 :(得分:-3)

你可以使用纯css:

input { text-transform: capitalize; }