Advanced 20 min read

Sorting, Row Actions, and Inline Editing

By the end of this lesson, you'll be able to:

  • Enable column sorting and handle the onsort event
  • Add row-level actions with a menu
  • Enable inline editing and handle saved draft values

Prerequisites: "lightning-datatable Fundamentals"

Column Sorting

get columns() {
    return [
        { label: 'Name', fieldName: 'name', type: 'text', sortable: true },
    ];
}

handleSort(event) {
    const { fieldName, sortDirection } = event.detail;
    const sorted = [...this.accounts].sort((a, b) => {
        const result = a[fieldName] > b[fieldName] ? 1 : -1;
        return sortDirection === 'asc' ? result : -result;
    });
    this.accounts = sorted;
    this.sortedBy = fieldName;
    this.sortedDirection = sortDirection;
}
<lightning-datatable
    columns={columns}
    data={accounts}
    key-field="id"
    sorted-by={sortedBy}
    sorted-direction={sortedDirection}
    onsort={handleSort}>
</lightning-datatable>

sortable: true on a column enables clicking its header; the actual re-sorting logic is the developer's own responsibility inside onsort — the component fires the event, but doesn't sort the data itself. [...this.accounts].sort(...) (Module 4's spread operator) avoids mutating the original array.

Row Actions

get columns() {
    return [
        // ...other columns
        {
            type: 'action',
            typeAttributes: {
                rowActions: [
                    { label: 'Edit', name: 'edit' },
                    { label: 'Delete', name: 'delete' },
                ],
            },
        },
    ];
}

handleRowAction(event) {
    const actionName = event.detail.action.name;
    const row = event.detail.row;

    if (actionName === 'delete') {
        this.deleteAccount(row.id);
    } else if (actionName === 'edit') {
        this.editAccount(row.id);
    }
}

A column with type: 'action' renders a dropdown menu per row; event.detail.action.name identifies which action was clicked, and event.detail.row is the full row data it applies to.

Inline Editing

get columns() {
    return [
        { label: 'Name', fieldName: 'name', type: 'text', editable: true },
    ];
}

handleSave(event) {
    this.draftValues = event.detail.draftValues;
    // persist each changed record, e.g. via updateRecord (Module 6)
}
<lightning-datatable
    columns={columns}
    data={accounts}
    key-field="id"
    draft-values={draftValues}
    onsave={handleSave}>
</lightning-datatable>

editable: true per column turns its cells into inline-editable fields. onsave fires when the user confirms their edits, with event.detail.draftValues — an array of just the changed fields per row — ready to be persisted with updateRecord (Module 6) or an Apex bulk update (Module 7).

Exercise

Add a row action column with a single "View" action (name: "view").

Show hint

Use type: "action" with a typeAttributes.rowActions array.

JAVASCRIPT

Exercise

Challenge: explain, as a comment, why onsort provides draft data via event.detail but does not sort this.accounts automatically.

Show hint

Think about who "owns" the data array.

JAVASCRIPT

Sorting, Row Actions, and Inline Editing Quiz

1. What does sortable: true on a column enable?

2. What column type renders a per-row action menu?

3. What does event.detail.draftValues contain in onsave?

4. Does lightning-datatable automatically sort its own data array when a column header is clicked?

5. What enables inline editing on a specific column?

Log in to submit the quiz and save your score.

My Notes

Log in to keep private notes on this lesson.

Questions about this lesson

No questions yet — be the first to ask.

Log in to ask a question about this lesson.

Summary

Sorting, per-row actions, and inline editing turn a static table into a genuinely interactive one — each is opt-in per column or per table, and each has its own event to handle.