【Apex+Visualforce】親画面と子画面で値を受け渡すサンプル

Salesforce

Visualforceページで、親画面・子画面間の値を受け渡す方法。
色々なやり方があると思うので、いちサンプルです。

サンプルソース

親画面

<!-- 親画面 -->
<apex:page id="pg" controller="OyaPageController">
    <apex:form id="frm">
        <apex:commandButton value="小画面表示" onclick="showPopup();" />
    </apex:form>
    <script type="text/javascript">
    	// 小画面表示を表示してパラメータを渡す
    	function showPopup() {
            var param1 = '12345';
            var param2 = 'あああああ';
            
            // URLにパラメータを付与
            var url = '/apex/KoPage'
            url += '?param1=' + param1;
            url += '&param2=' + param2;
            
            // 小画面表示(新規ウィンドウ)
            window.open(url, 'newwindow', 'width=300,height=200');
        }
    
    	// 小画面からパラメータを受け取る
    	function getParamFromPopup(paramKo1, paramKo2) {
            alert('小画面から受け取ったパラメータ\n'
                  + '・' + paramKo1 + '\n'
                  + '・' + paramKo2);
        }
    </script>
</apex:page>
/**
 * 親画面コントローラ.
 */
public class OyaPageController {

    /**
     * コンストラクタ.
     */
    public OyaPageController() {
    }
}

親画面から子画面へは、URLにパラメータをくっつけて渡してます。

子画面

<!-- 小画面 -->
<apex:page id="pg" controller="KoPageController">
    <apex:form id="frm">
        <p>親画面から受け取ったパラメータ</p>
        <ul>
            <li>{!param1}</li>
            <li>{!param2}</li>
        </ul>
        <apex:commandButton value="小画面を閉じる" onclick="closePopup();" />
    </apex:form>
    <script type="text/javascript">
    	// 小画面を閉じてパラメータを渡す
    	function closePopup() {
            var paramKo1 = '67890';
            var paramKo2 = 'いいいいい';
            
            // 親画面のfunctionを実行
            window.opener.getParamFromPopup(paramKo1, paramKo2);
            
            // 小画面を閉じる
            window.close();
        }
    </script>
</apex:page>
/**
 * 小画面コントローラ.
 */
public class KoPageController {
    
    /** 親画面より受け取ったパラメータ */
    public String param1{get; private set;}
    public String param2{get; private set;}

    /**
     * コンストラクタ.
     */
    public KoPageController() {
        // URLパラメータ取得
        Map<String, String> paramMap = apexPages.currentPage().getParameters();
        this.param1 = paramMap.get('param1');
        this.param2 = paramMap.get('param2');
    }
}

子画面から親画面へは、親画面のJavascript経由でパラメータを渡してます。

動作確認

親画面を表示。

「小画面表示」ボタンをクリックで、小画面を表示する。ちゃんとパラメータが渡っている。

「小画面を閉じる」ボタンクリックで、小画面が閉じる。親画面にもちゃんとパラメータが渡っている。

ちなみにAPI Versionは46です。

メモ:小画面から、親画面のコンポーネントに値を設定する

サンプルソースでは小画面→親画面にJavascript経由で値を渡しているが、window.openerを使って、親画面のコンポーネントに直接値を設定することもできる。

ためしに親画面にこんなのを付け足して

<apex:form id="frm">
    <apex:commandButton value="小画面表示" onclick="showPopup();" />
    <p>小画面から受け取った値1:<apex:outputText id="receveParam1" value="" /></p>
    <p>小画面から受け取った値2:<apex:outputText id="receveParam2" value="" /></p>
</apex:form>

小画面のJavascriptから、そいつらに値を設定してやる。

// 小画面を閉じてパラメータを渡す
function closePopup() {
    var paramKo1 = '67890';
    var paramKo2 = 'いいいいい';
            
    // 親画面のコンポーネントに値を設定する
    window.opener.document.getElementById('pg:frm:receveParam1').innerHTML = paramKo1;
    window.opener.document.getElementById('pg:frm:receveParam2').innerHTML = paramKo2;
            
    // 小画面を閉じる
    window.close();
}

こんな感じで、小画面から親画面のコンポーネントに直接値を設定できた。

上記では小画面から親画面に値を設定する例を書いたが、同じ要領で小画面から親画面の値を参照することも可能。

VisualforceにおけるgetElementByIdの使い方は下記を参照。
【Visualforce】JavascriptからgetElementByIdで値を参照する方法

メモ:小画面から実行する親画面のfunctionを可変にしたい場合

サンプルソースでは小画面から実行する親画面のJavascriptのfunctionをベタで書いた。

// 親画面のfunctionを実行
window.opener.getParamFromPopup(paramKo1, paramKo2);

例えばこのfunctionを可変にしたい場合。
小画面が閉じられた時、常にgetParamFromPopup()を実行するのではなく、条件によっては別のfunctionを実行したい場合。

パッと思いつくのはevalを使う方法。

// 小画面を閉じてパラメータを渡す
// ※実行させる親画面のfunction名をパラメータで受ける想定で書いてみる(function名は文字列として)
function closePopup(func) {
    var paramKo1 = '67890';
    var paramKo2 = 'いいいいい';
            
    // 親画面のfunctionを実行
    var code = 'window.opener.' + func + '("' + paramKo1 + '","' + paramKo2 + '");';
    eval(code);
            
    // 小画面を閉じる
    window.close();
 }

これで一応やりたいことはできるけど、うーん、どうなんでしょーか。

なんか他にやり方ないのかなーと探していたら、こんなのを見つけたので参考に実装してみる。結論から言うと、eval使わずにfunctionを可変にできました(ありがとうございます)。
関数名を文字列で指定して動的に呼び出す機構(evalを使わず)

まずは親画面のfunctionを配列化する。検証のため getParamFromPopup1 と getParamFromPopup2 を作る。

/*
 * 親画面のJavascript(書き換え部分のみ抜粋)
 */

var funcObj = new Array;
    
// 小画面からパラメータを受け取る(パターン1)
funcObj.getParamFromPopup1 = function(paramKo1, paramKo2) {
    alert('小画面から受け取ったパラメータ\n'
          + '・' + paramKo1 + '\n'
          + '・' + paramKo2);
}
        
// 小画面からパラメータを受け取る(パターン2)
funcObj.getParamFromPopup2 = function(paramKo1, paramKo2) {
    alert('小画面から受け取ったパラメータは ' + paramKo1 + ' と ' + paramKo2);
}

そんで小画面のJavascript処理をこんな感じにする。

// 小画面を閉じてパラメータを渡す
// ※実行させる親画面のfunction名をパラメータで受ける想定で書いてみる(function名は文字列として)
function closePopup(func) {
    var paramKo1 = '67890';
    var paramKo2 = 'いいいいい';
            
    // 親画面のfunctionを実行
    window.opener.funcObj[func](paramKo1, paramKo2);
            
    // 小画面を閉じる
    window.close();
 }

小画面を閉じる時のパラメータが func=”getParamFromPopup1″の場合

続いてfunc=”getParamFromPopup2″の場合

やったぜ父ちゃん!!

コメント

タイトルとURLをコピーしました