出来ないと思ってたのです
カスタムコンポーネントの動的選択リストの作成 に記載がある通りなのですが、最近まで全然知らなかった。 Apex はまじで奥が深い・・・。
Lightning アプリケーションビルダーでコンポーネントが設定されるときに、コンポーネントのプロパティを選択リストとして公開できます。選択リストの値は、作成する Apex クラスによって提供されます。
VisualEditor を使う
Apex のライブラリには、 VisualEditor という名前空間があります。
これに含まれる DynamicPickList クラスを継承したカスタムクラスを Lightning コンポーネントのデザインファイルにデータソースとして指定する事で、アプリケーションビルダーで動的な選択リストを表示する事が出来ます。
MyCustomPickList.apxc
global class MyCustomPickList extends VisualEditor.DynamicPickList{
global override VisualEditor.DataRow getDefaultValue(){
VisualEditor.DataRow defaultValue = new VisualEditor.DataRow('red', 'RED');
return defaultValue;
}
global override VisualEditor.DynamicPickListRows getValues() {
VisualEditor.DataRow value1 = new VisualEditor.DataRow('red', 'RED');
VisualEditor.DataRow value2 = new VisualEditor.DataRow('yellow', 'YELLOW');
VisualEditor.DynamicPickListRows myValues = new VisualEditor.DynamicPickListRows();
myValues.addRow(value1);
myValues.addRow(value2);
return myValues;
}
}
MyCustomPickList.design
<design:component>
<design:attribute name="property1" datasource="apex://MyCustomPickList"/>
</design:component>
SObject のリストを表示する
SObject のリストを選択リストで表示したい時のサンプルコードです。
DataRow クラスのリストに対して sort がうまく動かなかったので、面倒ですがラッパークラスで一度ソートする事にしました。
SObjectTypes.apxc
global class SObjectTypes extends VisualEditor.DynamicPickList {
// 未選択用の DataRow
private static final VisualEditor.DataRow EMPTY_DATAROW = new VisualEditor.DataRow('', null);
// メンバー変数
private VisualEditor.DesignTimePageContext context; // Lightning コンポーネントが配置されたページの情報
private VisualEditor.DynamicPickListRows dynamicPickListRows; // 表示する選択肢
// コンストラクター
// 選択リストを初期化する
global SObjectTypes(VisualEditor.DesignTimePageContext context) {
this.context = context;
this.dynamicPickListRows = new VisualEditor.DynamicPickListRows();
this.dynamicPickListRows.addRow(EMPTY_DATAROW);
for (SObjectType sObjType : getSortedSObjectTypeList()) {
this.dynamicPickListRows.addRow(new VisualEditor.DataRow(sObjType.label, sObjType.name));
}
}
// デフォルト値を返す
// レコードページの場合はレコードのおブジェクトタイプを返す。それ以外であれば空白
global override VisualEditor.DataRow getDefaultValue() {
if (context.pageType == 'RecordPage') {
for (VisualEditor.DataRow row : this.dynamicPickListRows.getDataRows()) {
if (row.getValue() == context.entityName) return row;
}
}
return EMPTY_DATAROW;
}
// 選択リストを返す
global override VisualEditor.DynamicPickListRows getValues() {
return this.dynamicPickListRows;
}
// SObject をラベル名で昇順に並べ替えるためのラッパークラス。
private class SObjectType implements Comparable {
public String label;
public String name;
public SObjectType(String name) {
Schema.DescribeSObjectResult dsor = Schema.getGlobalDescribe().get(name).getDescribe();
this.label = dsor.getLabel();
this.name = dsor.getName();
}
public Integer compareTo(Object compareTo) {
SObjectType other = (SObjectType)compareTo;
if (this.label > other.label) return 1;
if (this.label < other.label) return -1;
return 0;
}
}
// ソートされた SObjectType のリストを返す
private List<SObjectType> getSortedSObjectTypeList() {
List<SObjectType> ret = new List<SObjectType>();
for (String name : Schema.getGlobalDescribe().keySet()) {
ret.add(new SObjectType(name));
}
ret.sort();
return ret;
}
}
SObjectPickListSample.design
<design:component>
<design:attribute name="objectName" label="Salesforce Object Name" datasource="apex://SObjectTypes"/>
</design:component>