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.
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>
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>
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);
}
});
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 /
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
}
};
});
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
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
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()));
});
});
}
}
};
});
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();}) : '';
}
});
suite aux réponses uniquement CSS, vous pouvez toujours utiliser Bootstrap Twitter :
<td class="text-capitalize">
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));
}
};
});
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();
}
}
};
}]);
vous pouvez utiliser CSS pur:
input {
text-transform: capitalize;
}