New to Telerik UI for ASP.NET Core? Download free 30-day trial

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

  1. 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>
    
  2. Track the state of the locked and unlcoked events using their id. The lockedRecords 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
                });
            }
        }
    
  3. 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's Edit 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>
    
  4. Handle the DataBound event of the Scheduler and handle the click 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>
    
  5. Handle the Edit and Save 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>
    
  6. Handle the MoveStart and MoveEnd 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>
    
  7. Handle the ResizeStart and ResizeEnd 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.

More ASP.NET Core Scheduler Resources

See Also

In this article