AngularJSフォーム要素内の入力フィールドの最初の文字を自動大文字化する方法は?
JQueryソリューションはすでに見ましたが、AngularJSではディレクティブを使用してこれを別の方法で行う必要があると考えています。
はい、ディレクティブを定義し、独自のパーサー関数を定義する必要があります。
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>
すべてがAngularソリューションを必要とするわけではないことを覚えておいてください。jQuery群衆はこれをよく見かけます。
したがって、大文字化関数が非常に必要になる可能性がありますが、上記の答えはそれを提供しますが、cssルール「text-transform:capitalize」を使用する方がはるかに効率的です
<tr ng-repeat="(key, value) in item">
<td style="text-transform: capitalize">{{key}}</td>
<td>{{item}}</td>
</tr>
カスタムフィルタ「capitalize」を作成し、必要な文字列に適用できます。
<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);
}
});
私はフィルターとディレクティブを好むでしょう。これはカーソルの動きで動作するはずです:
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;
});
}
};
}]);
Wordの最初の文字をすべて大文字にするようにコードを修正しました。 「john doe」を指定すると、出力は「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
}
};
});
CSS:first-letter擬似クラスを使用します。
すべて小文字にする必要があり、最初の文字にのみ大文字を適用する必要があります
p{
text-transform: lowercase;
}
p:first-letter{
text-transform: uppercase;
}
以下に例を示します。 http://jsfiddle.net/AlexCode/xu24h/
カーソルの問題(Mark Rajcokのソリューションの元)を修正するには、メソッドの最初にelement [0] .selectionStartを保存し、element [0] .selectionStartおよびelement [0] .selectionEndを保存されたものにリセットするようにします。戻る前の値。これは、選択範囲を角度でキャプチャする必要があります
Mark Rajcokソリューションへのコメント:$ setViewValueを使用する場合、パーサーとバリデーターを再度トリガーします。大文字化関数の先頭にconsole.logステートメントを追加すると、2回印刷されます。
次のディレクティブソリューションを提案します(ngModelはオプションです)。
.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()));
});
});
}
}
};
});
CSSのみの答えに加えて、常に Twitter Bootstrap を使用できます。
<td class="text-capitalize">
最初の文字を大文字にするフィルターのコードペンは次のとおりです。 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();}) : '';
}
});
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));
}
};
});
Css-onyの回答の問題は、angularモデルがビューで更新されないことです。これは、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();
}
}
};
}]);