- Bootstrap4公式のページでは、未入力に対するバリデーションはあったけど、パスワード一致のバリデーションはどうしたら実現できるのかの記述がなかったので、自分で作って見ました。
- Bootstrap4では、以下のようなJSファイルを書くことで、バリデーションエラーが生じた場合にエラー文を出してくれます
(function() {
'use strict';
window.addEventListener('load', function() {
var forms = document.getElementsByClassName('needs-validation');
var validation = Array.prototype.filter.call(forms, function(form) {
form.addEventListener('submit', function(event) {
// ここでバリデーションエラーがないか確認している
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
}, false);
})();
- つまり
checkValidity()
メソッドで、パスワードの不一致を判定できれば言いわけです。 - 本当は
data-match属性
とか使う方がスマートなのかもしれません。 - ですが、自分ではどうもうまく行かなかったので、今回は
pattern属性
を使うことで実現しています。 - もっとスマートな方法があったらぜひお知らせ願います。
パスワードの一致バリデーションの書き方
- 今回は、「パスワード(確認)のInputタグの
pattern属性
」を使います。 - pattern属性には文字列を入れることができ、その文字列とInputに入れられた値が異なる場合にはバリデーションエラーを発生させてくれます。
- なので「パスワード入力欄のInputハンドラ」で、「パスワード(確認)のpattern属性」と、「パスワード入力欄の値」を連動させれば、パスワードの一致バリデーションを実現することができます。
<div class="form-group">
<%= f.label :password %>
<%= f.password_field :password, id: 'password-input', class: 'form-control', required: true, pattern: '^(?=.*?[a-zA-Z_-])(?=.*?\d)[0-9a-zA-Z_-]{8,}$' %>
<div class="invalid-feedback" style="width: 100%">
パスワードを正しいフォーム(数字、小か大文字を含む8文字以上)で入力してください
</div>
</div>
<div class="form-group">
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation, id: 'password-confirmation-input', class: 'form-control', required: true, pattern: '' %>
<div class="invalid-feedback" style="width: 100%">
空欄もしくはパスワードが不一致です
</div>
</div>
// password-inputの値とpattern属性を連動させる
$('#password-input').on('input', function(){
$('#password-confirmation-input').prop('pattern', $(this).val())
});
- 改めてポイントを復習すると以下の通りです。
- pattern属性を「パスワード(確認)のインプット欄」につける。
- 「パスワードのインプット欄」のInputハンドラで、「パスワードのインプット欄の値」と「パスワード(確認)のインプット欄のpattern属性」を連動させる。
これで実現できるはず!