鶏口牛後な日々

魔法使い(なんでも作れるエンジニア)を目指してます。ブログは発散中

<button>タグ使うときは、type属性の記述を忘れるなかれ。(時折面倒なことに巻き込まれます)

buttonタグのtype属性

HTMLだけを勉強している人は、入門の教科書などで、Formを送信したい時のボタンは type="submit" をつけます、というのを知っていると思います。 ただ、submitしたくない、ただのボタンの時は、 type="button" をつけましょう! というのはそこまで強調されていなかったのではないかと思います。 私も、 type="submit" をつけないと送信されない! ということを意識したことはあれ、 type="button" をつけないとまずい、というのはこれまで意識したことがありませんでした。

そんなわけで、適当に <button class="muhu" id="hoge"></button> といったボタンをこれまで書いていたと思います。 今回、相当にはまったので、時折(頻繁ではないと思いますが)落とし穴にはまるから、 type="button" は忘れずに書こう、ということを記しておきたいと思います。

先に結論:buttonタグを使うときは、type属性(submit/button)を書くよう習慣づけて無用なエラーに繋がらないようにしよう

結論から言うと、 type="button" と書いておかないと、buttonタグは type="submit"だと解釈されるみたいで、画面遷移させたくない時でも画面が遷移します。 ただ、ajaxやjsやLaravelのvalidation機能など、ただのHTMLより色々と複雑な画面遷移が起きかねない実装をしていると、それらのせいで画面が遷移したと勘違いして、はまる可能性がある、ということです。 HTMLだけ使っているシンプルな画面であれば、特に問題はないと思いますが、複雑になればなるほどエラーが起きた時の原因を探すのが面倒になるので、できればはまらないためにも type="button" は常日頃から書いておくようにしよう、と思った次第です。

実際に起きたこと

何がおきたかというと、郵便番号を入力して、「住所を検索」みたいなボタン、よくありますよね。 あれをajaxで実装しました。サーバサイドはPHP Laravelを使っています。 その時のボタンに、typeをつけていなかったんですね。

そうしたら、なぜか住所を検索した途端に、バリデーションが走って、せっかく検索して入力した住所の内容が消えてしまう。 これに相当ハマりました。 バリデーションが走るのは、PHP Laravelのバリデーション機能のおかげなので、 「ajax redirect prevent PHP Laravel 」 とかの検索用語で検索しました。 検索結果は結構ヒットして、StackOverflowなどで、ajaxで勝手にリダイレクトされる機能を、Laravelの既存のresponseメソッドをオーバーライドするとできる、といった内容の回答が結構出てきて、 「うーん、そんな難しそうなことほんとにしないといけないんだろうか」と悩み、ちまちまと、ブラウザのNetworkタブを見たり、console.logで出力させたりして原因を解明しようとしました。

かなり詰まったので、一度ちょっと時間をおいてリフレッシュしてから再度試してみたところ、validationが通っている場合、次の画面に遷移することがわかりました。 ここで、やっと、「あれ? このボタンで次の画面に遷移する必要はないんだけどな? もしかして・・・」と気づいたわけです。

buttonタグを、pタグに変えてみたところ、無事に画面遷移することなく、住所が入りました。 あとで先輩から、何もtype属性を入れないと、デフォルトで type="submit" になってしまう話を聞き、まさにそれだと痛感。 反省を込めて、この記事にまとめていると言うわけです。

先輩もそれでハマったことがあるらしいので、案外みんながはまるポイントなのかも。