WicketでHTMLのaタグにonclick属性を書く場合の注意点

はじめに

 「そりゃJSP + Strutsで開発してた人にとっては違和感あるだろうなぁ」という出来事があったのでメモ。
 何かと言いますと、「HTMLのaタグにonclick属性を書いた際、実行時に残っている場合と、消えている場合がある」という話です。
 もっと一般化すると、onclick属性に限らず全ての属性について起きる可能性のあることなのですが、今回はonclick属性に着目してメモします。

環境

aタグにSubmitLinkを適用する場合

 aタグにSubmitLinkを適用する場合は、onclick属性は常に消えます。
 「常に」というのは若干語弊*1があるのですが、それはさておき。

 どういうことかと言いますと、下記のようなHTMLを書いたとしましょう。

<html>
    <head>
        <title>link</title>
    </head>
    <body>
        <form wicket:id="form">
            <div><input type="text" wicket:id="text" /></div>
            <!-- onclick属性の中身に注目-->
            <div><a href="#" wicket:id="submit" onclick="confirm('a');">submit</a></div>
        </form>
    </body>
</html>

 実行時には以下のようになり、最初に書いてあったonclick属性は消えてしまいます。

<html>
    <head>
        <title>link</title>
    </head>
    <body>
        <form id="form1" action=";jsessionid=626B0612B1B5F04075AB874C9917FE3C?wicket:interface=:0:form::IFormSubmitListener::" method="post" wicket:id="form"><div style="display:none"><input type="hidden" name="form1_hf_0" id="form1_hf_0" /></div>
            <div><input name="text" value="" type="text" wicket:id="text"/></div>
            <!-- onclick属性の中身に注目-->
            <div><a onclick="var e=document.getElementById('form1_hf_0'); e.name=':submit'; e.value='x';var f=document.getElementById('form1');var ff=f;if (ff.onsubmit != undefined) { if (ff.onsubmit()==false) return false; }f.submit();e.value='';e.name='';return false;" href="#" wicket:id="submit">submit</a></div>
        </form>
    </body>
</html>

 なぜこのようなことが起きるかと言いますと、SubmitLink#onComponentTag(ComponentTag)の実装に秘密があります。
 以下に引用するメソッドを読めば分かるのですが、HTMLに書かれたonclick属性なんてものは気にせずに、onclik属性を設定しています。

	protected void onComponentTag(ComponentTag tag)
	{
		super.onComponentTag(tag);
		// If we're disabled
		if (!isLinkEnabled())
		{
			disableLink(tag);
		}
		else
		{
			if (tag.getName().equalsIgnoreCase("a"))
			{
				tag.put("href", "#");
			}
			tag.put("onclick", getTriggerJavaScript());
		}
	}

aタグにLinkを適用する場合

 Linkコンポーネントの場合は複雑で、最初に書いてあったonclick属性が消える場合と消えない場合があります。
 以下の場合に消えます。

  • LinkコンポーネントにPopupSettingsが設定されている場合
  • Link#getOnClickScript(final CharSequence)が実装されている場合

 消えない場合は、onclickの戻り値がtrueの場合はサーバに接続にいき、falseの場合はサーバに接続に行きません。
 遷移先がhref属性に記載されていますので、まあ、そういうことです。

さいごに

 SubmitLnkコンポーネントと、Linkコンポーネントのこの仕様は、理解していれば便利な仕様ではあります。
 HTMLでモックアップを作成する際に、画面遷移も含めた高機能なモックアップを作れますので。
 でも、Wicketに慣れた人だけでコーディングする際はさておき、「aタグにonclickイベントは書くな」というルールにした方が、開発しやすい気もします。

 「aタグにonclickイベントは書くな」というルールを採用するかどうかは、メンバー構成や規模に合わせて要検討ですね。

*1:onComponentTagメソッドを良い感じにオーバーライドしてやれば、消さないようにもきっと出来る