AngularJS强制文本框内字母大写

71

我尝试过使用大写过滤器,但它不起作用。我已经尝试了两种方式:

<input type="text" ng-model="test" uppercase/>

<input type="text" ng-model="{{test | uppercase}}"/>

第二个触发JavaScript错误:

语法错误:令牌“test”不是预期的,需要[:]

我希望在用户输入文本框时将文本强制转换为大写。

我该如何做到这一点?

14个回答

107

请看下面的答案,那个更好一些。

这个答案是基于这里的答案:如何在AngularJS中自动大写输入字段的第一个字符?

我想你需要一个像这样的解析器函数:

angular
  .module('myApp', [])
  .directive('capitalize', function() {
    return {
      require: 'ngModel',
      link: function(scope, element, attrs, modelCtrl) {
        var capitalize = function(inputValue) {
          if (inputValue == undefined) inputValue = '';
          var capitalized = inputValue.toUpperCase();
          if (capitalized !== inputValue) {
            // see where the cursor is before the update so that we can set it back
            var selection = element[0].selectionStart;
            modelCtrl.$setViewValue(capitalized);
            modelCtrl.$render();
            // set back the cursor after rendering
            element[0].selectionStart = selection;
            element[0].selectionEnd = selection;
          }
          return capitalized;
        }
        modelCtrl.$parsers.push(capitalize);
        capitalize(scope[attrs.ngModel]); // capitalize initial value
      }
    };
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp">
  <input type="text" ng-model="name" capitalize>
</div>


太好了,这正是我需要的。我之前没有看到这个例子。我觉得大写过滤器有点误导我了...谢谢! - Sam
4
这是一个很实用的指令!在调用inputValue的方法之前,检查其是否存在可能会有所帮助。 - Matt Jensen
3
除了将 push(首字母大写) 更改为 unshift(首字母大写)之外,其他都正常工作。谢谢。 - Christophe Geers
+1 我卡了一个多小时,试图弄清楚为什么$parsers$formatters没有更新输入控件。添加调用$setViewValue$render解决了问题。我将要求Angular团队将此添加到文档中。 - Reactgular
10
你可以在渲染前存储输入框的selectionStart,然后在渲染后重置,这样每次按键后光标就不会跳到字符串末尾。modelCtrl.$setViewValue(capitalized); modelCtrl.$render(); element[0].selectionStart = selection; element[0].selectionEnd = selection; - rucsi
显示剩余3条评论

68

如果有人尝试在现有字符串开头输入小写字母,则被接受的答案会引起问题。每次按键后,光标都会移动到字符串的末尾。以下是一个简单的解决方案,可以解决所有问题:

directive('uppercased', function() {
    return {
        require: 'ngModel',
        link: function(scope, element, attrs, modelCtrl) {
            modelCtrl.$parsers.push(function(input) {
                return input ? input.toUpperCase() : "";
            });
            element.css("text-transform","uppercase");
        }
    };
})

这里是一个代码小样例: http://jsfiddle.net/36qp9ekL/1710/


4
需要翻译的内容:不过需要注意的是,CSS中的text-transform属性只会将屏幕上显示的文本转换为大写,但与模型绑定的值并没有改变。虽然被接受的答案可能会产生其他意想不到的后果(比如光标跳到末尾),但这个解决方案也可能会根据需求产生类似的问题。 - Mattygabe
3
模型绑定的值由解析器转换为大写字母。或者你是指 input 元素的 value 属性吗?如果是的话,你说得对。 - Karen Zilles
1
啊 - 我并不是特别指向那个,而且不知怎么错过了解析器部分。我有点匆忙地浏览了你的例子,我的注意力立刻集中在应用于元素的文本转换上。我会自己打一下手,因为我只是匆匆浏览而不是仔细阅读 :) - Mattygabe
谢谢。唯一的不便之处是,如果有占位符,它也将是大写字母。 - pgrodrigues
3
请参考这个答案,以保留占位符不变。 - Jaydo
显示剩余5条评论

35

这个想法是在客户端以大写形式显示(而不是转换)字符串,并在服务器端将其转换为大写形式(用户始终可以控制客户端发生的情况)。因此:

1)在 HTML 中:

<input id="test" type="text" ng-model="test">

不进行大写转换。

2) 在css中:

#test {text-transform: uppercase;}

数据显示为大写,但实际上仍然是小写,如果用户键入小写,则如此。 3) 在插入数据库时将字符串转换为大写。

= = = = = 为了玩弄,可以尝试以下操作:

<input type="text" ng-model="test" ng-change="test=test.toUpperCase();">
<input type="text" ng-model="test" ng-blur="test=test.toUpperCase();">

但我认为在您的情况下,ng-change或ng-blur方式并不必要。


现在它可以工作了,而且非常简单!这是最好的事情!:) 谢谢 P.S 我也使用了 ng-keydown 来确保用户尽早看到这个魔法 :) - BlackBurn027

31

由于ng-model必须是可分配的,因此无法对其进行过滤。解决方法要么是使用解析器,要么就是使用ng-change。

<input ng-model="some" ng-change="some = (some | uppercase)"  />

这应该可以运行。


2
完美运行 - Milo Cabs
迄今为止对我来说是最好的解决方案! - coderpc
我会选择这个作为解决方案。简单且值传递到后端也是大写的。 - Sh4m

