Table - Server Sync

Back to Table Component Documentation

The table supports an optional server-sync workflow for saving edits and deleting records. When the request-edit attribute is present, calling saveEditedRecord() fires a requestSave event instead of applying the changes immediately. When the request-delete attribute is present, calling deleteRecord() or deleteSelected() fires a requestDelete event instead of deleting immediately.

Both events expose an approve() function on event.detail. Call it once the server operation succeeds to commit the change. If the operation fails, simply do not call approve() — the record stays in its current state so the user can retry. requestSave also provides event.detail.record (the original record) and event.detail.newData (the values read from the editor inputs). requestDelete provides event.detail.records, an array of the records targeted for deletion.

The example below mocks a server call that takes 1–3 seconds and randomly fails 50% of the time. Toasts are used to notify the user of success or failure.

<k-table id=serverSyncExample enable-selection request-edit request-delete><k-tc-edit slot=after></k-tc-edit><k-tc-delete-record slot=after></k-tc-delete-record><k-tc-delete-selected slot=top></k-tc-delete-selected></k-table>
<script type=module>
import Toast from '/src/components/Toast.js';
await window.customElements.whenDefined('k-table');
const table = document.getElementById('serverSyncExample');
const mockServer = () => new Promise((resolve, reject) => {
setTimeout(() => {
Math.random() < 0.8 ? resolve() : reject();
}, 1000 + Math.random() * 2000);
});
table.setData({
records: contacts,
fields: [{
name: 'name',
label: 'Name'
}, {
name: 'email',
label: 'Email'
}, {
name: 'birthday',
label: 'Birthday',
type: 'date'
}, {
name: 'phoneNumber',
label: 'Phone Number'
}, {
name: 'gender',
label: 'Gender',
formatter: v => v === 'm' ? 'Male' : 'Female'
}]
});
table.addEventListener('requestSave', async ({
detail: {
approve,
reject
}
}) => {
try {
await mockServer();
approve();
Toast.success('Record saved.', {
timeout: 3000
});
} catch {
reject();
Toast.error('Save failed. The record remains open for editing.', {
timeout: 5000
});
}
});
table.addEventListener('requestDelete', async ({
detail: {
records,
approve,
reject
}
}) => {
const count = records.length;
try {
await mockServer();
approve();
Toast.success(count === 1 ? '1 record deleted.' : count + ' records deleted.', {
timeout: 3000
});
} catch {
reject();
Toast.error('Delete failed. Please try again.', {
timeout: 5000
});
}
});
</script>