結構よくやることだと思うのですが、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だったり、数値だったりのときにエラーにならないためでしょうかね。