input type=imageの挙動について

スポンサーリンク

現象

先日に、eccube2の「入力内容のご確認」画面の「次へ」ボタンを押して、次の決済画面に進まない、決済モジュールの問題ではないかを含めて、調査&対応してほしいというお客様からご依頼がありました。

事前に予想し、調査の方向を決める

WEBアプリケーションにおいて、ボタンを押して、想定外の挙動が起きた場合、大体、javascriptに何らかの問題があります。
今回は、決済モジュールにも関わったようですが、決済モジュールの問題かどうかはまだ分からないため、javascriptにエラーがあるという想定で調査を進めます。

問題の現象を再現する

テストデータを作って、対象画面に進んで、「次へ」ボタンを押して、確かに次の画面に進まないことを再現しました。

調査&分析する

再現する同時に、Firefoxの(javascriptデバッグ機能、パフォーマンス、使い勝手などはとても優れる)開発ツールを開きながら、コンソールにjavascriptエラーが発生しないため、この時点で単純ミスの可能性が高く、対応難易度が下がるかもしれないことが分かりました。すぐにネットワークパネルに切り替えて、サーバーにsubmitの挙動がなかったことを確認しました。

原因を特定する

ボタンを押して、submitできない場合、html実装上に問題があるかと思って、インスペクターパネルで、「次へ」ボタンの実装を確認したところ、inputタグのtype属性の値が「button」であることを確認できました。
onclickイベントでjavascript 関数を呼び出したが、その関数の中にformのsubmitの実装がなかった。ここまでは問題の原因を特定しました。

■問題となる実装

問題を解決する

submitしないのは、原因なので、inputタグのtype属性の値(button)を「submit」に修正すれば、問題を解決します。

■改修後の実装

■submitボタンがヤダな方はtype属性の改修をやめて、下記のように、fnCheckSubmit関数の中にformのsubmitメソッドを呼び出せば、大丈夫と思います。(筆者はこの方法で対応しました)

※inputタグはbuttonのまま

動作確認

改修後に、再現手順でもう一度確認したところ、javascriptエラーなどの問題がなく、次の画面に遷移することを確認できました。

疑問

無事に対応して良かったですが、一つの疑問が残っています。
eccubeさんがちゃんとテストしたはずのに、なぜ、今回の問題が発生したでしょうか。もしかして、決済モジュールを使う場合、この問題が発生するでしょうか。
取り急ぎ、オリジナル実装と比べたら、その疑問を解消しました。

■オリジナル実装

■問題となる実装

皆さん、お分かりになりますでしょうか。imageですよね。「input type=image」と言えば、その厄介な自動submit特性が有名ですね。

ノウハウ

昔(10数年前)、画像(image)を使って、ボタンを表すWEBアプリケーションが多かったと思います。その際に、inputタグのtype属性に「image」を設定すれば、実現できます。CSSを重視しなかった時代に、見た目(美しさ)を意識するWEBアプリケーションにとって、imageは大変便利な実現方法です。
ただし、厄介なのは、どこのドキュメントにも記載されていなくて、imageは隠れた特性を持っています。それは自動submitのことです。submitをさせないように、多くのプロジェクトは苦労していました。
(筆者が参画したプロジェクトは開発の末期でinput buttonをimageに変えましたため、想定外の挙動ばかりで、チーム全体がパニック状態になったということもありました)

今回の問題と関係ないですが、おまけに、imageのsubmitをさせない方法を紹介します。

■submitさせる/させない対応方法

まとめ

最近のWEBアプリケーションは、imageの代わりに、CSSでボタンイメージを実現することは流行っていますので、imageの自動submit特性を知らない若い人が多いではないかと思います。
今回の問題を通して、input type=imageの自動submit特性を覚えて、今後このノウハウを活かして、問題を解決できればと思います。

スポンサーリンク