Your search did not match any results.

Chat - Edit and Delete Messages

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

Use a data source to allow users to edit and delete messages. DevExtreme 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
@model DevExtreme.MVC.Demos.ViewModels.ChatViewModel @{ var editingOptions = new[] { new { Text = "Enabled", Value = "enabled" }, new { Text = "Disabled", Value = "disabled" }, new { Text = "Only the last message (custom)", Value = "custom" } }; } <div class="chat-container"> @(Html.DevExtreme().Chat() .ID("chat") .Height(600) .User(user => user .Id(Model.CurrentUser.Id) .Name(Model.CurrentUser.Name) ) .DataSource(new JS("dataSource")) .ReloadOnChange(false) .Editing(e => e.AllowUpdating(true).AllowDeleting(true)) .OnInitialized("chat_onInitialized") .OnMessageEntered("chat_onMessageEntered") .OnMessageDeleted("chat_onMessageDeleted") .OnMessageUpdated("chat_onMessageUpdated") ) </div> <div class="options"> <div class="caption">Options</div> <div class="option"> <span>Allow Editing:</span> @(Html.DevExtreme().SelectBox() .DataSource(editingOptions) .DisplayExpr("Text") .ValueExpr("Value") .InputAttr("aria-label", "Allow Editing") .Value(editingOptions[0].Value) .OnValueChanged("selectBox_allowUpdating_onValueChanged") ) </div> <div class="option"> <span>Allow Deleting:</span> @(Html.DevExtreme().SelectBox() .DataSource(editingOptions) .DisplayExpr("Text") .ValueExpr("Value") .InputAttr("aria-label", "Allow Deleting") .Value(editingOptions[0].Value) .OnValueChanged("selectBox_allowDeleting_onValueChanged") ) </div> </div> <script> let chat = null; let lastUserMessageId = null; const user = @Html.Raw(System.Text.Json.JsonSerializer.Serialize(Model.CurrentUser)); const store = @Html.Raw(System.Text.Json.JsonSerializer.Serialize(Model.Messages)); const customStore = new DevExpress.data.CustomStore({ key: "id", load: async () => [...store], insert: async (message) => { store.push(message); return message; }, }); const dataSource = new DevExpress.data.DataSource({ store: customStore, paginate: false, }); const editingStrategy = { enabled: true, disabled: false, custom: ({ component, message }) => { const { items, user } = component.option(); const userId = user.id; const lastNotDeletedMessage = items.findLast((item) => { return item.author?.id === userId && !item.isDeleted; }); return message.id === lastNotDeletedMessage?.id; }, }; function chat_onInitialized({ component }) { chat = component; } function chat_onMessageEntered({ message }) { dataSource.store().push([{ type: "insert", data: { ...message, id: new DevExpress.data.Guid(), }, }]); } function chat_onMessageDeleted({ message }) { dataSource.store().push([{ type: "update", key: message.id, data: { isDeleted: true }, }]); } function chat_onMessageUpdated({ message, text }) { dataSource.store().push([{ type: "update", key: message.id, data: { text, isEdited: true }, }]); } function selectBox_allowUpdating_onValueChanged({ value }) { chat.option("editing.allowUpdating", editingStrategy[value]); } function selectBox_allowDeleting_onValueChanged({ value }) { chat.option("editing.allowDeleting", editingStrategy[value]); } </script>
using System; using System.Linq; using System.Collections.Generic; using System.Web.Mvc; using DevExtreme.MVC.Demos.Models.Chat; using DevExtreme.MVC.Demos.Models.SampleData; using DevExtreme.MVC.Demos.ViewModels; namespace DevExtreme.MVC.Demos.Controllers { public class ChatController : Controller { private List<Message> GetPreparedMessages() { var initialMessages = SampleData.Messages.ToList(); var messages = initialMessages .Select(message => new Message { Id = Guid.NewGuid().ToString(), Timestamp = message.Timestamp, Author = message.Author, Text = message.Text, IsDeleted = message.IsDeleted, IsEdited = message.IsEdited }) .Take(initialMessages.Count - 2) .ToList(); messages.Insert(3, new Message { Id = Guid.NewGuid().ToString(), Timestamp = initialMessages[1].Timestamp, Author = SampleData.CurrentUser, IsDeleted = true }); messages[4].IsEdited = true; return messages; } public ActionResult MessageEditing() { return View(new ChatViewModel { CurrentUser = SampleData.CurrentUser, Messages = GetPreparedMessages(), }); } } }
using DevExtreme.MVC.Demos.Models.Chat; using System; using System.Collections.Generic; namespace DevExtreme.MVC.Demos.Models.SampleData { public partial class SampleData { private static readonly DateTime todayDate = DateTime.Now.Date; private static DateTime GetTimestamp(DateTime date, int offsetMinutes = 0) { DateTime adjustedDate = date.AddMinutes(offsetMinutes); return adjustedDate; } public static ChatUser CurrentUser = new ChatUser { Id = "c94c0e76-fb49-4b9b-8f07-9f93ed93b4f3", Name = "John Doe" }; public static ChatUser SupportAgent = new ChatUser { Id = "d16d1a4c-5c67-4e20-b70e-2991c22747c3", Name = "Support Agent", AvatarUrl = "../../Content/Images/petersmith.png" }; public static readonly IEnumerable<Message> Messages = new[] { new Message { Timestamp = GetTimestamp(todayDate, -9), Author = SupportAgent, Text = "Hello, John!\nHow can I assist you today?", }, new Message { Timestamp = GetTimestamp(todayDate, -7), Author = CurrentUser, Text = "Hi, I'm having trouble accessing my account.", }, new Message { Timestamp = GetTimestamp(todayDate, -7), Author = CurrentUser, Text = "It says my password is incorrect." }, new Message { Timestamp = GetTimestamp(todayDate, -7), Author = SupportAgent, Text = "I can help you with that. Can you please confirm your UserID for security purposes?" }, new Message { Timestamp = GetTimestamp(todayDate, 1), Author = CurrentUser, Text = "john.doe1357" }, new Message { Timestamp = GetTimestamp(todayDate, 1), Author = SupportAgent, Text = "✅ Instructions to restore access have been sent to the email address associated with your account." } }; } }
using DevExtreme.MVC.Demos.Models.Chat; using System.Collections.Generic; namespace DevExtreme.MVC.Demos.ViewModels { public class ChatViewModel { public IEnumerable<Message> Messages { get; set; } public ChatUser CurrentUser { get; set; } public ChatUser SupportAgent { get; set; } } }
using System; using System.Text.Json.Serialization; namespace DevExtreme.MVC.Demos.Models.Chat { public class Message { [JsonPropertyName("id")] public string Id { get; set; } [JsonPropertyName("timestamp")] public DateTime Timestamp { get; set; } [JsonPropertyName("author")] public ChatUser Author { get; set; } [JsonPropertyName("text")] public string Text { get; set; } [JsonPropertyName("isDeleted")] public Boolean IsDeleted { get; set; } [JsonPropertyName("isEdited")] public Boolean IsEdited { get; set; } } }
using System.Text.Json.Serialization; namespace DevExtreme.MVC.Demos.Models.Chat { public class ChatUser { [JsonPropertyName("id")] public string Id { get; set; } [JsonPropertyName("name")] public string Name { get; set; } [JsonPropertyName("avatarUrl")] public string AvatarUrl { get; set; } } }
.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); }

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 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.