Kendo UI Scheduler: Delete/Edit/Update only specified events

user3629755 picture user3629755 · May 27, 2014 · Viewed 7.7k times · Source

Im working with the Kendo Scheduler and users can create, delete, update, edit events to my local database. But I'm working with different users on this webapp so I only want those users to be able to edit, delete and update events that they personally created. So user 1 can delete events created by user 1 but can't delete events created by user 2 or 3 etc...

I thought I just modify the model/controller to check the userID of the logged in user against the userID in the db of the event.

public virtual JsonResult Meetings_Destroy([DataSourceRequest] DataSourceRequest request, MeetingViewModel meeting)
{
    var userid = System.Convert.ToInt32(Session["userID"]);

    if (ModelState.IsValid)
        {
            if (meeting.UserID== userid)
            {
                meetingService.Delete(meeting, ModelState);
            }
            else
            {
                "cant delete"
            }
        }

    return Json(new[] { meeting });
}

But this doesn't seem to work, when click on delete the event dissapears but after reloading you see that it actually isn't really deleted from the db ... That of course isn't a good solution cause the goal is of course that that user just can't delete that event.

Any idea's?


VIEW

$(function () {
    $("#scheduler").kendoScheduler({
        date: new Date(Date.now()),
        startTime: new Date(2013, 5, 13, 9, 0, 0, 0),
        height: 800,
        timezone: "Etc/UTC",
        dataSource: {
            transport: {
                read: {
                    url: "@Url.Action("Meetings_Read", "Home")",
                    dataType: "json",
                    contentType: "application/json; charset=utf-8",
                    type: "POST"
                },
                update: {
                    url: "@Url.Action("Meetings_Update", "Home")",
                    dataType: "json",
                    contentType: "application/json; charset=utf-8",
                    type: "POST"
                },
                create: {
                    url: "@Url.Action("Meetings_Create", "Home")",
                    dataType: "json",
                    contentType: "application/json; charset=utf-8",
                    type: "POST"
                },
                destroy: {
                    url: "@Url.Action("Meetings_Destroy", "Home")",
                    dataType: "json",
                    contentType: "application/json; charset=utf-8",
                    type: "POST"
                },
                parameterMap: function (options, operation) {
                    if (operation === "read") {
                        var scheduler = $("#scheduler").data("kendoScheduler");
                        var result = {
                            start: scheduler.view().startDate(),
                            end: scheduler.view().endDate()
                        }
                        return kendo.stringify(result);
                    }
                    return kendo.stringify(options);
                }
            },
            error: error_handler,
                schema: {
                    model: {
                        id: "MeetingID",
                        fields: {
                            MeetingID: { type: "number" },
                            title: { from: "Title", type: "string", defaultValue: "No title", validation: { required: true } },
                            description: { from: "Description", type: "string" },
                            start: { from: "Start", type: "date" },
                            startTimezone: { from: "StartTimezone", type: "string" },
                            end: { from: "End", type: "date" },
                            endTimezone: { from: "EndTimezone", type: "string" },
                            recurrenceRule: { from: "RecurrenceRule", type: "string" },
                            recurrenceId: { from: "RecurrenceID", type: "number", defaultValue: null },
                            recurrenceException: { from: "RecurrenceException", type: "string" },
                            isAllDay: { from: "IsAllDay", type: "boolean" },
                            Timezone: { type: "string" },
                            RoomID: { type: "number", defaultValue: null },
                            Attendees: { type: "object" }
                        }
                    }
                }

            },

        });
    });

JAVASCRIPT

<script type="text/javascript">
    function error_handler(e) {
        if (e.errors) {
            var scheduler = $("#scheduler").data("kendoScheduler");
            scheduler.one("dataBinding", function (e) {
                e.preventDefault();
                for (var error in e.errors) {
                    alert("can't delete")
                }
            })
            var message = "Errors:\n";
            $.each(e.errors, function (key, value) {
                if ('errors' in value) {
                    $.each(value.errors, function () {
                        message += this + "\n";
                    });
                }
            });
            alert(message);
        }
    }

CONTROLLER

   public virtual JsonResult Meetings_Destroy([DataSourceRequest] DataSourceRequest request, MeetingViewModel meeting)
    {
            if (ModelState.IsValid)
            {
                if(meeting.UserID == System.Convert.ToInt32(Session["userID"]))
                {
                meetingService.Delete(meeting, ModelState);
                }
                else
                {
                ModelState.AddModelError("","cant delete");
                }
            }

        return Json(new[] { meeting });
    }

Answer

piercove picture piercove · May 27, 2014

I have a similar situation with my project where I have users that have limited access to do things on the calendar. I have found that you have to prevent things like Adds, Edits, and Deletes, that a user should not do, you can do this with the JavaScript events. Then, in the JavaScript functions, if a condiation is met (or not), then call the e.preventDefault(); method. Here's the demo on Client Events.

View (HTML 5 snippet)

remove: RemoveMe,
edit: EditMe,
add: AddMe,

View (MVC version snippet)

.Events(events =>
{
    events.Add("AddMe").Edit("EditMe").Remove("RemoveMe");
})

JavaScript

function AddMe (e) {
    if (SomeValue != SomeOtherValue) 
       e.preventDefault();
};

function EditMe (e) {
    if (SomeValue != SomeOtherValue) 
       e.preventDefault();
};

function RemoveMe (e) {
    if (SomeValue != SomeOtherValue) 
       e.preventDefault();
};

So, the good news is that this prevents the Calendar from showing updates (whether a Delete occurs or not), but it doesn't prevent the Delete Prompt (aka. "Are you sure you want to delete this event?"). Preventing the actions on the Client side is the way to go and you could extend it with alerts or notifications to the screen (since you would have the condition in the JavaScript function anyways), all to inform the user they can't do something.