angularjs force uppercase in textbox
Asked Answered
H

14

71

I've tried using the uppercase filter but it does not work. I've tried doing it two ways:

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

and

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

The 2nd triggers a javascript error:

Syntax Error: Token 'test' is unexpected, expecting [:]

I want the text to be forced to uppercase as the user types in the textbox.

How can I do that?

Hypochondriac answered 5/5, 2013 at 20:1 Comment(0)
A
107

Please see the other answer below, which is superior to this one.

this answer is based on the answer here: How to autocapitalize the first character in an input field in AngularJS?.

I'd imagine that what you'd want would be a parser function like this:

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>
Actinium answered 5/5, 2013 at 20:9 Comment(8)
perfect, that's what I needed. I didn't see this example. I think the uppercase filter was a bit mis-leading for me.... ThanksHypochondriac
This is a handy directive! It may be helpful if you tested for the existence of inputValue before calling a method on it however.Ow
Changed the push(capitalize) to unshift(capitalize), but other than that it worked fine. Thx.Laquanda
+1 I was stuck for over an hour trying to figure out why $parsers and $formatters were not updating the input control. Adding the calls to $setViewValue and $render did the trick. I'm going to ask the Angular team to add this to the docs.Borowski
you could store the selectionStart of the input before and reset after rendered, so the cursor would not move to the end of the string after each key press. var selection = element[0].selectionStart; modelCtrl.$setViewValue(capitalized); modelCtrl.$render(); element[0].selectionStart = selection; element[0].selectionEnd = selection; Handclasp
Add modelCtrl.$commitViewValue() after modelCtrl.$render(), because without doing this, a potential ng-pattern validation on the input will check the non-capitalized value. :)Gaylordgaylussac
Hi but this fails if you are editing the same field. for e.g. existing text in the field is East. I want to update as NorthEast. The time you enter N your cursor foucus shifts to the endDryad
This failed for input type = "email" as email input types does not support selection.Lobworm
P
68

The accepted answer causes problems if someone tries to enter a lowercase letter at the beginning of an existing string.. The cursor moves to the end of the string after each key press. Here's a simple solution that addresses all the issues:

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

Here's a fiddle: http://jsfiddle.net/36qp9ekL/1710/

Platinumblond answered 23/9, 2014 at 18:15 Comment(10)
Its to be noted however that the CSS text-transform merely makes the text on-screen uppercase, but the value bound to the model is not. While the accepted answer may have other unintended consequences (like the cursor bumping to the end), this one may too, depending on the requirements.Houghton
The value bound to the model is upper cased by the $parser. Or are you referring to the value attribute of the input element? In that case you are correct.Platinumblond
Ah - wasn't referring to that necessarily and missed the parser piece somehow. I kind of skimmed your example and my mind instantly focused on the text-transform being applied to the element. I'll smack my own hand for skimming instead of reading :)Houghton
Correct me if I'm wrong but I think $(element) and element are equivalent.Importunity
You are correct. I was thinking element was the unwrapped dom element, but it comes prewrapped. I've updated the code (and added a fiddle too).Platinumblond
Note that THIS ONE is uppercase -- This One is Title Case. lowerCamelCase. UpperCamelCase.Rahal
Hi, @Cody. What are you trying to note here? The question asks for uppercase and this directive provides uppercase.Platinumblond
Just contributing some context here as many times the semantics get a little butchered -- just adding it anecdotally for what its worth.Rahal
Thanks. The only inconvenient is that if there is a placeholder it will also be in uppercase.Aleida
See this answer to keep placeholder as isHescock
D
35

The idea is to show (not transform) the string as uppercase at client side and transform into uppercase at server side (users can always control what happens at client side). So:

1) in the html:

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

here no uppercase transformation.

2) in the css:

#test {text-transform: uppercase;}

data is shown as uppercase, but actually still lowercase, if user typed in lowercase. 3) turn the string into uppercase at server side when inserting into database.

= = = = = for playing around, can try follow:

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

but I think ng-change or ng-blur ways are not necessary for your case.

Douai answered 16/9, 2014 at 8:41 Comment(1)
Now this works and its simple! So that's the best thing! :) Thanks P.S i used ng-keydown as well to make sure user sees the magic sooner :)Deaminate
A
31

You cannot make filter on ng-model since it has to be assignable. the workaround is either parser, or simply ng-change.

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

This should work.

Artie answered 20/2, 2017 at 2:7 Comment(3)
Works perfectlyImp
Best solution for me so far!Corporeal
I would select this as a solution. Simple and value passed to backend also uppercase.Schedule
Z
17

When used with Bootstrap, just add text-uppercase to input's class attribute.

