2017-04-17 更新

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」を返すようにしています。

この対応が正しいかどうかはわかりませんし、他に方法がありそうな気もしますが、上記の対応で今のところ問題は出ていません。


参考リンク

Cordova】関連記事