MENU
Abo
某SIer勤務。
新卒文系からエンジニア就職。
日々の学びをつらつらと書いています。
保有資格:
Salesforce認定アドミニストレーター  
Salesforce認定Platformデベロッパー
Salesforce認定上級Platformデベロッパー
カテゴリー
アーカイブ

【Aura】lightning:datatableにRow Actionを追加【編集・詳細・削除】

今回は以前作成したlightning:datatableを用いた関連リストに行アクション機能を追加していきます。

追加するのは次の3つのアクションです。

  • レコードの詳細表示
  • レコードの編集
  • レコードの削除

lightning:datatable内にonrowactionを追加し、controller.jsのhandleRowActionメソッドを呼び出します。
また、削除処理時にはレコード削除確認用のモーダル画面を表示したいので、showConfirmDialogを属性に持たせ、行の削除ボタンを押下した際に確認のモーダル画面が開くようにします(L74~92)。

<aura:component controller="ContactList" implements="force:appHostable,flexipage:availableForRecordHome,force:hasRecordId" access="global" >
    
    <!--関連リスト表示用-->
    <aura:attribute name="recordId" type="Id"/>
    <aura:attribute name="conList" type="contact[]" />
    <aura:attribute name="mycolumns" type="List[]"/>
    <aura:attribute name="contactNumber" type="Integer" />
    
    <!--ページネーション用-->
    <aura:attribute name="pageSize" type="Integer" default="10" />        <!--1ページに表示するレコード数-->
    <aura:attribute name="currentPageNumber" type="Integer" default="1"/> <!--現在のページNo-->
    <aura:attribute name="totalPages" type="Integer" default="0" />
    <aura:attribute name="filteredData" type="List" />
    
    <!--削除確認メッセージ用-->
    <aura:attribute name="showConfirmDialog" type="boolean" default="false"/>
    <aura:attribute name="deleteRecId" type="Id"/>
    
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <aura:handler event="force:refreshView" action="{!c.doInit}"/> <!--リロード時は初期表示処理を呼び出す-->
    
    <lightning:card class="slds-theme_shade" iconName="standard:contact_list">   
        <aura:set attribute="title">
            <a href="https://satsuki-dev-ed.lightning.force.com/lightning/o/Contact/list?filterName=Recent" style="color:#000">関連取引先責任者 ({!(v.filteredData.length)})</a>
        </aura:set>
        <aura:set attribute="actions">
            <lightning:button label="New" onclick="{! c.createRecord}"/>
        </aura:set>
        <lightning:datatable data="{! v.conList }"
                             columns="{! v.mycolumns }"
                             keyField="id"
                             showRowNumberColumn="true"
                             onrowaction="{! c.handleRowAction }" 
                             />
        
        <lightning:card >
            <div >
                <center>
                    <lightning:button class="slds-m-bottom_medium"
                                      label="First"
                                      iconName="utility:left"
                                      iconPosition="left"
                                      onclick="{! c.onFirst }"
                                      disabled="{! v.currentPageNumber == 1 }" />
                    <lightning:button class="slds-m-bottom_medium"
                                      label="Previous"
                                      iconName="utility:chevronleft"
                                      iconPosition="left"
                                      onclick="{! c.onPrev }"
                                      disabled="{! v.currentPageNumber == 1 }" />
                    <span class="slds-m-horizontal_x-small">
                        Page {! v.currentPageNumber } of {! v.totalPages}
                    </span>
                    <span class="slds-m-horizontal_x-small">
                        Number of records: {! (v.filteredData.length) }
                    </span>
                    <lightning:button class="slds-m-bottom_medium"
                                      label="Next"
                                      iconName="utility:chevronright"
                                      iconPosition="right"
                                      onclick="{! c.onNext }"
                                      disabled="{! v.currentPageNumber == v.totalPages  }" />
                    <lightning:button class="slds-m-bottom_medium"
                                      label="Last"
                                      iconName="utility:right"
                                      iconPosition="right"
                                      onclick="{! c.onLast }"        
                                      disabled="{! v.currentPageNumber == v.totalPages }" />
                </center>
            </div>
        </lightning:card>      
    </lightning:card>
    
    <!--削除確認メッセージ-->
    <aura:if isTrue="{!v.showConfirmDialog}">
        <!--モーダル画面-->
        <div role="dialog" class="slds-modal slds-fade-in-open ">
            <div class="slds-modal__container">
                <header class="slds-modal__header">
                    <h1 class="slds-text-heading--medium">取引先責任者を削除</h1>
                </header>
                <div class="slds-modal__content slds-p-around--medium">
                    <center>この取引先責任者を削除しますか?</center>
                </div>                     
                <footer class="slds-modal__footer">
                    <lightning:button name='No' label='キャンセル' onclick='{!c.handleConfirmDialogNo}'/>
                    <lightning:button variant="brand" name='Yes' label='削除' onclick='{!c.handleConfirmDialogYes}'/>
                </footer>
            </div>
        </div>
        <div class="slds-backdrop slds-backdrop--open"></div>            
    </aura:if>
