###・要件
Lightningでテーブルリストでのソートと検索を実現する
SalesforceのAuraでコンポーネント作成手順をまとめる
###・対応案
・Aura技術要領を把握する
・データ渡す方法を理解する
###・方法
####①DeveloperConsoleでコンポーネントを作成する
コンポーネントに7ファイルを生成されるが、上3つだけはよく使われている
#####AccountList.cmp →画面描写XML
<aura:component controller="AccountListController"
implements="flexipage:availableForAllPageTypes,lightning:actionOverride,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:appHostable" >
<aura:attribute name="acctList" type="List"/>
<aura:attribute name="filteredData" type="List" />
<!-- Server検索項目 -->
<aura:attribute name="schStr" type="String" />
<!-- filter input -->
<aura:attribute name="filter" type="String" />
<!-- Header -->
<aura:attribute name="mycolumns" type="List"/>
<!-- Sort -->
<aura:attribute name="sortedBy" type="String" default="Industry"/>
<aura:attribute name="sortedDirection" type="String" default="asc"/>
<aura:handler name="init" value="{!this}" action="{!c.fetchAccounts}"/>
<div class="demo-only" style="height: 24rem;">
<div class="demo-only demo-only--sizing slds-grid ">
<div class= "slds-size--1-of-8" ><span> </span> </div>
<div class= "slds-size--2-of-8" >
<span onkeypress="{!c.search}">
<lightning:input type="text" placeholder="全データからEnterキーで再検索する"
value="{!v.schStr}" />
</span></div>
<div class= "slds-size--3-of-8" ><span></span></div>
<div class= "slds-size--1-of-8" >
<span>
<lightning:input type="text" placeholder="結果からフィルタする" onchange="{!c.filter}" value="{!v.filter}" />
</span>
</div>
<div class= "slds-size--1-of-8" ><span></span></div>
</div>
<lightning:datatable data="{!v.filteredData}"
columns="{!v.mycolumns}"
keyField="id"
hideCheckboxColumn="false"
onsort="{!c.updateColumnSorting}"
sortedBy="{!v.sortedBy}"
sortedDirection="{!v.sortedDirection}"/>
</div>
</aura:component>
#####AccountListController.js →画面描写JS
({
fetchAccounts : function(component, event, helper) {
component.set('v.mycolumns', [
{label: 'Account Name', fieldName: 'linkName', type: 'url',
typeAttributes: {label: { fieldName: 'Name' }}, sortable: true},
{label: 'Industry', fieldName: 'Industry', type: 'text', sortable: true},
{label: 'Type', fieldName: 'Type', type: 'text', sortable: true},
{label: 'Number Of Employees', fieldName: 'NumberOfEmployees',
type: 'number',cellAttributes: { alignment: 'left' }, sortable: true},
{label: 'Clean Status', fieldName: 'CleanStatus', type: 'text', sortable: true},
]);
var action = component.get("c.fetchAccts");
var schStr = component.get("v.schStr");
if (schStr== null ||schStr== undefined){
schStr='';
}
schStr = '%' + schStr + '%';
action.setParams({ keyWord : schStr});
action.setCallback(this, function(response){
var state = response.getState();
if (state === "SUCCESS") {
// Link
var records = response.getReturnValue();
records.forEach(function(record){
record.linkName = '/'+record.Id;
});
component.set("v.acctList", records);
//sort
component.set("v.filteredData",records);
helper.sortData(component, component.get("v.sortedBy"), component.get("v.sortedDirection"));
}
});
$A.enqueueAction(action);
},
updateColumnSorting: function (cmp, event, helper) {
var fieldName = event.getParam('fieldName');
var sortDirection = event.getParam('sortDirection');
cmp.set("v.sortedBy", fieldName);
cmp.set("v.sortedDirection", sortDirection);
helper.sortData(cmp, fieldName, sortDirection);
},
filter: function(component, event, helper) {
var data = component.get("v.acctList"),
term = component.get("v.filter"),
results = data, regex;
try {
regex = new RegExp(term, "i");
// filter checks each row, constructs new array where function returns true
results = data.filter(row=>regex.test(row.Name)
|| regex.test(row.Industry)
|| regex.test(row.Type)
|| regex.test(row.NumberOfEmployees==undefined?"":row.NumberOfEmployees.toString())
|| regex.test(row.CleanStatus)
);
} catch(e) {
// invalid regex, use full list
alert(e);
}
component.set("v.filteredData", results);
},
search: function(component, event, helper){
//alert("msg " + event.which);
if(event.which == 13) {
var action = component.get("c.fetchAccts");
var schStr = component.get("v.schStr");
if (schStr== null ||schStr== undefined){
schStr='';
}
schStr = '%' + schStr + '%';
action.setParams({ keyWord : schStr});
// alert(schStr);
action.setCallback(this, function(response){
var state = response.getState();
// alert(state);
if (state === "SUCCESS") {
// Link
var records = response.getReturnValue();
// alert(records);
records.forEach(function(record){
record.linkName = '/'+record.Id;
});
component.set("v.acctList", records);
//sort
component.set("v.filteredData",records);
helper.sortData(component, component.get("v.sortedBy"), component.get("v.sortedDirection"));
}
});
$A.enqueueAction(action);
}
}
})
#####AccountListHelper.js →画面データ処理の共通JS
({
sortData: function (cmp, fieldName, sortDirection) {
var data = cmp.get("v.filteredData");
var reverse = sortDirection !== 'asc';
data.sort(this.sortBy(fieldName, reverse))
cmp.set("v.filteredData", data);
},
sortBy: function (field, reverse, primer) {
var key = primer ?
function(x) {return primer(x[field])} :
function(x) {return x[field]};
reverse = !reverse ? 1 : -1;
return function (a, b) {
return a = key(a)?key(a):'', b = key(b)?key(b):'', reverse * ((a > b) - (b > a));
}
}
})
testAccoutList.app Previewボタンを押す
<aura:application extends="force:slds" >
<c:AccountList/>
</aura:application>
####④画面のSFIDを渡す方法
画面レコードSFIDはXMLに使える
####⑤Apexの実装
AccountListController.apex
public with sharing class AccountListController {
@AuraEnabled
public static List < Account > fetchAccts( String keyWord) {
return [ SELECT Id, Name, Industry, Type,NumberOfEmployees,CleanStatus FROM Account
where Name like :keyWord
OR Industry like :keyWord
OR Type like :keyWord
// OR NumberOfEmployees like :keyWord
OR CleanStatus like :keyWord
Limit 100 ];
/*
List<List<SObject>> customerAccountSearchList = new List<List<SObject>>();
customerAccountSearchList = [FIND :keyWord IN ALL Fields
RETURNING Account(Id, Name, Industry, Type,NumberOfEmployees,CleanStatus)];
Account [] searchedAccount = ((List<Account>)customerAccountSearchList[1]);
return searchedAccount; */
}
}