LoginSignup
8
8

More than 5 years have passed since last update.

Visualforce で連動選択リスト

Posted at

結構よくやることだと思うのですが、Visualforce側の書き方を忘れがちなのでメモ

ポイントは
<apex:actionSupport>タグでonchangeイベントを拾う
<apex:actionRegion>タグで他の項目の入力チェックを回避する
の2点です。

まずはVF

DependentSelectList.page
<apex:page controller="DependentSelectListController">
  <apex:form>
    <apex:pageBlock>
      <apex:pageBlockSection columns="1">
        <apex:pageBlockSectionItem>
          <apex:outputLabel value="選択リスト1"/>
          <apex:actionRegion>
            <apex:selectList value="{!selectValue1}" id="selectList1" size="1">
              <apex:selectOptions value="{!selectList1}"/>
              <apex:actionSupport event="onchange" reRender="selectList2"/>
            </apex:selectList>
          </apex:actionRegion>
        </apex:pageBlockSectionItem>
        <apex:pageBlockSectionItem>
          <apex:outputLabel value="選択リスト2"/>
            <apex:selectList value="{!selectValue2}" id="selectList2"
                             size="1" disabled="{!ISBLANK(selectValue1)}">
            <apex:selectOptions value="{!selectList2}"/>
          </apex:selectList>
        </apex:pageBlockSectionItem>
      </apex:pageBlockSection>
    </apex:pageBlock>
  </apex:form>
</apex:page>

選択リスト1の<apex:selectList>タグの中に<apex:actionSupport>タグを入れ、onchangeイベントを拾って選択リスト2を更新するようにしています。

さらに、選択リスト1の<apex:selectList>タグを<apex:actionRegion>タグで囲って、他の項目の入力チェックが動作するのを回避しています。

また、選択リスト2の方は、選択リスト1で値が選択されていない間は、非活性になるようにしています。

続いて、コントローラ

DependentSelectListController.cls
public with sharing class DependentSelectListController {
  public ID selectValue1 {get; set;}
  public ID selectValue2 {get; set;}
  public List<SelectOption> selectList1 {
    get {
      List<SelectOption> selectOptions 
       = new List<SelectOption> { new SelectOption('', '-なし-') };

      for(Example__c e : [
        SELECT ID
             , Name
          FROM Example__c
         WHERE IsValid__c = true
         ORDER BY DisplayOrder__c]
      ) {
        selectOptions.add(new SelectOption(e.ID, e.Name));
      }

      return selectOptions;
    }
  }
  public List<SelectOption> selectList2 {
    get {
      List<SelectOption> selectOptions 
       = new List<SelectOption>{new SelectOption('', '-なし-')};

      for(ExampleChild__c ec : [
        SELECT ID
             , Name
          FROM ExampleChild__c
         WHERE IsValid__c = true
           AND Example__c = :selectValue1
         ORDER BY DisplayOrder__c
      ]) {
        selectOptions.add(new SelectOption(ec.ID, ec.Name));
      }

      return selectOptions;
    }
  }

  public DependentSelectListController() {
  }
}

選択リストの中身は、今回は一番よく使いそうな親子関係にあるオブジェクトを表示する形式にしています。
親レコードを選択リスト1に、その子レコードを選択リスト2にセットします。

余談ですが、Keyに空文字列をセットしたSelectOprionをnewしていますが、VFでこの選択肢を選択した場合にクラス側に渡ってくる値は、なぜかnullになるっぽいです。
まぁ、受け取る変数の型がIDだったり、数値だったりのときにエラーにならないためでしょうかね。

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8