Lock Edited Events of Scheduler Configured for SignalR Binding Using Local Hub
Environment
Product | Telerik UI for ASP.NET Core Scheduler |
Product Version | Created with version 2024.4.1112 |
Description
How can I lock the edited events of the ASP.NET Core Scheduler that uses SignalR DataSource with a local hub?
Solution
This example demonstrates locking the currently edited events of the Scheduler so the events cannot be edited, deleted, moved, or resized until they are saved (unlocked).
-
Disable the default events editing of the Scheduler by using the
Editable.Update()
configuration.@(Html.Kendo().Scheduler<MeetingViewModel>() .Name("scheduler") .Editable(editable => editable.Update(false)) ...// Additional configuration. )
@addTagHelper *, Kendo.Mvc <kendo-scheduler name="scheduler"> <editable update="false"></editable> <!-- Other configuration --> </kendo-scheduler>
-
Track the state of the locked and unlcoked events using their
id
. ThelockedRecords
global object stores their state.<script> var lockedRecords = {}; var hubStart = {}; // Create a new SignalR connection to the specified hubUrl. var hubUrl = "https://demos.telerik.com/kendo-ui/service/signalr/hubs"; var connection = $.hubConnection(hubUrl, { useDefaultPath: false }); var productHub = connection.createHubProxy("meetingHub"); $(function () { // Define functions that will lock and unlock the events by using their Ids. productHub.lockRecord = function (record) { lockedRecords[record.id] = true; }; productHub.unlockRecord = function (record) { lockedRecords[record.id] = false; } hubStart = connection.start({ jsonp: true }); }); </script>
public class ProductHub : Hub { public void LockRecord(int id) { Clients.Others.lockRecord(new { id = id }); } public void UnlockRecord(int id) { Clients.Others.unlockRecord(new { id = id }); } }
-
When the page with the Scheduler is loaded, handle the
dblclick
event over the events, prevent its default action (editing), and check if the double-clicked event is locked for editing. If not, trigger the Scheduler'sEdit
event.<script> // After the Scheduler declaration. $(function () { var scheduler = $("#scheduler").data("kendoScheduler"); scheduler.element.on("dblclick", ".k-event", function (e) { // Handle the "dblclick" event of the Scheduler events and prevent its default action (the opening of the Popup eidtor). e.preventDefault(); var eventUid = $(this).closest(".k-event").attr(kendo.attr("uid")); // Get the "uid" of the event. var event = scheduler.occurrenceByUid(eventUid); // Access the event data using its "uid". if (!lockedRecords[event.id]) { // If the cliked event is not locked for editing. $.connection.productHub.server.lockRecord(event.id); // Lock it. scheduler.view().trigger("edit", { uid: eventUid }); // Trigger the "edit" event of the Scheduler that will open its Popup editor. } else { alert("Currently the event cannot be edited"); return false; } }); }); </script>
-
Handle the
DataBound
event of the Scheduler and handle theclick
event of the Delete event icon. Use a custom function to check if the event that the user wants to delete is currently locked.<script> function onDataBound(e) { // Handle the "click" event of the event's "Delete" icon. this.view().content.on("click", ".k-event-delete", preventEvent); } function preventEvent(e) { var scheduler = $("#scheduler").data("kendoScheduler"); var eventUid = $(this).closest(".k-event").attr(kendo.attr("uid")); var event = scheduler.occurrenceByUid(eventUid); // Select the event's data by using its "uid". if (lockedRecords[event.id]) { // Check if the event is locked. e.stopImmediatePropagation() // If the event is currently locked for editing, prevent the deleting of the event and inform the user. alert("Currently the event cannot be deleted"); } } </script>
-
Handle the
Edit
andSave
events of the Scheduler to unlock the respective event when the user cancels the editing or when the event is saved.<script> function onEdit(e) { var model = e.event; e.container.find(".k-scheduler-cancel").click(function () { $.connection.productHub.server.unlockRecord(model.id); }); } function onSave(e) { productHub.unlockRecord(e.event.id); } </script>
-
Handle the
MoveStart
andMoveEnd
events of the Scheduler to prevent the moving of a currently locked event or unlocking the event when it is moved successfully.<script> function onMoveStart(e) { var scheduler = this; var event = e.event; if (!lockedRecords[event.id]) { $.connection.productHub.server.lockRecord(event.id); // Lock the event when the user starts moving it. } else { alert("Currently the event cannot be moved"); e.preventDefault(); // Prevent the moving of the event when it is already locked. } } function onMoveEnd(e) { $.connection.productHub.server.unlockRecord(e.event.id); // Unlock the event when it is moved successfully. } </script>
-
Handle the
ResizeStart
andResizeEnd
events of the Scheduler to prevent the resizing of a currently locked event or unlocking the event when it is resized successfully.<script> function onResizeStart(e) { var scheduler = this; var event = e.event; if (!lockedRecords[event.id]) { $.connection.productHub.server.lockRecord(event.id); // Lock the event when the user starts resizing it. } else { alert("Currently the event cannot be resized"); e.preventDefault(); // Prevent the resizing of the event when it is already locked. } } function onResizeEnd(e) { $.connection.productHub.server.unlockRecord(e.event.id); // Unlock the event when it is resized successfully. } </script>
For a runnable example, refer to the ASP.NET MVC application in the UI for ASP.NET MVC Examples repository. You can use this as a starting point to configure the same behavior in an ASP.NET Core project.