Zamboanga answered 2/1, 2015 at 10:51 Comment(4)
You can add this then : ::-webkit-input-placeholder { text-transform: none; } ::-moz-placeholder { text-transform: none; } :-ms-input-placeholder { text-transform: none; } input:-moz-placeholder { text-transform: none; }. Add .text-uppercase to this classes if needed.Zamboanga
It worked on the user interface, but the model value is still lowecaseDehumidify
If you want to change the model to uppercase, you will need to use model controller's $parsers like explained above. This solution is visual only.Zamboanga
You can use bootstrap class for visual purpose, and in your controller, using the toUperCase() function before using your modelCumulonimbus
W
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();
}

here is my fiddle http://jsfiddle.net/mzmmohideen/36qp9ekL/299/

Wandering answered 19/5, 2015 at 7:40 Comment(5)
This solution is wonderful - just the few lines that it needs. It does seem to cancel out my ng-pattern I am using to validate a MAC address using a regex. Any ideas on how I can get both to work? jsfiddle.net/630dkL15Brenza
I cant get your question... U got uppercase for your input and you going to compare it with mac_regex is it right? and in your jsfiddle found one external link, it describes about uppercase the given text while binding not for ng-model or run time inputs. that will work for angular output which will bind within it {{}}Wandering
jsfiddle.net/mzmmohideen/oqzs0w8m here is my JSFIDDLE , here when you enter mac address correctly means it shows correct else it return false and dont worry about lower case, when u entered mac correctly at the end it will become upper caseWandering
@Brenza did u got what you want?Wandering
I like your solution, I may use it if I cannot find a solution that capitalizes AS the user types instead of at the end when it finally does validation. I was hoping to see what the issue was with the conflict of ng-pattern and ng-change - jsfiddle.net/rod9pLom/3Brenza
K
2

This will not work at all.

ng-model is for specifying which field / property from the scope should be bound to the model. Also, ng-model does not accept an expression as value. Expressions in angular.js are things between {{ and }}.

The uppercase filter could used in the output and everywhere where expressions are allowed.

You cannot do what you want to do, but you could use CSS's text-transform to at least display everything in uppercase.

If you want to have the value of a text field in uppercase letters you can achieve this with some custom JavaScript.

In your controller:

$scope.$watch('test', function(newValue, oldValue) {
  $scope.$apply(function() {
    $scope.test = newValue.toUpperCase();
  }
});
Koehn answered 5/5, 2013 at 20:5 Comment(1)
good answer, I'll take GHC's though as it is closer to what I want (using an attribute in the view)Hypochondriac
H
2

Don't forget to include 'ngSanitize' in your module!

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

});

  • Pay attention to "?" in "require: '?ngModel',"... only then worked my application.

  • "if(inputValue) {...}" For no undefined error occurs

Hercule answered 30/7, 2014 at 21:29 Comment(0)
A
1

When using bootstrap:

First approach: Using class text-uppercase

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

Second approach: Using style which can be applied with existing class

<input  type="text" class="form-control" style="text-transform: uppercase;">

Here is my stackBlitz: https://angular-nvd7v6forceuppercase.stackblitz.io

Anesthesiology answered 17/4, 2019 at 9:1 Comment(0)
P
0

it is just an alternative , you can use this " text- transform : capitalize ; " in your css and the text entry will be capitalized. unless the user types it in capital letters everywhere.

it is just an alternative ^^

Politician answered 25/1, 2015 at 0:21 Comment(0)
D
0

To improve the answer by Karl Zilles this is my revision of his solution. In my version the placeholder isn't changed to uppercase and works also if you want to do a regex on the string. It also take the "type" of the input string (null or undefined or empty):

var REGEX = /^[a-z]+$/i;
myApp.directive('cf', function() {
    return {
        require: 'ngModel',
        link: function(scope, elm, attrs, ctrl) {
            ctrl.$validators.cf = function(modelValue, viewValue) {
            ctrl.$parsers.push(function(input) {
                elm.css("text-transform", (input) ? "uppercase" : "");
                return input ? input.toUpperCase() : input;
            });
            return (!(ctrl.$isEmpty(modelValue)) && (REGEX.test(viewValue)));
        }
    }
}
});
Duke answered 24/9, 2015 at 7:55 Comment(0)
D
0

Solution with cursor shift fix

.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
            }
        };
    });
Dryad answered 19/6, 2018 at 12:52 Comment(0)
U
0

If you want to change model and value, use:

angular.module('MyApp').directive('uppercased', function() {
    return {
        require: 'ngModel',
        link: function(scope, element, attrs, ngModel) {
            element.bind("blur change input", function () {
                ngModel.$setViewValue($(this).val().toUpperCase());
                $(this).val($(this).val().toUpperCase());
            });
            element.css("text-transform","uppercase");
        }
    };
});

Then add uppercased to your html input text

<input  type="text" uppercased />
Unashamed answered 2/6, 2020 at 1:49 Comment(0)
P
-1

I would just use the filter itself in the controller:

 $filter('uppercase')(this.yourProperty)

just keep in mind that, if you you are going to use it inside a controller, for example, you need to inject this filter:

app.controller('FooController', ['$filter', function($filter) ...
Percentile answered 4/11, 2015 at 22:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.