開発環境
Mac OS Catalina 10.15.7
ruby 2.6系
rails 6.0系
前提
-
投稿フォームのビューは実装済み
-
JavaScriptのフレームワーク等は使っていません
ビューにIDを付与する
まずはビューにIDを付与していきます。
IDを付与する要素は2箇所で、文字数を出力する要素と、文字数をカウントしたいフォームの要素に付与していきます。
<div class="new-postss">
<div class="weight-bold-text">
写真のタイトル
<span class="indispensable">必須</span>
# IDを付与
<span class="count" id="count_title">0文字</span>
</div>
# IDを付与
<%= f.text_area :title, id:"post_text", placeholder:"タイトル(必須 40文字まで)", maxlength:"40", rows:"1" %>
</div>
Count.jsファイルを作成
文字数をカウントする関数を記述するためのファイルを作ります。
ディレクトリのパス
ファイルを作ったら、忘れずにapplication.jsで読み込みましょう。
また、turbolinksが原因で、正常な挙動にならないケースもあるので、コメントアウトしています。(2行目)
require("@rails/ujs").start()
//require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
//この1行を追加
require('./count')
Count.jsファイルを編集
ここまでできたら、いよいよJavaScriptを書いていきます。
まずは関数countを作り、window.addEventListenerで、ページが読み込まれた後に関数が起動するように記述します。
function count (){
}
window.addEventListener('load', count);
その後、先ほど付与したID(フォームの方)を取得して、定数に代入します。
function count (){
const postText = document.getElementById('post_text');
}
window.addEventListener('load', count);
その後、先ほどの変数に対して、ユーザーがキーボードを離したときに発火するkeyupを用いて文字数がカウントされるイベントを書いていきます。
完成形は以下の通りです。(後から順を追って説明します。)
function count (){
const postText = document.getElementById('post_text');
postText.addEventListener("keyup", () => {
let titleLength = postText.value.length
let countTitle = document.getElementById('count_title')
if (titleLength > 40){
titleLength = 40
}
countTitle.innerHTML = `${titleLength}文字`
});
}
window.addEventListener('load', count);
まず、イベント発火させるための記述をします。
postText.addEventListener("keyup", () => {
});
次に、フォームに入力された文字数( postText.value.length )と文字数を出力したい要素を変数に代入します。
postText.addEventListener("keyup", () => {
let titleLength = postText.value.length
let countTitle = document.getElementById('count_title')
});
次に、文字数を出力したい要素を代入した変数(この場合は countTitle)のHTMLを書き換える記述をします。
そのHTMLを書き換える際に文字数を代入した変数 titleLength を使います。
postText.addEventListener("keyup", () => {
let titleLength = postText.value.length
let countTitle = document.getElementById('count_title')
countTitle.innerHTML = `${titleLength}文字`
});
最後に、おまけにはなりますが、自分の場合は、フォームで40文字以内という制限を設けているので、if文で、40文字を越える際は、強制的に40文字に止まるように記述しています。
postText.addEventListener("keyup", () => {
let titleLength = postText.value.length
let countTitle = document.getElementById('count_title')
if (titleLength > 40){
titleLength = 40
}
countTitle.innerHTML = `${titleLength}文字`
});
以上が、railsでJavaScriptを使って文字数のカウントをする方法です。
文字数をカウントしたいフォームが複数ある場合でも、新しくIDを付与して、関数count内に同様の手順で記述していけば実装できます。
参考になれば幸いです。