17

使用Bootstrap时,只需将text-uppercase 添加到输入框的class属性中即可。


1
你可以添加以下内容:::-webkit-input-placeholder { text-transform: none; } ::-moz-placeholder { text-transform: none; } :-ms-input-placeholder { text-transform: none; } input:-moz-placeholder { text-transform: none; }。如果需要,将.text-uppercase添加到这些类中。 - Ludovic Guillaume
它在用户界面上运行良好,但模型值仍为小写。 - Diego
1
如果您想将模型更改为大写,您需要使用模型控制器的 $parsers,就像上面所解释的那样。这个解决方案仅限于视觉效果。 - Ludovic Guillaume
你可以使用Bootstrap类来实现视觉效果,在控制器中,在使用模型之前使用toUpperCase()函数。 - Emmanuel P.

6
one of the simple way is,
<input type="text" ng-model="test" ng-change="upper(test)/>

just do below 2 line code in your js file,
$scope.upper = function(test){
$scope.test = test.toUpperCase();
}

这是我的代码片段 http://jsfiddle.net/mzmmohideen/36qp9ekL/299/

。它涉及到IT技术。


这个解决方案非常棒 - 只需要几行代码。但它似乎取消了我使用正则表达式验证MAC地址的ng-pattern。你有什么办法让两者都能正常工作吗?https://jsfiddle.net/630dkL15/ - SpaceNinja
我不太明白你的问题... 你的输入是大写的,然后你要和mac_regex进行比较,是吗?在你的jsfiddle中发现了一个外部链接,它描述了绑定时给定文本的大写形式,而不是ng-model或运行时输入。这将适用于Angular输出,其中会在{{}}中进行绑定。 - Mohideen bin Mohammed
1
这是我的JSFIDDLE链接:https://jsfiddle.net/mzmmohideen/oqzs0w8m/。在这里,当您正确输入MAC地址时,它会显示正确,否则它将返回false。不用担心大小写问题,当您正确输入MAC地址后,它会自动转换为大写字母。 - Mohideen bin Mohammed
@SpaceNinja,你得到你想要的了吗? - Mohideen bin Mohammed
我喜欢你的解决方案,如果我找不到一个在用户输入时能够把AS大写的解决方案而不是最后验证时才大写的方案,我可能会使用它。我希望看到ng-pattern和ng-change之间冲突的问题在哪里 - http://jsfiddle.net/rod9pLom/3/ - SpaceNinja

2

这样做完全行不通。

ng-model 用于指定将从作用域中绑定到模型的字段/属性。此外,ng-model 不接受表达式作为值。在 angular.js 中,表达式是指 {{}} 之间的内容。

可以在输出中和所有允许使用表达式的地方使用 uppercase 过滤器。

无法实现您想要的操作,但您可以使用 CSS 的 text-transform 至少将所有内容显示为大写。

如果您想要文本字段的值为大写字母,则可以使用一些自定义 JavaScript 实现此目的。

在您的控制器中:

$scope.$watch('test', function(newValue, oldValue) {
  $scope.$apply(function() {
    $scope.test = newValue.toUpperCase();
  }
});

好的回答,但我会选择 GHC 的,因为它更接近我想要的(在视图中使用属性)。 - Sam

2

不要忘记在你的模块中包含 'ngSanitize'!

app.directive('capitalize', function() {
    return {
        restrict: 'A', // only activate on element attribute
        require: '?ngModel',
        link : function(scope, element, attrs, modelCtrl) {
            var capitalize = function(inputValue) {
                if(inputValue) {
                    var capitalized = inputValue.toUpperCase();
                    if (capitalized !== inputValue) {
                        modelCtrl.$setViewValue(capitalized);
                        modelCtrl.$render();
                    }
                    return capitalized;
                }
            };
            modelCtrl.$parsers.push(capitalize);
            capitalize(scope[attrs.ngModel]); // capitalize initial value
        }
    };

});

  • 请注意 "require: '?ngModel'," 中的 "?",只有这样我的应用程序才能正常工作。

  • "if(inputValue) {...}" 以避免未定义错误的发生


1

使用Bootstrap时:

第一种方法:使用class text-uppercase

<input  type="text" class="text-uppercase" >

第二种方法:使用可以应用于现有类的样式
<input  type="text" class="form-control" style="text-transform: uppercase;">

这是我的 StackBlitz:https://angular-nvd7v6forceuppercase.stackblitz.io


0

解决光标偏移问题的解决方案

.directive('titleCase', function () {
        return {
            restrict: 'A',
            require: 'ngModel',
            link: function (scope, element, attrs, modelCtrl) {
                var titleCase = function (input) {
                    let first = element[0].selectionStart;
                    let last = element[0].selectionEnd;
                    input = input || '';
                    let retInput = input.replace(/\w\S*/g, function (txt) { return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); });
                    if (input !== retInput) {
                        modelCtrl.$setViewValue(retInput);
                        attrs.ngModel = retInput;
                        modelCtrl.$render();
                        if (!scope.$$phase) {
                            scope.$apply(); // launch digest;
                        }
                    }
                    element[0].selectionStart = first;
                    element[0].selectionEnd = last;
                    return retInput;
                };
                modelCtrl.$parsers.push(titleCase);
                titleCase(scope[attrs.ngModel]);  // Title case  initial value
            }
        };
    });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接