DevExtreme v25.1 is now available.

Explore our newest features/capabilities and share your thoughts with us.

Your search did not match any results.

JavaScript/jQuery Chat - Edit and Delete Messages

The DevExtreme JavaScript Chat allows users to edit and delete messages as needs dictate.

Use a data source to allow users to edit and delete messages. DevExtreme JavaScript Chat does not update the data source automatically. Implement a CustomStore with CRUD operations to handle updates. Once you configured these operations, enable editing.

Backend API
$(() => { const customStore = new DevExpress.data.CustomStore({ key: 'id', load: async () => messages, insert: async (message) => { messages.push(message); return message; }, }); const dataSource = new DevExpress.data.DataSource({ store: customStore, paginate: false, }); const chat = $('#chat').dxChat({ height: 600, dataSource, editing: { allowUpdating: true, allowDeleting: true, }, reloadOnChange: false, user: currentUser, onMessageEntered(e) { const { message } = e; dataSource.store().push([{ type: 'insert', data: { id: new DevExpress.data.Guid(), ...message, }, }]); }, onMessageDeleted(e) { const { message } = e; dataSource.store().push([{ type: 'update', key: message.id, data: { isDeleted: true }, }]); }, onMessageUpdated(e) { const { message, text } = e; dataSource.store().push([{ type: 'update', key: message.id, data: { text, isEdited: true }, }]); }, }).dxChat('instance'); $('#allow-editing').dxSelectBox({ items: editingOptions, value: editingOptions[0].key, valueExpr: 'key', displayExpr: 'text', inputAttr: { 'aria-label': 'Allow Editing' }, onValueChanged(data) { chat.option('editing.allowUpdating', editingStrategy[data.value]); }, }); $('#allow-deleting').dxSelectBox({ items: editingOptions, value: editingOptions[0].key, valueExpr: 'key', displayExpr: 'text', inputAttr: { 'aria-label': 'Allow Deleting' }, onValueChanged(data) { chat.option('editing.allowDeleting', editingStrategy[data.value]); }, }); const editingStrategy = { enabled: true, disabled: false, custom: ({ component, message }) => { const { items, user } = component.option(); const userId = user.id; const lastNotDeletedMessage = items.findLast( (item) => item.author?.id === userId && !item.isDeleted ); return message.id === lastNotDeletedMessage?.id; }, }; });
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <head> <title>DevExtreme Demo</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script>window.jQuery || document.write(decodeURIComponent('%3Cscript src="js/jquery.min.js"%3E%3C/script%3E'))</script> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/25.1.3/css/dx.light.css" /> <script src="js/dx.all.js"></script> <link rel="stylesheet" type="text/css" href="styles.css" /> <script src="data.js"></script> <script src="index.js"></script> </head> <body class="dx-viewport"> <div class="demo-container"> <div class="chat-container"> <div id="chat"></div> </div> <div class="options"> <div class="caption">Options</div> <div class="option"> <span>Allow Editing:</span> <div id="allow-editing"></div> </div> <div class="option"> <span>Allow Deleting:</span> <div id="allow-deleting"></div> </div> </div> </div> </body> </html>
.demo-container { min-width: 720px; display: flex; gap: 20px; } .chat-container { display: flex; flex-grow: 1; align-items: center; justify-content: center; } .options { padding: 20px; display: flex; flex-direction: column; min-width: 280px; background-color: rgba(191, 191, 191, 0.15); gap: 16px; } .dx-chat { max-width: 480px; } .caption { font-size: var(--dx-font-size-sm); font-weight: 500; } .dx-avatar { border: 1px solid var(--dx-color-border); }
const getTimestamp = function (date, offsetMinutes = 0) { return date.getTime() + offsetMinutes * 60000; }; const date = new Date(); date.setHours(0, 0, 0, 0); const currentUser = { id: 'c94c0e76-fb49-4b9b-8f07-9f93ed93b4f3', name: 'John Doe', }; const supportAgent = { id: 'd16d1a4c-5c67-4e20-b70e-2991c22747c3', name: 'Support Agent', avatarUrl: '../../../../images/petersmith.png', }; const messages = [ { id: new DevExpress.data.Guid(), timestamp: getTimestamp(date, -9), author: supportAgent, text: 'Hello, John!\nHow can I assist you today?', }, { id: new DevExpress.data.Guid(), timestamp: getTimestamp(date, -7), author: currentUser, text: "Hi, I'm having trouble accessing my account.", }, { id: new DevExpress.data.Guid(), timestamp: getTimestamp(date, -7), author: currentUser, text: 'It says my password is incorrect.', }, { id: new DevExpress.data.Guid(), timestamp: getTimestamp(date, -7), author: currentUser, isDeleted: true, }, { id: new DevExpress.data.Guid(), timestamp: getTimestamp(date, -7), author: supportAgent, text: 'I can help you with that. Can you please confirm your UserID for security purposes?', isEdited: true, }, ]; const editingOptions = [ { text: 'Enabled', key: 'enabled' }, { text: 'Disabled', key: 'disabled' }, { text: 'Only the last message (custom)', key: 'custom' }, ];

The editing object includes allowUpdating and allowDeleting properties. These Boolean options are initially set to false. To edit and delete messages, set these Boolean options to true or assign functions with custom logic.

Review this demo and learn how to delete/edit chat messages. First, ensure that "Options" are active in the panel next to the JavaScript Chat component. Right-click (Control+Click on MacOS) or long-tap a message to open the context menu. Select "Delete" to remove the message; a marker is then displayed in place of the deleted message within the feed. Choose "Edit" to view the original message and update its content. Click "Send" to save changes; this will mark the message as edited.