</aura:component>

controller.jsでは、押下されたボタンが「show_details」、「edit」、「delete」かを判定し、それに応じてhelper.jsの処理を呼び出さします。なお、ボタンの定義はhelper.jsで行っています。
また、削除時のモダール画面で「削除」と「キャンセル」を押下した場合の処理も記述しています。

({
    /***
     * 初期表示
     ***/
    doInit : function(component, event, helper) {
        helper.getColumn(component);
        helper.getContact(component);
    },
    
    /***
     * 取引先責任者新規作成
     ***/
    createRecord : function (component, event, helper) {
        var createRecordEvent = $A.get("e.force:createRecord");
        createRecordEvent.setParams({
            "entityApiName": "Contact",
            "defaultFieldValues":{
                "AccountId": component.get("v.recordId")
            }
        });
        createRecordEvent.fire();
    },
    
    /***
     * レコードアクション
     ***/
    handleRowAction: function (component, event, helper) {
        var action = event.getParam('action');
        var row = event.getParam('row');
        var recId = row.Id;
            
        switch (action.name) {
            case "show_details":
                helper.showDetail(component, recId);
                break;
            case 'edit':
                helper.editRecord(component, recId);    
                break;
            case "delete":
                component.set('v.showConfirmDialog', true);
                component.set('v.deleteRecId', recId);
                break;
        }           
    },
    
    /***
     * 削除確認-削除時
     ***/
    handleConfirmDialogYes : function(component, event, helper) {
        component.set('v.showConfirmDialog', false);
        helper.deleteRecord(component, event, helper);
        
    },
    
    /***
     * 削除確認-キャンセル時
     ***/
    handleConfirmDialogNo : function(component, event, helper) {
        component.set('v.showConfirmDialog', false);
    },
    
    
    
    /***
     * ページネーション
     ***/
    //次へ
    onNext: function(component, event, helper) {        
            let pageNumber = component.get("v.currentPageNumber");
            component.set("v.currentPageNumber", pageNumber + 1);
            helper.setPageDataAsPerPagination(component);
    },
        
    //前へ
    onPrev: function(component, event, helper) {        
        let pageNumber = component.get("v.currentPageNumber");
        component.set("v.currentPageNumber", pageNumber - 1);
        helper.setPageDataAsPerPagination(component);
    },
    
    //最初へ
    onFirst: function(component, event, helper) {        
        component.set("v.currentPageNumber", 1);
        helper.setPageDataAsPerPagination(component);
    },
      
    //最後へ
    onLast: function(component, event, helper) {        
        component.set("v.currentPageNumber", component.get("v.totalPages"));
        helper.setPageDataAsPerPagination(component);
    },
})

helper.jsのgetColumnメソッド内で行のボタンと行アクション定義します(L7~9、22)。
L51~94に行アクションの具体的な処理を記述しています。詳細画面を表示する場合は、対象のレコードのidをurlに指定し、「e.force:navigateToURL」を使用して画面遷移します。編集の場合は、「e.force:editRecord」を使用することで編集画面を開くことができます。

削除処理では、「e.force:editRecord」のようなテンプレート処理が用意されていないので、削除処理と削除メッセージを作成する必要があります。削除処理はApexクラス内のdeleteContactメソッドを呼び出して実行します。メッセージについてはshowToastメソッド内の「e.force:showToast」を使用することで表示できます。また、レコード削除後は、reloadDataTable処理を呼び出し、画面のリフレッシュを行うことで最新のレコード一覧を表示することができます。

