jQueryでパスワードの表示と非表示を切り替える


はじめに

railsでアプリケーションを行っている初学者のいりふねです。
今回、ユーザー登録画面のパスワード入力欄の表示と非表示を切り替える実装を行いました。ネット上に「カンタン」と書かれた同記事が多くありましたが、自分の環境で実装するのは少し時間がかかりました。
そこで、アウトプット兼自分用メモとして私の環境でうまく動作した手順を書いていきます。

開発環境

  • Rails 5.2.4.3
  • Haml 5.1.2
  • jquery-rails (4.4.0)
  • form_forを使用して実装しています

実現すること

ユーザー登録画面などでデフォルトで非表示になっているパスワードをcheck_boxを使用して表示と非表示を切り替えます。具体的には、以下Gifのような状態を目指します。

手順

  1. check_boxの設置
  2. password_fieldにidを付与
  3. jsファイルにjQueryを記述

check_boxの設置

hamlファイルにcheck_boxを記述します。今回は、説明に不要なclass名などは予め外した状態にしています。cssなどをつけるときは別途設定して下さい。

example.html.haml
= form_for @user, url: user_registration_path do |f|

〜中略、password_fieldの記述などがあります〜

    %p
      = check_box_tag :passcheck
      = f.label "パスワードを表示する"

順番に説明します。
まず、pタグで囲ったのは、チェックボックスや「パスワードを表示する」という文字が、直上のpassword_fieldの右に回り込んでしまうためです。cssを編集することでカバーも可能でしょうが、pタグだけで解決するので、今回はこの方法を採用しました。

次に「check_box_tag」の部分です。これは、関連するモデルがない時のチェックボックスの書き方になります。他のフォームの記述に揃えて「= f.check_box」を使用すると、引数として保存先モデルのカラム名の記述が必須となってしまいます。今回のチェックボックスはレコードの保存が目的ではないので、「check_box_tag」を使用しました。

参考にさせていただいた記事【初心者向け】チェックボックスの書き方あれこれ[Ruby][Rails]

同行後半の「:passcheck」は、nameとidを指定しています。検証ツールで確認すると反映されていることが分かります。idはこの後、jQueryで要素を指定するための使用します。

password_fieldにidを付与

password_fieldにjQueryで要素を指定するためのidを付与します。コードの後半部分がidを付与している箇所となります。

example.html.haml
〜省略〜
= f.password_field :password, autocomplete: "off", placeholder: "7文字以上の半角英数字", id: "js-password"
〜省略〜
= f.password_field :password_confirmation, autocomplete: "off", placeholder: "もう一度入力して下さい", id: "js-password_confirmation"
〜省略〜

ここで、idを同じものにしてしまうと、検証ツールのコンソール上で「idが重複しているよ!!」と黄色で警告が出てきます。ページが表示されないほどのエラーにはなりませんが、気持ち良いものではないので、今回はid名を分けて書きました。

jsファイルにjQueryを記述

jsファイルを作成し、コードを記述します。

example.js
$(function() {
  $('#passcheck').change(function(){
    if ($(this).prop('checked')) {
      $('#js-password').attr('type','text');
      $('#js-password_confirmation').attr('type','text');
    } else {
      $('#js-password').attr('type','password');
      $('#js-password_confirmation').attr('type','password');
    }
  });
});

実は、jQueryはまだ勉強中なので、十分説明ができません。汗
参考にされていただいた記事パスワード表示時にマスキング有無を選択できるようにする方法

とはいえ、自分なりに言語化してみます。
まずは、先程チェックボックスに指定したid名#passcheckで要素を取得し、changeイベントを設定します。ちなみにイベントはclickに変えても動きました。

次にif文を記述し、取得した要素からcheckedプロパティの有無をpropメソッドで確認します。チェックされていれば真、それ以外なら偽という扱いになります。

if結果が真の場合、つまりチェックが入った状態であれば、フォームに入力されたパスワードの値に対して、attrメソッドを使用して属性を取り出します。チェック済みならtype属性のtextを表示、そうでなければtype属性のpasswordを表示で隠すという具合です。

今日の積み上げ

改めて、jQueryの復習が必要であると感じました。
と同時に未熟な私でも機能実装できるようにわかりやすくまとめられた記事の多さに感謝しました。今後もアウトプットを続けて同じ初学者の方のためになればと思います。