Таблица данных Lightning — редактируемые CDT-файлы
Используйте возможности пользовательских типов данных в LWC с возможностью обработки данных lightning.
До сих пор я не видел ни одной организации Salesforce без пользовательских LWC. Неудивительно, что наиболее распространенным /популярным пользовательским компонентом всегда была копия стандартного компонента Связанный список (Related List).
Отображение информации в табличном виде имеет множество преимуществ, особенно с точки зрения ясности, организованности и эффективности.
ИМХО, в современном мире Salesforce единственным соответствующим подходом к созданию пользовательского компонента «Связанного списока» (или, по сути, любого компонента, который отображает данные в табличном виде) было бы использование lightning-datatable LWC.
Базовая таблица данных LWC
Salesforce вложила много средств в базовый LWC с возможностью передачи данных по молниям, и функции его компонентов значительно изменились за последние 2–3 года.
Программные возможности компонента имеют широкий спектр, в том числе:
- отображение табличных данных в структурированном и читаемом формате
- поддержка фиксированных или изменяемых размеров столбцов
- одиночный/множественный выбор строк
- действия на уровне строки (как статические, так и динамические) и действия заголовка
- индивидуальный стиль и тематика (с помощью крючков стиля SLDS)
- поддержка пользовательского рендеринга ячеек 💯
- поддержка пользовательского встроенного редактирования 💯
С помощью базовой таблицы данных LWC вы можете относительно легко добиться пользовательского опыта, подобного Excel.
Пользовательские типы данных и поддержка встроенного редактирования
Пользовательские типы данных расширяют уровень настройки LWC с таблицами данных lightning. CDT форматируют данные на основе типа, указанного вами для конкретного столбца. По умолчанию поддерживается дюжина типов данных.
Очевидно, что с помощью CDT вы можете придумать свой собственный тип данных для размещения информации, которую вы хотите отобразить в ячейке.
Вот реальные применения CDT в пользовательской таблице данных LWC:
- Отобразить пользовательский компонент «поиск» в ячейке
- Отобразить пользовательский компонент список выбора» в ячейке
- Отобразить управляющие и зависимые пользовательские компоненты список выбора» в соседних столбцах (имитируя поведение зависимых раскрывающихся списков Salesforce на странице сведений о записи)
Отображать данные, доступные только для чтения, в datatable просто. Самое интересное, что это касается ввода данных.
lightning-datatable позволяет включить режим редактирования для ячеек CDT.
Чтобы сделать ваш CDT доступным для редактирования, вам необходимо выполнить следующие действия:
Шаг №1: Определите свойство editTemplate
в конфигурациях CDT.
import LightningDatatable from 'lightning/datatable';
// Custom Data Type for Picklist;
import customPicklistReadonlyTemplate from './templates/customPicklist/readonly.html';
import customPicklistEditableTemplate from './templates/customPicklist/editable.html';
export default class Datatable extends LightningDatatable {
static COMMON_TYPE_ATTRIBUTES = ['value', 'fieldName', 'context', 'required'];
static customTypes = {
customCombobox: {...},
customPicklist: {
template: customPicklistReadonlyTemplate,
editTemplate: customPicklistEditableTemplate,
standardCellLayout: true,
typeAttributes: [...this.COMMON_TYPE_ATTRIBUTES, 'objectApiName', 'recordTypeId']
},
customLookup: {...},
customInput: {...}
};
}
Шаг №2: Реализуйте шаблон для свойства editTemplate
Редактируемые поля пользовательских типов выделяются желтым цветом так же, как и стандартные типы данных. Измененное значение ячейки временно сохраняется в свойстве editedValue
.
<template>
<!--Embed you custom LWC that handles edit behavior of your CDT-->
<c-custom-picklist
data-inputable="true"
...
value={editedValue}
></c-custom-picklist>
</template>
Шаг №3: Сделайте редактируемый пользовательский тип в определении столбца
get columns() {
return [
...
{
label: 'Industry',
fieldName: 'Industry__c',
type: 'customPicklist',
editable: true,
typeAttributes: {...}
},
...
];
}
Флаг editable
позволяет использовать значок карандаша внутри ячейки. При нажатии на него datatable создает экземпляр соответствующего LWC.
Смотрите демонстрацию пользовательского списка выбора CDT ниже:
Встроенное редактирование для CDT
Чтобы зафиксировать изменения, сделанные пользователем в редактируемом CDT, вы можете повторно использовать событие cellchange
. Убедитесь, что структура полезных данных события соответствует официальной/стандартной:
<c-datatable
lwc:ref="datatable"
key-field="Id"
draft-values={draftValues}
...
oncellchange={handleCellChange}
></c-datatable>
handleCellChange(event) {
event.stopPropagation();
let [changedEntry = {}] = cloneObject(event.detail.draftValues);
/**
* `changedEntry` object structure:
* {
* "Id": "0037Y00001ygqDvQAI"
* [changedFieldName]: "new_value"
* }
*/
...
// Capture particular field changes for the record;
this.draftValues = this.draftValues.map(...);
}
Поэтому CDT должен знать как минимум о следующих свойствах ячеек:
context
— это уникальное значение, идентифицирующее запись/строку (обычно идентификатор записи).fieldName
— как следует из названия, оно соответствует уникальному имени API поля (то есть свойству объекта, т. е.Industry__c
)value
— значение поля
Вышеупомянутые атрибуты можно легко передать в CDT через typeAttributes
с динамической/статической привязкой:
get columns() {
return [
...
{
label: 'Industry',
fieldName: 'Industry__c',
type: 'customPicklist',
editable: true,
typeAttributes: {
context: { fieldName: "Id" }, // dynamic
fieldName: 'Industry__c', // static
value: { fieldName: 'Industry__c' }, // dynamic
objectApiName: 'Contact' // static
}
},
...
];
}
В конце концов, как только CDT обнаруживает изменения в ячейке, создается соответствующая полезная нагрузка события, и событие запускается:
// LWC withing editable CDT;
notify() {
this.dispatchEvent(
new CustomEvent('cellchange', {
composed: true,
bubbles: true,
cancelable: true,
detail: {
draftValues: [{
['context']: this.context,
[this.fieldName]: this.value
}]
}
})
);
}
При таком подходе родительский компонент сможет захватывать и обрабатывать события изменения ячеек, происходящие от обоих:
- стандартные типы данных (например, text, number, date)
- пользовательские типы данных (например, customPicklist, customLookup)
Преимущество этого подхода заключается в том, что Lightning-Datatable обрабатывает рендеринг ячеек за вас — он динамически создает экземпляр CDT только для чтения или редактируемого, располагая его близко к границам ячейки. Он выделяет измененные ячейки, имитируя поведение стандартной таблицы в виде списка. Более того, API данных остается неизменным — используются одни и те же события и их структура.
Задача встроенного редактирования CDT
Когда пользователь нажимает на значок карандаша в ячейке, таблица данных переключается в режим встроенного редактирования.
Для стандартных типов данных (например, текст, число, дата) lighting-datatable легко переключается обратно в режим только для чтения, как только изменяется входное значение - это стандартное поведение.
Однако для CDT я не нашел официального способа выйти из режима встроенного редактирования при обнаружении изменения значения в ячейке. Если вы не выйдете из режима встроенного редактирования, редактируемый экземпляр CDT будет продолжать отображаться в сетке, вводя в заблуждение конечного пользователя.
Ниже приведено «неофициальное» решение этой проблемы, которое я нашел на данный момент:
escape() {
if (this.$focusedInput) {
/**
* Simulate 'Escape' button click on focused input within CDT.
* Open browser developer tools > top/YOUR_ORG_URL/components/lightning/datatable.js file > search for 'ESCAPE' keyword.
*/
const escapeEvent = new KeyboardEvent('keydown', {
composed: true,
bubbles: true,
cancelable: false,
key: 'Escape',
keyCode: 27,
code: 'Escape',
which: 27
});
this.$focusedInput.focus();
this.$focusedInput.dispatchEvent(escapeEvent);
} else {
/**
* Force escape from cell edit panel via reserved/unofficial event.
* Open browser developer tools > top/YOUR_ORG_URL/components/lightning/datatable.js file > search for 'ieditfinished' keyword.
*/
this.dispatchEvent(
new CustomEvent('ieditfinished', {
composed: true,
bubbles: true,
cancelable: false,
detail: {
reason: 'lost-focus',
rowKeyValue: this.context,
colKeyValue: 'unknown'
}
})
);
}
}
Приведенное выше решение имеет 2 варианта — вы можете использовать любой из них ИЛИ использовать оба (второй вариант является запасным).
Выйдите из режима встроенного редактирования с помощью кнопки Escape
После тщательного изучения источников данных, доступных с помощью lightning, я выяснил, что ячейка переключается обратно в режим только для чтения, как только пользователь нажимает кнопку Escape. Концептуальная идея, лежащая в основе этой опции, заключается в программной имитации такого же поведения. Следует отметить, что сфокусированный элемент должен быть определен в редактируемом шаблоне CDT (см. переменную $this.focusedInput).
Выйдите из режима встроенного редактирования с помощью события ieditfinished
Это сложный вариант, но с лета 24 года он работает без проблем!
Важно: «ieditfinished» не является документированным / официально рекомендованным событием. Мне удалось обнаружить это, наблюдая за JavaScript-источниками lightning-datatable с помощью инструментов разработчика Chrome.
Полезная нагрузка события требует определения атрибута атрибута rowKeyValue
.. Он соответствует уникальному значению, идентифицирующему запись/строку (по сути, это значение атрибута key-fiel
).
Бонусная демонстрация — Пользовательский поиск CDT:
Заключение
Рекомендуем потратить время на изучение возможностей LWC, собирающего данные о lightning. Это универсальный компонент, который охватывает широкий спектр потребностей бизнеса и пользователей. Его возможности по рендерингу данных, встроенному редактированию и настройке делают его мощным инструментом для улучшения пользовательского опыта и производительности в приложениях Salesforce.
Источник: https://medium.com/@awispack/lightning-datatable-editable-cdts-3458005a2043