マジみたいです。
によると、maxlengthが使えるのは、
- text
- search
- url
- tel
- password
だけのようです。
じゃあ文字数をどう制限しようか?
この記事では代替案(解決策)を2つ紹介します。
経緯:決まった桁数を超えて入力できないようにしたい
そもそも、どうしてnumber_fieldにmaxlengthを使いたいと思ったかという経緯を説明しておきます。
web開発をしていると、金額や個数などの数字を入力する場面が多々存在します。
数字の入力フォームにはnumber_fieldですよね!
= f.number_field, :price, max: 999999, class: "form-control"
これでも十分(maxを超えた金額を入力して送信ボタンを押しても反応せず、エラーメッセージが表示される)ですが、例えば、100万円以上の取引ができないことが明確な場合、そもそも7桁目以降を入力できない方が親切なUIですよね。ユーザーフレンドリーなサイトにしたい!
そこで目をつけたのが、text_areaで使われていたmaxlengthオプションです。このオプションをつければ、指定した文字数を超えて入力することができなくなると思ったのですが・・・
フツーに7桁目も入力できてしまいました。この記事のタイトルにしたように、number_fieldでmaxlengthは使えないようです。
代替案2つ
1.JavaScriptで制御
こちらのサイトで紹介されていました。
sliceを使って7桁目以降を切ってあげることができます。
また今回の趣旨から外れますが、個人的には、7桁目の入力はいったん許容するがJSでエラーメッセージを表示してあげる、というUIもなかなか良いと思います。
2.text_fieldを使う(number_fieldは使わない)
元も子もないと思うかもしれませんが、これが現状最適解です。そもそも、郵便番号や電話番号、クレジットカード番号、「◯◯コード」や「◯◯番号」など頭に0がつく可能性のあるものは文字列として扱います。number_fieldだと扱いづらいのです。
「文字列だと数字以外も入ってしまうのでは?」と心配する気持ちもわかります。それは、
validates :price, numericality: { only_integer: true }
と半角数字のみ許可するバリデーションを組むことで対応しましょう。全角や数字以外の文字列を入力してsubmitを押しても、レンダーしてエラーメッセージを表示させることができます。
「いやいや、それを非同期で制御できるようにnumber_fieldを使っていたのに、それでは本末転倒では?」と思う気持ちもわかります。しかし、「金額」などの数字を入力することが明らかな項目に対して、
- ユーザーが数字以外を入力してしまう確率
- ユーザーが誤った桁数を入力してしまう確率
の2つを比較したとき、圧倒的に2の桁数ミスの方が多いしうっかりやりがちなので、こちらを優先的に制御してあげる、という方針です。しかも、number_fieldを使っていたとしても上記のバリデーションはどちらにせよ組んでおくことになります。開発者ツールなどで不正な値を送信された時にシステムを守るためですね。それがセオリーです。
以上より、下記のとおりになります。
= f.text_field, :price, maxlength: 6, class: "form-control"
これで、7桁目は入力できません!「あれ、どうして7桁目は入力できないんだ?」とユーザーが困惑しないように注釈を書いておくのを忘れずに。
感想
「マ?」ってもう死語なんですか。昨年か一昨年あたり流行っていた気がしたので使ってみたかったんですけど、最近見ないですね・・・マジ卍
最後まで読んでくださってありがとうございました!
コメント