({
    /***
     * カラム設定
     ***/
    getColumn:function(component){
        var actions = [
            { label: "Detail", name: "show_details" },
            { label: "Edit", name: "edit" },
            { label: "Delete", name: "delete" }           
        ];
        
        component.set('v.mycolumns', [
            {label: '氏名',  fieldName: 'LinkName', type: 'url', typeAttributes:{label: {fieldName: 'Name'}}},
            {label: '有効フラグ', fieldName: 'IsActive__c', type: 'boolean'},
            {label: 'エリア', fieldName: 'Area__c', type: 'pickList'},
            {label: 'メール', fieldName: 'Email', type: 'Mail '},
            {label: '電話', fieldName: 'Phone', type: 'Phone'},
            {label: '役職', fieldName: 'Title', type: 'text '},
            {label: '部署', fieldName: 'Department', type: 'text'},
            {label: '年齢', fieldName: 'Age__c', type: 'text'},
            {label: '誕生日', fieldName: 'Birthdate', type: 'date'},   
            {type: "action", typeAttributes: { rowActions: actions }}
        ]);
    },
     
    /***
     * Contact取得
     ***/
    getContact:function(component, event, helper){
        var action = component.get("c.getContact");
        action.setParams({
            recordId:component.get("v.recordId")
        });   
        console.log(action)
        action.setCallback(this,function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                var conList = response.getReturnValue();
                if(conList.length > 0){
                    conList.forEach(function(record){
                       record.LinkName = "/lightning/r/Contact/"+record.Id +"/view"; 
                    });
                }
                component.set("v.filteredData",conList);
                this.preparePagination(component, conList);
            }
        });
        $A.enqueueAction(action);
    },  
      
    /***
     * レコードアクション
     ***/
    //詳細画面遷移
    showDetail:function(component, recId){
        var viewRecordEvent = $A.get("e.force:navigateToURL");
        viewRecordEvent.setParams({
            "url": "/" + recId
        });
        viewRecordEvent.fire();    
    },
    
    //編集処理
    editRecord:function(component, recId){
        var editRecordEvent = $A.get("e.force:editRecord");
        editRecordEvent.setParams({
            "recordId": recId
        });
        editRecordEvent.fire();
    },  
    
    //削除処理
    deleteRecord: function (component, event, helper) {
        var action = component.get("c.deleteContact");
            action.setParams({
                recordId:component.get("v.deleteRecId")               
            });
                
         console.log(action)
            action.setCallback(this, function(response) {
                var state = response.getState();           
                if (state === "SUCCESS" ) {
                    this.showToast({
                        "title": "取引先責任者削除",
                        "type": "success",
                        "message":" 取引先責任者が削除されました。"});
                    //削除した後のリロード
                    this.reloadDataTable();
                }else{
                    this.showToast("ERROR","error",JSON.stringify(response.getError())); 
                }
            });
            $A.enqueueAction(action);
        },
    
        
    preparePagination: function (component, Contact) {
        var countTotalPage = Math.ceil(Contact.length/component.get("v.pageSize"));
        var totalPage = countTotalPage > 0 ? countTotalPage : 1;
        component.set("v.totalPages", totalPage);
        component.set("v.currentPageNumber", 1);
        this.setPageDataAsPerPagination(component);
    },
        
    setPageDataAsPerPagination: function(component) {
        var data = [];
        var pageNumber = component.get("v.currentPageNumber");
        var pageSize = component.get("v.pageSize");
        var filteredData = component.get('v.filteredData');
        var x = (pageNumber - 1) * pageSize;
        for (; x < (pageNumber) * pageSize; x++){
            if (filteredData[x]) {
                data.push(filteredData[x]);
            }
        }
        component.set("v.conList", data);
    },
    
    /***
     * メッセージ表示
     ***/
    showToast:function(params){
        var toastEvent = $A.get("e.force:showToast");
    	if(toastEvent){
    		toastEvent.setParams(params);
    		toastEvent.fire();
    	} else{
    		alert(params.message);
    	}
    },
    
    /***
     * リロード処理
     ***/
    reloadDataTable : function(){
        var refreshEvent = $A.get("e.force:refreshView");
        if(refreshEvent){
            refreshEvent.fire();
        }
    },
})

Apexクラスでは、レコード削除処理を実行します。編集についてはhelper.js内の「e.force:editRecord」が行ってくれます。

public class ContactList {
    @AuraEnabled
    //Contact取得
    public static List<Contact> getContact(Id recordId){      
         return [select Id, Name,IsActive__c, Area__c, Phone, Email, Age__c, Birthdate, Title, Department from Contact Where AccountId =: recordId];      
    }
    
    @AuraEnabled
    //Contact削除
    public static Contact deleteContact(Contact recordId){     
        delete recordId; 
        return null;
    }
}
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

某SIer勤務。
新卒文系からエンジニア就職。
日々の学びをつらつらと書いています。
保有資格:Salesforce認定アドミニストレーター
     Salesforce認定Platformデベロッパー
     Salesforce認定上級Platformデベロッパー

コメント

コメントする

CAPTCHA


目次