前に上記のような2段階でのステータス表示について、lightning:picklistPathを使ったアイデアを書きました。
crmprogrammer38.hatenablog.com
そのアイデアの実装内容になります。
実装内容
- パスによる1段階目のステータスと、lightning:picklistPathによる2段階目のステータスを表示
- 2段階目のステータスは1段階目のステータスの連動項目のみを表示
- 2段階目のステータスのリスト値をクリックすると確認ダイアログを表示後、値を変更する。
オブジェクト項目
オブジェクト:サブのパス(SubPath__c)
選択リスト(制御):ステータスLv1(StatusLv1__c)
選択リスト(連動):ステータスLv2(StatusLv2__c)
選択リストの連動関係
ステータスLv1 |
ステータス1 |
ステータス2 |
ステータス3 |
ステータス4 |
ステータス5 |
ステータスLv2 |
ステータスA |
|
|
|
|
ステータスB |
|
|
|
|
ステータスC |
ステータスC |
|
|
|
ステータスD |
ステータスD |
|
|
|
ステータスE |
ステータスE |
ステータスE |
|
|
|
ステータスF |
ステータスF |
ステータスF |
|
|
ステータスG |
ステータスG |
ステータスG |
|
|
|
ステータスH |
ステータスH |
|
|
|
ステータスI |
ステータスI |
ステータスI |
|
|
|
ステータスJ |
ステータスJ |
|
|
|
ステータスK |
ステータスK |
ステータスLv2の連動設定に対応する選択リスト項目
ステータスLv2_1(StatusLv2_1__c):ステータス1の連動項目
ステータスLv2_2(StatusLv2_2__c):ステータス2の連動項目
ステータスLv2_3(StatusLv2_3__c):ステータス3の連動項目
ステータスLv2_4(StatusLv2_4__c):ステータス4の連動項目
ステータスLv2_5(StatusLv2_5__c):ステータス5の連動項目
作成したトリガ
今回の実装では、ステータスLv2の連動設定に対応する選択リスト項目を用意したので、その項目は常にステータスLv2と同期するようにトリガを作成した。
trigger SubPathTrigger on SubPath__c (before insert , before update) {
for(SubPath__c newrow : Trigger.New ){
//常に同期する
newrow.StatusLv2_1__c = newrow.StatusLv2__c;
newrow.StatusLv2_2__c = newrow.StatusLv2__c;
newrow.StatusLv2_3__c = newrow.StatusLv2__c;
newrow.StatusLv2_4__c = newrow.StatusLv2__c;
newrow.StatusLv2_5__c = newrow.StatusLv2__c;
}
}
作成したクラス
lightning:picklistPathの表示で、どの選択リスト項目を表示するかの制御と lightning:picklistPath上で選択したリスト値を更新する処理を作成した。
public without sharing class SubPathPickList {
//ステータスLv1の値に応じて表示する選択リストのフィールドを返す
@AuraEnabled
public static String getLv2PickFieldName(String salesforceId){
List rows = [select Id, StatusLv1__c From SubPath__c where Id =:salesforceId ];
Map<String, String> fieldMapForLv1 = new Map<String,String>();
fieldMapForLv1.put('ステータス1','StatusLv2_1__c');
fieldMapForLv1.put('ステータス2','StatusLv2_2__c');
fieldMapForLv1.put('ステータス3','StatusLv2_3__c');
fieldMapForLv1.put('ステータス4','StatusLv2_4__c');
fieldMapForLv1.put('ステータス5','StatusLv2_5__c');
String fieldName = 'StatusLv2_1__c';
if( rows.isEmpty() == false){
if( fieldMapForLv1.get(rows[0].StatusLv1__c) != null ){
fieldName = fieldMapForLv1.get(rows[0].StatusLv1__c);
}
}
return fieldName;
}
//ステータスLv2の値を更新
@AuraEnabled
public static Boolean setLv2PickFieldValue(String salesforceId, String pickValue){
List rows = [select Id From SubPath__c where Id =:salesforceId ];
if( rows.isEmpty() == true){
return false;
}
rows[0].StatusLv2__c =pickValue ;
try{
update rows;
return true;
} catch( Exception ex){
return false;
}
}
}
作成したLightning Component
モーダル確認ダイアログ用にbodyとfooterを用意
[ConfirmDialogBody] Component
<aura:component>
<aura:attribute name="messageText" type="String"></aura:attribute>
<div class="slds-align_absolute-center">{!v.messageText}</div>
</aura:component>
[ConfirmDialogFooter] Component
<aura:component>
<aura:attribute name="modalResult" type="String"></aura:attribute>
<lightning:overlaylibrary aura:id="overlayLib"></lightning:overlaylibrary>
<lightning:button variant="neutral" label="キャンセル" onclick="{! c.handleCancel }"></lightning:button>
<lightning:button variant="brand" label="OK" onclick="{! c.handleOK }"></lightning:button>
</aura:component>
[ConfirmDialogFooter] Component
({
handleOK: function(cmp, event, helper) {
cmp.set("v.modalResult", "OK");
cmp.find("overlayLib").notifyClose();
},
handleCancel: function(cmp, event, helper) {
cmp.set("v.modalResult", "Cancel");
cmp.find("overlayLib").notifyClose();
}
});
Lightningページ上に表示するLightning Component
[SubPath] Component
<aura:component
controller="SubPathPickList"
implements="flexipage:availableForAllPageTypes,force:hasRecordId"
access="global"
>
<lightning:overlayLibrary aura:id="overlayLib" />
<aura:attribute name="recordId" type="String" />
<aura:attribute name="modalResult" type="String" />
<aura:attribute name="pickField" type="String" default="StatusLv2_1__c" />
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
<aura:handler event="force:refreshView" action="{!c.doInit}" />
<lightning:picklistPath
aura:id="picklistPath"
recordId="{!v.recordId}"
variant="non-linear"
picklistFieldApiName="{!v.pickField}"
onselect="{!c.handleSelect}"
></lightning:picklistPath>
</aura:component>
[SubPath] Controller
({
doInit: function(component, event, helper) {
var recordId = component.get("v.recordId");
var fetchEventAction = component.get("c.getLv2PickFieldName");
fetchEventAction.setParams({ salesforceId: recordId });
fetchEventAction.setCallback(this, function(response) {
var fieldName = response.getReturnValue();
component.set("v.pickField", fieldName);
});
$A.enqueueAction(fetchEventAction);
},
handleSelect: function(component, event, helper) {
var recordId = component.get("v.recordId");
var stepName = event.getParam("detail").value;
$A.createComponents(
[
[
"c:ConfirmDialogBody",
{ messageText: "ステータスLv2を" + stepName + "に更新しますか?" }
],
[
"c:ConfirmDialogFooter",
{ modalResult: component.getReference("v.modalResult") }
]
],
function(components, status) {
if (status == "SUCCESS") {
component.find("overlayLib").showCustomModal({
header: "ステータスLv2を更新",
body: components[0],
footer: components[1],
showCloseButton: true,
closeCallback: function() {
if (component.get("v.modalResult") == "OK") {
var updateAction = component.get("c.setLv2PickFieldValue");
updateAction.setParams({
salesforceId: recordId,
pickValue: stepName
});
updateAction.setCallback(this, function(response) {
if (
response.getState() == "SUCCESS" &&
response.getReturnValue()
) {
$A.get("e.force:refreshView").fire();
//refreshViewと同じタイミングでtoastの再描画を防ぐ
window.setTimeout(
$A.getCallback(function() {
var toastEvent = $A.get("e.force:showToast");
toastEvent.setParams({
message: stepName + "に更新しました。",
type: "success"
});
toastEvent.fire();
}),
1000
);
} else {
var toastEvent = $A.get("e.force:showToast");
toastEvent.setParams({
message: stepName + "の更新に失敗しました。",
type: "error"
});
toastEvent.fire();
}
});
$A.enqueueAction(updateAction);
}
}
});
}
}
);
}
});
lightning:picklistPathの「onselect」アクションでは、選択された選択リスト値のAPI参照名が取得できます。表示ラベルは取得できないので表示ラベルを使いたい場合は、Apexで取得してくるなどの処理が必要になります。