LoginSignup
22
18

More than 1 year has passed since last update.

【Rails】jQueryでフォームに文字数カウントをつける

Last updated at Posted at 2019-10-04

フォームに文字を入力していく時、あと何文字まで打てるのか分かった方がユーザーに優しいと思ったため、文字数カウント機能を作りました。

▷今回やること
フォームに残り何文字入力できるかを表示する

ezgif.com-video-to-gif.gif

文字数カウント方法を考える

・文字を入力したり、消したりするたびフォームの文字数を数える → 残り何文字まで入力できるか表示する
・文字数がオーバーしていた場合、文字色を赤にする → ユーザーに警告する

文字数カウントのアルゴリズムを考える

jQueryで文字数カウントをする


▷jsが読み込まれたら以下の処理をする

 ・処理内容(ページが読み込まれた時、フォームに残り何文字入力できるかを数えて表示する)
 フォームのvalueを取得して文字数を数える
 <!-- Macの改行コードは1文字(\n)であるが、Rails側では改行コードが2文字(\r\n)で保存されるため、\nは2文字とカウントするように設定 -->
 最大文字数 ー 取得した文字数 (=残りの入力できる文字数)

 if 最大文字数より取得文字数の方が大きい
  表示する文字色を赤にする

 “あと (残りの入力できる文字数)文字” と表示する

  ▷jQueryのkeyup()でキーボードが押されて離れるたびに処理を行う

   ・処理内容(キーボードを押した時、フォームに残り何文字入力できるかを数えて表示する)
    フォームのvalueを取得して文字数を数える。
    <!-- Macの改行コードは1文字(\n)であるが、Rails側では改行コードが2文字(\r\n)で保存されるため、\nは2文字とカウントするように設定 -->
    入力最大文字数 ー 取得した文字数 (=残りの入力できる文字数)

   if 最大文字数より取得文字数の方が大きい
    表示する文字色を赤にする
    “あと (残りの入力できる文字数)文字” と表示する
   else
    表示する文字色を黒にする
    ”あと (残りの入力できる文字数)文字” と表示する

  処理終了
処理終了

コードで文字数カウント処理を書く

1.htmlでフォーム入力タグと文字数表示タグにclassを設定し、jsで指定できるようにする

フォーム入力タグtext_areaのクラスにjs-text、文字数表示タグpのクラスにjs-text-countを指定する
(フォームにbootstrapを適用しています)

form.html.erb
<%= form_for(@profile) do |f| %>
  <div class="panel-body">
    <div class="form-group">
    <%= f.label :yourself, '自己紹介(最大150文字)' %>

    <%# js-textをclassに追加 %>
    <%= f.text_area :yourself, class: 'form-control  js-text', rows: 6, placeholder: '改行は反映されません' %>

    <%# js-text-count をclassに追加 %>
    <P class="js-text-count pull-right"></P>
  </div>
      
  <div class="text-center">
     <%= f.submit '保存する', class: 'btn btn-info'%>
  </div>
<% end %>    

2.jsファイルにフォームと文字数表示に対する処理を書く

js-textのvalueを数えて、js-text-countに結果を表示する
app/assets/javascripにcount.jsファイルを作成し、文字数カウントの処理を書いていく
(今回のフォームの最大文字数は150)

app/assets/javascrip/count.js
// jquery書きはじめ
$(function (){
  // 処理(ページが読み込まれた時、フォームに残り何文字入力できるかを数えて表示する)

  //フォームに入力されている文字数を数える
  //\nは"改行"に変換して2文字にする。オプションフラグgで文字列の最後まで\nを探し変換する
  var count = $(".js-text").text().replace(/\n/g, "改行").length;
  //残りの入力できる文字数を計算
  var now_count = 150 - count;
  //文字数がオーバーしていたら文字色を赤にする
  if (count > 150) {
    $(".js-text-count").css("color","red");
  }
  //残りの入力できる文字数を表示
  $(".js-text-count").text( "残り" + now_count + "文字");

  $(".js-text").on("keyup", function() {
    // 処理(キーボードを押した時、フォームに残り何文字入力できるかを数えて表示する)
    //フォームのvalueの文字数を数える
    var count = $(this).val().replace(/\n/g, "改行").length;
    var now_count = 150 - count;

    if (count > 150) {
      $(".js-text-count").css("color","red");
    } else {
      $(".js-text-count").css("color","black");
    }
    $(".js-text-count").text( "残り" + now_count + "文字");
  });
});

3.リンクをクリックしてページ遷移した時、jacascriptを読み込むようにする

現在のままでは、ページ遷移してもjsが機能しない

▷原因
rails4.0からデフォルトで導入されたgem「turbolinks」が読み込まれているため

〜turbolinksとは〜

画面遷移を高速化させるライブラリ。
ページ遷移するとき、現在のページのtitleとbodyだけを抜き取り、
新しいhtmlのtitleとbodyに交換することで、ページ遷移を高速化させる。
→ページ読み込みを起点としたJavascriptは機能しなくなる
jQuery を使用している場合、
下記の様にページが読み込まれたときの処理を記述出来ますが、
Turbolinksによって、実行されなくなります。
$(function() {
#処理内容
});

『Turbolinks』って、なんぞ?より抜粋

▷解決方法
count.jsを読み込みたいリンクのtubolinksを無効にする
aタグdata-turbolinks="false"link_toメソッドdata: {"turbolinks" => false}でtubolinksを無効化できる

リンク設定がaタグの場合

<a href=“◯◯” data-turbolinks="false">turbolinksを使わずにリンクする</a>

リンク設定がlink_toメソッドの場合

<%= link_to "turbolinksを使わずにリンクする", ◯◯_path, data: {"turbolinks" => false} %>

これでページ遷移した時、count.jsが読み込まれるようになり、文字数カウント処理が行われる。

参考

[簡単すぎる]Rails + jQueryで文字数カウント
【JavaScript】文字列から改行を全て削除する方法
turbolinksチートシート
『Turbolinks』って、なんぞ?

22
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
18