textareaで改行を含んだ入力文字数をカウントする方法
textareaの入力中に入力できる残りの文字数を表示しようとしたのですが、改行を含めた文字列を入力すると、「maxlength」と「.length」でカウントされる文字数に差異があって上手くいかなかったので、その時に対応した内容になります。
目次
- 問題のあったコード
- 対応したコード
- 参考リンク
問題のあったコード
調べていくと、どうやらHTMLレンダリングエンジン「Webkit」を利用している場合に起こる問題のようで、「maxlength」と「.length」でカウントされる改行の文字数が2文字と1文字で異なっているのが原因のようでした。
CordovaではAndroidでもiOSでもこのWebkitを使ってレンダリングしているので、textareaを使う場合、ちょっと注意が必要そうです。
HTML
<textarea ng-model="message" maxlength="100" ng-trim="false"></textarea>
あと<span ng-bind="countInputStr(message, 100)"></span>文字
JavaScript
$scope.countInputStr = function (input, maxlength) {
return maxlength - input.length;
}
上記のコードの場合、文中に改行が入力されると「あと0文字」になっていないのに、それ以上の入力ができないといった動作になってしまいます。
ちなみにHTMLのコードで ng-trim="false" としている理由は、「maxlength」がtrimしていない文字数をカウントしているためです。本当はtrimした上でやりたかったのですが、maxlengthの調整方法がわからなかった(できない?)ので、そこは断念しました。
対応したコード
$scope.countInputStr = function (input, maxlength) {
if (input == null) {
return 0;
} else if (input.length == 0) {
return maxlength;
} else {
input = input.replace(/\\n|\r\n|\n\r|\r|\n/g, "\r\n");
var inputLen = maxlength - input.length;
return inputLen >= 0 ? inputLen : 0;
}
}
上記は、改行コードを「.length」で2文字換算となるように「\r\n」に置換しています。(「\r\n」としていますが、文字数カウント用なので半角スペースでもなんでも2文字分あればいいです。)また、入力が確定する前は最大文字数を超える文字を入力可能なので、超えたら固定で「0」を返すようにしています。
この対応が正しいかどうかはわかりませんし、他に方法がありそうな気もしますが、上記の対応で今のところ問題は出ていません。