Salesforce技術ブログ(レイアウトに埋め込まれたVisualforceページを、カスタムボタンで動かしてみよう!)
こんにちは、マルシェ丸岡です!
某ⅩⅤの発売が9月末から11月末へ延期となり、傷心気味です。。。
ある日、エンドユーザ様からご依頼が。
「Salesforceで取引先の情報共有をもっと簡単にしたい!」
「Chatterだとメンションをミスしたり、標準のメール送信画面も正直使いづらい・・・」
そこで取引先のレコード詳細画面に、Visualforceページで開発した【Chatter情報共有機能】を埋め込むことに。
ユーザを指定すれば、そのユーザへのメンション付きでChatterに投稿してくれるものです。
取引先チーム全員への一括メンション機能も完備!さぁこれを存分にご利用ください!!
・・・しかし、喜んでいただけると考えていた矢先、以下のようなご要望が・・・
ボタンが点在してて、ちょっと混乱します・・・ボタンの位置を集約できませんか?
たしかに、ごもっともでございます。。。
ということで、Visualforceページ内にボタンを配置するのをやめ、標準画面にカスタムボタンを配置し、そこからVisualforceページを制御することが可能か検証してみました。
・Visualforceページを作り、レイアウトに埋め込む。
下記のようなVisualforceページを作成しましょう。
<apex:page standardController="Account" sidebar="false" id="page">
<script type="text/javascript">
function iframeProcess(){
alert("処理を開始します!!");
}
</script>
<apex:form id="form">
<div style="height:80px; background-color:#99FFCC; text-align:center;">ここにVisualforceページが埋め込まれています。</div>
</apex:form>
</apex:page>
作成したVisualforceページを、取引先のページレイアウトに埋め込みましょう。
・カスタムボタンを作って、動かしてみる。
埋め込んだVisualforceページ内のJavascript処理【iframeProccess】を、カスタムボタンから動かしてみます。
まずはiframeのIDを確認しましょう。
以下はChromeのデベロッパーツールを用いてIDを確認している図です。
IDが確認できたら、下記の処理を組み込んだカスタムボタンを作成します。
表示の種類は「詳細ページボタン」、動作は「Javascriptを実行」です。
//フレームのID : 06628000006aOt4
document.getElementById('06628000006aOt4').contentWindow.iframeProcess();
早速、作成したカスタムボタンをクリック!「処理を開始します!」とアラート表示されれば成功ですが。。。
謎のエラーで動いてくれない。。。
・動かない原因は?
Blocked a frame with origin “https://ap2.salesforce.com” from accessing a cross-origin frame.
このエラーの原因を調査したところ、同一オリジンポリシーによる制約を受けていることが原因でした。
AページからBページへのアクセスを実行した際に、AとBのスキーム、及びホストが一致していなければ、
セキュリティ保持のために例外エラーを吐き出すといったものです。
このエラーはIEでも、Chromeでも、FireFoxでも発生するもので、
クロスサイトスクリプティングのような、悪意ある攻撃を防ぐための仕組みとなっています。
今回の場合、
・埋め込んだVisualforceページ:https://c.ap2.visual.force.com/
・カスタムボタンを配置したページ:https://ap2.salesforce.com/
となっており、ホストが一致していません。
ということは、今回の目的を達成することはできないのか。。。
・ひと工夫してみる
工夫さえすればなんでもできる!
【addEventListener】と【postMessage】を使いましょう!
作成したVisualforceページを下記のように編集します。
<apex:page standardController="Account" sidebar="false" id="page">
<script type="text/javascript">
var MYORIGIN = "https://ap2.salesforce.com";
window.addEventListener("message", function(e) {
if(e.origin == MYORIGIN && e.data == "goProcess") {
alert("処理を開始します!!");
}
}, false);
</script>
<apex:form id="form">
<div style="height:80px; background-color:#99FFCC; text-align:center;">ここにVisualforceページが埋め込まれています。</div>
</apex:form>
</apex:page>
次に、カスタムボタンの処理を下記のように編集します。
//フレームのID : 06628000006aOt4
var MYORIGIN = "https://c.ap2.visual.force.com";
var frame = document.getElementById("06628000006aOt4");
frame.contentWindow.postMessage("goProcess", MYORIGIN );
これでOK!早速カスタムボタンを動作すると。。。
動いてくれました~
これで、取引先ページレイアウトがこんなにもすっきりとしました!
埋め込んだVisualforceページをカスタムボタンで制御したい!と考えていた方は、是非参考にしてください!