В данной статье рассмотрим, как можно реализовать кастомную сортировку таблицы в Lightning. Так как таблицу в Lightning можно построить разными способами, то дальше рассмотрим сортировку для таблицы, построенной с помощью HTML тега “table” и Lightning тега “lightning:datatable”.
Какую реализацию таблицы использовать — решайте сами ниже просто опишу их возможности.
HTML таблица “table” - это просто html таблица к которой можно применять CSS стили Lightning Design System. Можно кастомизировать, как хотите. Какой-то дополнительный функционал нужно реализовывать самому.
Lightning таблица “lightning:datatable” - это lightning aura тег, который позволяет построить таблицу с уже реализованными функциями. Что поддерживает тег:
- Отображение и форматирование столбцов с соответствующими типами данных;
- Прокрутка строк;
- Возможность редактирования значения в строке (применимо не для всех типов);
- Можно добавить actions на заглавие или строку таблицы;
- Изменение размера столбцов;
- Выбор строк. Можно включить checkbox;
- Нумерация строк;
- Выравнивание содержимого ячейки.
Но эта таблица не поддерживается в мобильной версии.
Вот ссылка на полное описание из документации:
https://developer.salesforce.com/docs/component-library/bundle/lightning:datatable/documentation
Итак, сначала рассмотрим сортировку для HTML таблицы:
1. Lightning компонент
<aura:component description="TestListForm" controller="FormTestController">
<aura:attribute name="accounts" type="List"/>
<aura:attribute name="sortDirection" type="Boolean" default="true"/>
<aura:attribute name="arrow" type="String" default="utility:arrowup"/>
<lightning:overlayLibrary aura:id="overlayLibDemo"/>
<div class="slds-card slds-p-top--medium">
<header class="slds-card__header">
<h3 class="slds-text-heading--small">Accounts</h3>
</header>
<section class="slds-card__body">
<div id="list" class="row">
<table class="slds-table slds-table_cell-buffer slds-table_bordered">
<thead>
<tr class="slds-line-height_reset">
<th class="slds-text-title_caps" scope="col">
<div class="slds-truncate" title="Accoint Id">Accoint Id</div>
</th>
<th class="slds-text-title_caps" scope="col">
<div class="slds-truncate" title="Account Name">Name
<lightning:buttonIcon onclick="{!c.sortByName}" iconName="{!v.arrow}" size="x-small" alternativeText="Order"/>
</div>
</th>
</tr>
</thead>
<tbody>
<aura:iteration items="{!v.accounts}" var="acc">
<tr class="slds-hint-parent">
<td data-label="Accoint Id">
<div class="slds-truncate" title="Accoint Id">{!acc.Id}</div>
</td>
<td data-label="Accoint Name">
<div class="slds-truncate" title="Accoint Name">{!acc.Name}</div>
</td>
</tr>
</aura:iteration>
</tbody>
</table>
</div>
</section>
</div>
<lightning:button onclick="{!c.getAccounts}" label="Update"/>
</aura:component>
Это разметка HTML таблицы с применением Salesforce Lightning стилей, где в имя столбца, которым можно сортировать, я вставил тег “lightning:buttonIcon” - это стандартная иконка стрелочки для сортировки.
По нажатию на эту стрелочку будет производится сортировка с помощью вызова JavaScript метода lightning:buttonIcon onclick="{!c.sortByName}"
.
В атрибут тега iconName="{!v.arrow}"
подставляем переменную “arrow” определенную в начале <aura:attribute name="arrow" type="String" default="utility:arrowup"/>
.
У этой переменной по дефолту default="utility:arrowup"
указано имя иконки “utility:arrowup”. Это значение мы буде менять на “utility:arrowdown” и обратно в JavaScript методе при нажатии на иконку.
Переменная <aura:attribute name=“sortDirection” type=“Boolean” default=“true”/> служит для указания направления сортировки. Изменяется также в JavaScript методе при нажатии на иконку.
2. JavaScript контроллер
({
getAccounts : function(component, event) {
var action = component.get("c.getListAccounts");
action.setCallback(this, function(response) {
var state = response.getState();
if (state === "SUCCESS") {
component.set("v.accounts", response.getReturnValue());
}
});
$A.enqueueAction(action);
},
sortByName : function (component, event) {
var listAccs = component.get("v.accounts");
var sortDirection = component.get("v.sortDirection");
if (sortDirection == true) {
listAccs.sort(function (a, b) {
var nameA = a.Name.toLowerCase();
var nameB = b.Name.toLowerCase();
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
return 0;
});
component.set("v.sortDirection", false);
component.set("v.arrow", "utility:arrowdown");
}else {
listAccs.sort(function (a, b) {
var nameA = a.Name.toLowerCase();
var nameB = b.Name.toLowerCase();
if (nameB < nameA) {
return -1;
}
if (nameB > nameA) {
return 1;
}
return 0;
});
component.set("v.sortDirection", true);
component.set("v.arrow", "utility:arrowup");
}
component.set("v.accounts", listAccs);
}
})
В контроллере функция “sortByName” берет список Accounts - var listAccs = component.get("v.accounts");
и сортирует, при этом при каждой сортировке устанавливается правильное значение в переменные “v.arrow” и “v.sortDirection” вот таким способом:
component.set("v.sortDirection", false);
component.set("v.arrow", "utility:arrowdown");
А дальше отсортированный список возвращается назад на страницу:
component.set("v.accounts", listAccs)
Сортировка с использованием “lightning:datatable”.
1. Lightning компонент.
<aura:component description="TestDataTable" controller="FormTestController" implements="force:appHostable,flexipage:availableForAllPageTypes">
<aura:attribute name="accountColumns" type="List"/>
<aura:attribute name="accountData" type="Object"/>
<aura:attribute name="sortBy" type="String"/>
<aura:attribute name="sortDirection" type="String"/>
<aura:handler name="init" action="{!c.onInit}" value="{!this}"/>
<lightning:datatable aura:id="accountTable"
keyField="Id"
hideCheckboxColumn="true"
columns="{!v.accountColumns}"
data="{!v.accountData}"
sortedBy="{!v.sortBy}"
sortedDirection="{!v.sortDirection}"
onsort="{!c.handleSort}"/>
<lightning:button onclick="{!c.getAccounts}" label="Update"/>
</aura:component>
Подробно про “lightning:datatable” можно почитать в документации вот ссылка:
https://developer.salesforce.com/docs/component-library/bundle/lightning:datatable/example
Пройдем только по основным моментам.
Аттрибут “accountColumns” - это имена колонок таблицы, которыe задаются в javaScript контроллере.
Аттрибут “accountData” - это список Accounts, который будет отображаться в таблице; задается в javaScript контроллере.
Аттрибут "sortBy" - имя столбца, по котором производится сортировка;
устанавливается автоматически тегом “lightning:datatable” вот в этом месте sortedBy="{!v.sortBy}"
.
Аттрибут “sortDirection” - устанавливает направление сортировки; может быть “asc” или “desc”. Устанавливается автоматически тегом “lightning:datatable” вот в этом месте sortedDirection="{!v.sortDirection}"
.
Тег "aura:handler " - используется для инициализации имен столбцов таблицы JavaScript контроллером. В теге вызывается метод контроллера action="{!c.onInit}", который устанавливает значения в аттрибут “accountColumns”.
2. JavaScript контроллер
({
onInit : function(component,event,helper) {
component.set("v.accountColumns", [
{
label: 'Id Account',
fieldName: 'Id',
type: 'text',
sortable: false
},
{
label: 'Account Name',
fieldName: 'Name',
type: 'text',
sortable: true
}
]);
},
getAccounts : function(component, event) {
var action = component.get("c.getListAccounts");
action.setCallback(this, function(response) {
var state = response.getState();
if (state === "SUCCESS") {
component.set("v.accountData", response.getReturnValue());
}
});
$A.enqueueAction(action);
},
handleSort : function(component,event,helper) {
var sortBy = event.getParam("fieldName");
var sortDirection = event.getParam("sortDirection");
var listAccs = component.get("v.accountData");
component.set("v.sortBy", sortBy);
component.set("v.sortDirection", sortDirection);
if (sortBy == "Name" && sortDirection == "asc") {
listAccs.sort(function (a, b) {
var nameA = a.Name.toLowerCase();
var nameB = b.Name.toLowerCase();
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
return 0;
});
} else {
listAccs.sort(function (a, b) {
var nameA = a.Name.toLowerCase();
var nameB = b.Name.toLowerCase();
if (nameB < nameA) {
return -1;
}
if (nameB > nameA) {
return 1;
}
return 0;
});
}
component.set("v.accountData", listAccs);
}
})
В функции “onInit” задаются имена столбцов и их свойство. Тут можно увидеть, что только один столбец можно отсортировать у него задано свойство “sortable: true”.
В функции “handleSort” выполняется сортировка. В нутри функции мы проверяем, что переданный для сортировки столбец это именно столбец с именнем “Name” и направление сортировки if (sortBy == "Name" && sortDirection == "asc")
.
Но нужно помнить, что приведенная реализация сортировки в JavaScript контроллере работает только для строковых типов данных. Если нужно сортировать другие типы данных — вам нужно реализовать сортировку для них отдельно.