Visualforceページを実装している時にハマったことがあったので記事化
やりたいこと
あるVFページからボタンを押したら、ブラウザの新規タブで別のVFページを表示させつつ、
新規表示するページにパラメータを渡したい
ハマったこと
Visualforce のtarget="_blank"
とreRender
を併用したら、うまくいかずにハマった
ハマったソースは以下のような感じ
あるコマンドボタンを押すと、対応するアクションでパラメータを受け取って
受け取ったパラメータを次のページのパラメータとして渡す
ハマったvisualforce
<apex:form id="form-id" target="_blank">
<!-- コマンドボタン 新規タブで開くがパラメータが渡らない -->
<apex:commandButton value="ボタン" action="{!openNewPage}">
<apex:param name="param" value="hoge"/>
</apex:commandButton>
<!-- コマンドボタン 新規タブで開かないがパラメータが渡る -->
<apex:commandButton value="ボタン" action="{!openNewPage}" reRender="form-id">
<apex:param name="param" value="hoge"/>
</apex:commandButton>
</apex:form>
ハマったApex
public with sharing class Controller {
// 直接パラメータを受けてそれを遷移先に渡そうとしていた
// commandLinkとcommandButtonから新規タブを開きながらアクションを呼ぼうとしたら、新規タブは開くがパラメータが渡らない
// target="_blank" と reRender を併用すると、新規タブで開かない代わりにパラメータが渡らない
public PageReference openNewPage() {
String param = System.currentPageReference().getParameters().get('param');
PageReference newPage = Page.NewPage;
newPage.getParameters().put('param', param);
return newPage;
}
}
原因
どうやらreRenderとtarget=_blankの併用だとよろしくないらしい
この辺の挙動の詳細がわかってないので、要調査
おそらく、reRenderをすると同一ページの再描画になるので、新規タブ表示が行われなくなる?
reRenderを使う時にその詳細な挙動まで意識したことがないので、反省
解決
いろいろと調べた挙句、ActionFunction
でパラメータをコントローラに登録する処理だけを別で呼ぶことにした。
ベストプラクティスかどうかはわからないが、実現したい挙動はできたのでとりあえずよしとする
<apex:form id="form-id" target="_blank">
<!-- パラメータをコントローラに持たせるための処理 -->
<apex:actionFunction name="setParams" action="{!setParams}" reRender="form-id">
<apex:param name="param" value="{!param}"/>
</apex:actionFunction>
<!-- 出力ボタン, onclickでsetParamsを呼ぶ -->
<apex:commandButton value="ボタン" action="{!openNewPage}" onclick="setParams()"/>
</apex:form>
public with sharing class Controller {
// パラメータを保持する変数
String param {get; set;}
// ActionFunctionで呼んで、パラメータをコントローラに保持させる関数
public void setParams() {
this.param = System.currentPageReference().getParameters().get('homesNo')
}
public PageReference openNewPage() {
PageReference newPage = Page.NewPage;
newPage.getParameters().put('param', param);
return newPage;
}
}
これで無事にパラメータを渡しつつ、別タブでの表示ができた
とはいえゴリ押し感が強いが、目をつむる