jQueryを使ってtextarea要素の入力文字数を制限する

HTMLのformタグを使った入力フォームでは入力文字数に制限をかけたい時はjQueryを利用することで入力文字数に制限をかけることができます。

Twitterでも投稿に文字数制限があるため、制限を超える入力があると投稿できないように制御されているかと思います。
そんな感じで自分で構築するWebアプリケーションも入力文字数をコントロールしたいことはあるでしょう。

ここではjQueryを使ってユーザーからの入力テキストの文字数に制限をかける方法をご紹介します。


textareaの入力文字数の制限

入力文字数の制限にはtextareaにmaxlength属性を使って「maxlength=”50″」のように制御する方法もありますが、今回は入力した文字数をカウントして、そのカウントの数値で残りの文字数の表示と制限文字数を超えたときの動作の制御をする流れで作ってみます。

formタグのaction属性はお問い合わせやアンケートフォームのアプリケーションの場合にchack.phpなどに飛ばすかと思いますので、一応action属性はchack.phpとしています。method属性と一緒にご自身のWebアプリケーションに合わせてください。

HTML

<div id="input-txt">
  <form method="post" action="chack.php">
    <textarea></textarea>
    <p id="count">あと<span id="num"></span>文字</p>
    <input type="submit" value="send">
  </form>
</div>


textareaの下にカウントに関する情報を表示させる部分を構築して、その下に送信ボタンを設置します。
カウントに関する情報や送信ボタンの動作はjQueryでコントロールしていきます。

続いて、CSSです。

input-txtではレスポンシブに対応するようにある程度のデザインをしておきます。
inputやtextareaに対してはデフォルトのCSSが効いているとデザインしにくいので、デフォルトのCSSをリセットしています。buttonやselectタグを使う場合でもセレクタを追加してあげればこちらでリセットすることができます。
便利なので覚えておきましょう。

CSS

#input-txt {
  width: 92%;
  max-width: 800px;
  margin: auto;
  text-align: center;
  position: relative;
}

input, textarea {
  margin: 0;
  padding: 0;
  background: none;
  border: none;
  border-radius: 0;
  outline: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
}

textarea {
  width: calc(100% - 24px);
  min-height: 200px;
  resize: none;
  /* resize: vertical; */
  /* resize: horizontal; */
  background: #f9f9f9;
  border: 2px solid #999;
  padding: 10px;
  margin: 30px 0 0;
}

input[type='submit'] {
  padding: 12px 40px;
  background: #f9f9f9;
  border: 2px solid #999;
  margin: 30px 0 0;
}

input.disabled {
  opacity: .4;
}

#count {
  display: none;
  text-align: right;
  position: absolute;
  right: 0;
}

#count.over {
  color: #f00;
  font-weight: bold;
}


textareaのデザインですが、幅の指定でcalc()関数を使って数値の計算を行っています。borderやpaddingをpx指定しているので、レスポンシブに対応するため要素の100%から左右にかかるborderやpaddingのpx指定分を引きます。

高さはmin-heightで最低限必要な高さを設定しています。ここはresizeプロパティを使うことでいろいろとコントロールができます。「resize: none」とすることで高さを変更できなくできます。その他「resize: vertical」で垂直方向へ、「resize: horizontal」で水平方向へのリサイズコントロールが可能となります。

input[type=’submit’]で送信ボタンのデザインをして、input.disabledで「disabled」のクラス名が付いている時に透過させて少し見た目を変えます。ここはjQueryで制限文字数を超えた時にボタンの機能を無効化する流れでデザインを変更します。

countでは最初は非表示にしておきます。こちらはjQueryで残りの文字数が迫って来た時に表示するようコントロールします。ポジションはtextareaの右下に配置されるようにします。カウントがオーバーした時に「over」というクラス名を付けるので、そこで文字を赤くしたり太くしたりとデザインします。

全体的なデザインはご自身のデザインに合わせてください。

続いて、jQueryで動作をコントロールしていきます。


文字数で動作をコントロール


ここからはjQueryを使い文字数によって動作をコントロールしていきます。

on()メソッドを使ってイベントを処理していきます。
イベントにはkeydown,keyup,keypress,changeと複数設定します。
キーが押された時、キーを離した時、キーを押している時、要素に変更があった時などに処理が実行されるようにします。そしてon()メソッドのfunction内でイベント発生時の処理を記述していきます。

jQuery

$(function(){
  $("textarea").on('keydown keyup keypress change',function(){
    let count = $(this).val().length;
    let limit = 50 - count;
    if (limit <= 20) {
      $("#count").show();
      $("#num").text(limit);
      $("#count").removeClass('over');
      $("input[type='submit']").prop('disabled', false).removeClass('disabled');
      if (limit <= 0) {
        $("#num").text('0');
        $("#count").addClass('over');
        $("input[type='submit']").prop('disabled', true).addClass('disabled');
      }
    } else if (limit >= 20) {
      $("#count").hide();
    }
   });
});


処理の内容としては、まずletで変数を2つ定義します。
変数「count」でtextareaのvalue値の文字数を格納、「limit」で制限文字数からカウントを引いた値を格納します。この変数limitの値がいくつかで表示や動作をコントロールします。

limitが20以下になったらCSSで非表示にしていたカウント部分をshow()メソッドで表示させて、id「num」にlimitの数値をテキストとして表示させます。
逆にlimitが20以上の時にはカウント部分は非表示にします。

また、limitが20以下の処理でlimitが0以下となった時にはカウントのナンバーのテキストを「0」としてカウントの要素には「over」のクラスを付けてデザインを変数させます。

そして制限文字数をオーバーしている時には送信できないようにするためinput[type=’submit’]に対してprop()メソッドでボタンを無効を「true」として無効化させるとともにaddClass()メソッドで「disabled」のクラスを付けてあげてデザインを変更します。
逆に制限文字数をオーバーしていない時は有効になるように「false」としてremoveClass()メソッドでクラスを取ってあげます。

これでユーザーの入力テキストの文字数でデザインや動作をコントロールすることができます。


まとめ


ユーザーからの入力テキストの文字数で動作をコントロールする方法をご紹介しましたが、文字列の制御で半角と全角のバイト数とMySQLなどのデータベースのテーブルでVARCHAR型の最大文字数の設定とズレが生じてきます。jQueryでもバイト数の制御は可能ですが、もう少し複雑なプログラムになりますのでシンプルに対応したいところです。
そこはデータベース側で調整すると楽かもしれません。

半角と全角、あとは文字コードによっても違いが出てきますので、テーブルのVARCHAR型の最大文字数は2倍かもう少し余裕をもたせた設定にするとエラーを回避できるので良いでしょう。