見出し画像

やっとVisualforceが完成形になったのでまとめ

これまでも色々なものをVisualforceで作ってきました。昨今ではLWCというものが盛り上がっているのですが、シンプルに印刷用の帳票作るんだったらVisualforceが楽だよなと思っています。

さて、そんなVisualforceの何が完成形なのかについて。

弊社リバネスでは、あらゆるデータをSalesforce上に集めて、それを使ったデータの出力を行うことは日常茶飯事なのですが、その中で実装したいことがいくつかありました。

実装したい条件

1:URLパラメータで情報を出し分けしたい。URL共有するから
2:ページ上のセレクトボックス等を使って条件を変更してrerenderしたい
2−2:条件を変更したらURLも同じ条件で自動的に書き換えたい
1−2:1を行ったときに、2のセレクトボックス等のデータをURLパラメータに入ってる内容にセットしたい

というものでした。

1はVisualforceで処理するなら比較的簡単で、URLパラメータは

ApexPages.CurrentPage().getParameters().get('パラメータ名');

という形式で取得できる。これは簡単。

2の実装について

実装方法は、jsでApexを呼び出してrerenderでページをリフレッシュすること無く内容を書き換えたい。これもそれほど難しいことはなく、慣れれば簡単にできるはず。ただ、著者である私はjsに明るくないので、そもそものパラメータの渡し方とか調べるのが面倒だったんですよね…今回ちゃんと勉強して実装してみました。時間かかってしまった。

Visualforce側からApexへの引数の渡し方は

<apex:actionFunction name="ActionFunction名" action="{!Apexのクラス名}" reRender="書き換えたいID" >
  <apex:param name="変数名1" value="変数名1" />
  <apex:param name="変数名2" value="変数名2" />
</apex:actionFunction>

こんな形式で、変数を設定し、Apex側で受け取ります。

Apex側では

public String 変数名1{get;set;}
public String 変数名2{get;set;}

という形式で変数を設定しておきましょう。これで受け取るための準備は完了です。

Visualforceに戻ります。
Visualforceで先程のactionFunctionをjsから呼び出す必要があります。

例えば、ドロップダウンリストの選択値が変更された場合にjsを呼ぶとします。

<apex:form id="Apexform名">
<select name="ドロップダウンリストの名前" id="ドロップダウンリストの名前" onchange="js関数名()">
       <option value="0">0</option>
       <option value="1">1</option>
</select>
</apex:form>

簡単なドロップダウンリストにしました。onchangeで変更を拾って、js関数名()で指定した関数を呼び出します。apex:formの間にはさみます。

onchangeで呼ばれるjsはこんな形です。

<script type="text/javascript">    
   function js関数名() {
       var selectList = document.getElementById('{!$Component.Apexform名}').ドロップダウンリストの名前;
       var selectednum = selectList.selectedIndex;
       var p_selected = selectList.options[selectednum].value;
       
       ActionFunction名(p_selected,p_selected2);  // 先程書いたactionFunctionのパラメータ設定が2つになっていたので便宜上p_selected2を加えていますが、このへんは適宜調整ください。
      }
</script>

onchangeでjs関数名が呼ばれて、そこから各種変数をしゅとくしてActionFunctionを呼び出し、引数p_selected,p_selected2を渡しています。

これだけだとURLが切り替わらないので一行追加します。

<script type="text/javascript">    
   function js関数名() {
       var selectList = document.getElementById('{!$Component.Apexform名}').ドロップダウンリストの名前;
       var selectednum = selectList.selectedIndex;
       var p_selected = selectList.options[selectednum].value;
       
       ActionFunction名(p_selected,p_selected2);  // 先程書いたactionFunctionのパラメータ設定が2つになっていたので便宜上p_selected2を加えていますが、このへんは適宜調整ください。
       
       window.history.pushState(null, null, '/apex/VisualforcePage名?p_selected=' + p_selected + '&p_selected2=' + p_selected2);//これでURLが書き換わります
      }
</script>

これでURLが書き換わります。Apexが呼ばれてrerenderで内容が書き換わります。HTML自体は、LIST<String>に入れてしまってrepeatで処理する形が楽なのでそうやっちゃってます。

        <apex:outputPanel id="actionFunctionのreRenderに書いた書き換えたいID">
           <apex:repeat value="{!StringList名}" var="st">
               <apex:outputText value="{!st}" escape="false" />    
           </apex:repeat>
       </apex:outputPanel>

これでHTML側(VisualforcePage)からjsでデータをApexの変数に渡してreRenderで書き換える処理が完成しました。

一つの工夫について

このVisualforcePageでは、onchangeで拾ってきたパラメータで表示を書き換える機能と、指定されたURLパラメータを使ってデータを表示する機能があります。それぞれの値を受け取る変数は2つに分けましょう。

例えば日付を格納するような項目があったとしたら

public String p_date{get;set;}
public String s_date{get;set;}

というように、URLパラメータ用と、セレクトボックス等のデータ用の2つに分けて、どちらかが存在したときにその値を使うような形にします。

String datestring;
       if(p_date!=NULL){
           datestring = p_date;
       }else{
           datestring = s_date;
       }

こうしておけば値が競合しません。

最後に、URLパラメータを含んだ状態で開いた場合に、セレクト等をそのデータで上書きするjsです

	window.onload = function() {
       //パラメータを取得する
       var params = getParameter();
       if(params['p_date']!==""){
           $("#ドロップダウンリストの名前").val(params['p_date']);
       }
   }
   function getParameter(){
       var paramsArray = [];
       var url = location.href; 
       parameters = url.split("#");
       if( parameters.length > 1 ) {
           url = parameters[0];
       }
       parameters = url.split("?");
       if( parameters.length > 1 ) {
           var params = parameters[1].split("&");
           for ( i = 0; i < params.length; i++ ) {
               var paramItem = params[i].split("=");
               paramsArray[paramItem[0]] = paramItem[1];
           }
       }
       return paramsArray;
   };

window.onloadで、ページをロードした時のみに発動させます。
URLパラメータをgetParameter関数で取得し、その値を使ってドロップダウンリストのvalueを置き換えます。

ここまでで完成です。やっと理想形になりました。

コードはこちらへ

これにてVisualforce開発を引退してLWC開発に勤しみたいとおもいます。


noteにはこれまでの経験を綴っていこうかと思います。サポートによって思い出すモチベーションが上がるかもしれない。いや、上がるはずです。