XPagesで同じカスタムコントールを使用する場合のID被りへの対処法

Notes/Dominoエンジニア XPages担当の米原です。

今回もXPagesのお話です!

共通して使用しているカスタムコントロールを同ページで複数使用する必要がある場合、

例えばこんなパターン

<xp:panel>
	<xc:ccFormSample02>
		<xc:this.rendered><![CDATA[#{javascript:param.get("paramTEST") == "01"}]]></xc:this.rendered>
	</xc:ccFormSample02>
	<xc:ccFormSample02>
		<xc:this.rendered><![CDATA[#{javascript:param.get("paramTEST") == "02"}]]></xc:this.rendered>
	</xc:ccFormSample02>
</xp:panel>

「ccFormSample02 」カスタムコントロールをURLパラメータの値で表示/非表示の切り替えを行っています。

↑ paramTEST=01 の場合
↑ paramTEST=02 の場合

今回は設計が複雑ではない簡単なカスタムコントロールを用意しましたが、実際運用される場合はもっと複雑

で複数配置を目的としたカスタムコントロールがあるかと思います。

例えばこのようなときが想像できます。

カスタムコントロールA(共通して使用したい。)

画面の表示をURLパラメータで切り替えている場合

画面Aでは「カスタムコントロールA」情報が重要になるので一番上に表示させたい。

画面Bでは「カスタムコントロースA」情報はあまり重要ではないので一番下に表示させたい。

そのような場合に同じカスタムコントロールを同画面に配置してURLパラメータで切り替えることで実装したりします。

表示・非表示切り替えで対応する場合に問題になるのが、IDの問題です!
今回は共有箇所のInputTestフィールドにIDを付与していてそのIDを元に値をセットしている場合があります。

<xp:tr>
	<xp:td styleClass="tblHead">
		<xp:label id="label2"
			for="orderNumber1">
			<xp:this.value><![CDATA[#{javascript:
var ret = "";
ret = "共通箇所"
return ret;}]]></xp:this.value>
		</xp:label>
	</xp:td>
	<xp:td>
		<xp:inputText id="test001"></xp:inputText>
	</xp:td>
</xp:tr>

id="test001" 箇所ですね。

例えば初期値に値をセットさせたい場合でこのように値をセットしている場合

	<xp:this.afterPageLoad><![CDATA[#{javascript:
getComponent("test001").setValue("test");
}]]></xp:this.afterPageLoad>

「 getComponent("test001").setValue("test"); 」このような方法で表示の値をセットすると、

結果的には

↑ paramTEST=01 の場合
↑ paramTEST=02 の場合

paramTEST=01 の場合 は初期値に 「test」がセットされていますが、 paramTEST=02 の場合 は値がセットされていません。

これはIDが被っているので最初に見つけた所のIDにセットされるようになります。

もう少し詳しく説明しますと、 getComponent("test001") .setValue("test") とすると、最初の id="test001"が取得されて、そちらに値がセットされてしまいます。

非表示の方法としてrenderをfalse にしたり、 style に display:none をして非表示にしたりしますが、 getComponent では非表示にしても取得されていまうので、そのような現象になってしまいます。

さてさて、どうしたものかな~と。。。。

そこで活躍するのが「loaded」です!

<xp:panel>
	<xc:ccFormSample02>
		<xc:this.loaded><![CDATA[${javascript:param.get("paramTEST") == "01"}]]></xc:this.loaded>
	</xc:ccFormSample02>
	<xc:ccFormSample02>
		<xc:this.loaded><![CDATA[${javascript:param.get("paramTEST") == "02"}]]></xc:this.loaded>
	</xc:ccFormSample02>
</xp:panel>

loaded は ページ作成時にコントロールを作成するかどうかですので、どちらかのカスタムコントールしか作成されなくなり、IDが被ることが無く期待した動作になるということになります。

loadedを使用した場合のparamTEST=02

無事期待する動作となりました。

今回のパターンでは 「rendered」では都合が悪く、「loaded」を使用しましたが、「loaded」は一度「false」にしてしまうと、ページ全体をロードしなおさないと表示の切り替えができません。「rendered」に関しましては、部分更新で表示/非表示の切り替えが可能となります。

両方使える場合では「 loaded 」が「false」の場合はカスタムコントロールを一切読み込まないので、余分にメモリを消費しないことや処理速度も 「rendered」 に比べて早いのではないかと考えられます。

用途に合わせて使うのがよろしいかと思います。

似た様なことでお困りの際はお試ししてください。

ではでは本日はこの辺で失礼いたします。