DevGang
Авторизоваться

Таблица данных Lightning — редактируемые CDT-файлы

Используйте возможности пользовательских типов данных в LWC с возможностью обработки данных lightning.

До сих пор я не видел ни одной организации Salesforce без пользовательских LWC. Неудивительно, что наиболее распространенным /популярным пользовательским компонентом всегда была копия стандартного компонента Связанный список (Related List).

Отображение информации в табличном виде имеет множество преимуществ, особенно с точки зрения ясности, организованности и эффективности.

ИМХО, в современном мире Salesforce единственным соответствующим подходом к созданию пользовательского компонента «Связанного списока» (или, по сути, любого компонента, который отображает данные в табличном виде) было бы использование lightning-datatable LWC.

Базовая таблица данных LWC

Salesforce вложила много средств в базовый LWC с возможностью передачи данных по молниям, и функции его компонентов значительно изменились за последние 2–3 года.

Программные возможности компонента имеют широкий спектр, в том числе:

  1. отображение табличных данных в структурированном и читаемом формате
  2. поддержка фиксированных или изменяемых размеров столбцов
  3. одиночный/множественный выбор строк
  4. действия на уровне строки (как статические, так и динамические) и действия заголовка
  5. индивидуальный стиль и тематика (с помощью крючков стиля SLDS)
  6. поддержка пользовательского рендеринга ячеек 💯
  7. поддержка пользовательского встроенного редактирования 💯

С помощью базовой таблицы данных 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&nbsp;«customPicklist»
CDT «customPicklist»

Встроенное редактирование для 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:

CDT «customLookup»
CDT «customLookup»

Заключение

Рекомендуем потратить время на изучение возможностей LWC, собирающего данные о lightning. Это универсальный компонент, который охватывает широкий спектр потребностей бизнеса и пользователей. Его возможности по рендерингу данных, встроенному редактированию и настройке делают его мощным инструментом для улучшения пользовательского опыта и производительности в приложениях Salesforce.

Источник: https://medium.com/@awispack/lightning-datatable-editable-cdts-3458005a2043

#Data Science #Data Visualization
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу