Visualforceページのプルダウンリストでパラメータを変更する:2つ連動の場合

   

Visualforceページを使ってダッシュボードを作ることがままあるのですが、URLパラメータを付与して表示を変えたりすることがあると思います。

その場合はVisualvoceページ側にjavascriptを記述してゴニョゴニョする必要があったりして、js初学者にはツラい。

やっとこAPEXに慣れてきたのに今度はフロントエンドかよ…となった人は使ってみてください。

今回実現するのはこんな感じのプルダウンメニューです。

左側の名前をセレクトすると、それに紐付いた右側のプルダウンメニューが変化します。Goボタンを押すと、該当データを表示するためのパラメータが付与されたURLへと飛んでいきます。

連動プルダウンの仕組み

仕組みは色々と調べてみた結果、一番簡単なのは全てのプルダウンメニューをレンダリングしてしまって、jsで表示を切り替えるというものでした。

最初にapex側で2つのリスト(それ以上の場合でも基本的には同じでしょう)を表示してしまいましょう。それが以下のコードです。

Visualforceページ

リストレンダリング部分

  <form name="userindex">
    <div class="pulldownset">
    <select name="userName" class="slds-select mainselect" style="width:8em;">
        <apex:repeat value="{!UserNameList}" var="unl">
            <option value="{!unl.Id}">{!unl.Name}</option>
        </apex:repeat>
    </select>

    <apex:outputText value="{!subList}" escape="false" />
     
    <input type="button" value="GO" onclick="jump();" />
    </div>
  </form>

js部分

jsでuserNameで選択されたvalueを元にsubリストのvalueと照合して表示非表示を切り替える
jumb()はプルダウンメニューで選択されているvalueを元に該当URLへと遷移するためのシンプルなボタンです。

<script type="text/javascript">

// ▼HTMLの読み込み直後に実行:
var targetSub;
var targetSubtext;
document.addEventListener('DOMContentLoaded', function() {

   // ▼全てのプルダウンメニューセットごとに処理
   var mainBoxes = document.getElementsByClassName('pulldownset');
   for( var i=0 ; i<mainBoxes.length ; i++) {
   
      var mainSelect = mainBoxes[i].getElementsByClassName("mainselect");   // 1階層目(メイン)のプルダウンメニュー(※後でvalue属性値を参照するので、select要素である必要があります。)
            targetSub = document.getElementById( mainSelect[0].value );   // 「1階層目のプルダウンメニューで選択されている項目のvalue属性値」と同じ文字列をid属性値に持つ要素を得る
            targetSub.style.display = 'inline';

      mainSelect[0].onchange = function () {
         // ▼同じ親要素に含まれているすべての2階層目(サブ)要素を消す
         var subBox = this.parentNode.getElementsByClassName("subbox");   // 同じ親要素に含まれる.subbox(※select要素に限らず、どんな要素でも構いません。)
         for( var j=0 ; j<subBox.length ; j++) {
            subBox[j].style.display = 'none';
         }
   
         // ▼指定された2階層目(サブ)要素だけを表示する
         if( this.value ) {
            targetSub = document.getElementById( this.value );   // 「1階層目のプルダウンメニューで選択されている項目のvalue属性値」と同じ文字列をid属性値に持つ要素を得る
            targetSub.style.display = 'inline';
         }
      }
   
   }

});


  function jump(){
        location.href = '/apex/Visualforceページ名?userID=' + userindex.userName.value + '&id=' + targetSub.value + '&subkey=' + targetSub.options[targetSub.selectedIndex].text;

  }


  //選択されたパラメータをページ表示タイミングで選択された状態にしたい
  //変数argはオブジェクトですよ
  var arg = new Object;

  // 変数pairにURLの?の後ろを&で区切ったものを配列にして代入
  var pair = location.search.substring(1).split('&');
      // location.search.substring(1)は、URLから最初の1文字 (?記号) を除いた文字列を取得する
      // .split('&')は&で区切り配列に分割する

  // for文でrairがある限りループさせる
  for(var i=0;pair[i];i++) {
    // 変数kvにpairを=で区切り配列に分割する
      var kv = pair[i].split('=');// kvはkey-value
    // 最初に定義したオブジェクトargに連想配列として格納
      arg[kv[0]]=kv[1];  // kv[0]がkey,kv[1]がvalue
  }

  //SELECTに設定
  if(arg.userName != ''){
    document.form.userName.value=arg.userName;      
  }
  if(arg.period != ''){
    document.targetSub.value=targetSub.value;
  }

</script>

実際に表示されるHTML

*js部分はそのまま表示されるので割愛

<form name="userindex">
    <div class="pulldownset">
    <select class="slds-select mainselect" name="userName" style="width:8em;">
            <option value="00************AAA">名前A</option> <!-- valueの値はSalesforceのユーザーIDです -->
            <option value="00************AAB">名前B</option> <!-- valueの値はSalesforceのユーザーIDです -->
            <option value="00************AAC">名前C</option> <!-- valueの値はSalesforceのユーザーIDです -->
    </select>
    <select name="period" id="00************AAA" class="subbox">
    	<option value="必要なパラメータ">2017-08</option> <!-- valueの値は何かしら必要なパラメータ -->
    	<option value="必要なパラメータ">2017-07</option> <!-- valueの値は何かしら必要なパラメータ -->
    	<option value="必要なパラメータ">2017-06</option> <!-- valueの値は何かしら必要なパラメータ -->
    	<option value="必要なパラメータ">2017-05</option> <!-- valueの値は何かしら必要なパラメータ -->
    </select>
    <select name="period" id="00************AAB" class="subbox">
    	<option value="必要なパラメータ">2017-08</option> <!-- valueの値は何かしら必要なパラメータ -->
    	<option value="必要なパラメータ">2017-07</option> <!-- valueの値は何かしら必要なパラメータ -->
    </select>
    <select name="period" id="00************AAC" class="subbox">
    	<option value="必要なパラメータ">2017-08</option> <!-- valueの値は何かしら必要なパラメータ -->
    </select>
    <input onclick="jump();" type="button" value="GO" />
    </div>
</form>

Apex

public class yourClass {
    public LIST<User> UserNameList{get;set;}
	public yourClass(ApexPages.StandardController controller) {
		UserNameList = new LIST<User>();
		getUserNameList(UserNameList);
		getSubList(UserNameList); // サブリスト用のデータ取得用のクラスを適当に作る

}

    public List<User> getUserNameList(LIST<User> UserNameList) {
        UserNameList = [SELECT Id,Name From User WHERE IsActive = true];    		
        return UserNameList;
    }
}

おすすめ記事一覧

 - Salesforce