Salesforce技術ブログ(レイアウトに埋め込まれたVisualforceページを、カスタムボタンで動かしてみよう!)

Salesforce技術ブログ(レイアウトに埋め込まれたVisualforceページを、カスタムボタンで動かしてみよう!)

Salesforce技術ブログ(レイアウトに埋め込まれたVisualforceページを、カスタムボタンで動かしてみよう!)

こんにちは、マルシェ丸岡です!
某ⅩⅤの発売が9月末から11月末へ延期となり、傷心気味です。。。

ある日、エンドユーザ様からご依頼が。
「Salesforceで取引先の情報共有をもっと簡単にしたい!」
「Chatterだとメンションをミスしたり、標準のメール送信画面も正直使いづらい・・・」

そこで取引先のレコード詳細画面に、Visualforceページで開発した【Chatter情報共有機能】を埋め込むことに。
ユーザを指定すれば、そのユーザへのメンション付きでChatterに投稿してくれるものです。
取引先チーム全員への一括メンション機能も完備!さぁこれを存分にご利用ください!!

・・・しかし、喜んでいただけると考えていた矢先、以下のようなご要望が・・・



ボタンが点在してて、ちょっと混乱します・・・ボタンの位置を集約できませんか?
PCT07_追加キャプチャ

たしかに、ごもっともでございます。。。
ということで、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ページを、取引先のページレイアウトに埋め込みましょう。



PCT02_VF埋め込み後

・カスタムボタンを作って、動かしてみる。

埋め込んだVisualforceページ内のJavascript処理【iframeProccess】を、カスタムボタンから動かしてみます。
まずはiframeのIDを確認しましょう。
以下はChromeのデベロッパーツールを用いてIDを確認している図です。

PCT03_iframeのID確認

IDが確認できたら、下記の処理を組み込んだカスタムボタンを作成します。
表示の種類は「詳細ページボタン」、動作は「Javascriptを実行」です。



//フレームのID : 06628000006aOt4
document.getElementById('06628000006aOt4').contentWindow.iframeProcess(); 



早速、作成したカスタムボタンをクリック!「処理を開始します!」とアラート表示されれば成功ですが。。。

PCT04_カスタムボタンうごかへん

謎のエラーで動いてくれない。。。



・動かない原因は?

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!早速カスタムボタンを動作すると。。。

PCT05_カスタムボタンうごいた

動いてくれました~




これで、取引先ページレイアウトがこんなにもすっきりとしました!
PCT08_追加キャプチャ

埋め込んだVisualforceページをカスタムボタンで制御したい!と考えていた方は、是非参考にしてください!

简体中文English日本語한국어
翻訳