How to get field data in Validator?

How to get field data in Validator?

kstankiewiczkstankiewicz Posts: 8Questions: 3Answers: 1

I have a SQL table with a field called UserID, when a new entry is created the UserID field is populated with the AD username of whoever created it. Whenever this row is edited (from inline Datatables Editor) I want to check if the person editing is the same as in the UserID field.

I am able to do this with the PreEdit event by doing something like this:

editor.PreEdit += (sender, e) =>
                {
                    var originalEntry = e.Editor.Db().Select("tablename", null, query => query.Where("ID", e.Id)).Fetch();

                    if (User.Identity.Name != originalEntry["UserID"].ToString())
                    {
                    e.Cancel = true;
                    }
                };

This works, but it doesn't give the user any notification. The documentation says this is not possible when cancelling pre* events, the only way to give an error notification is using a Validator. However I'm having trouble getting a Validator to perform this function. Here's what I have right now:

                editor.Validator((thisEditor, action, data) =>
                {
                    if (action == DtRequest.RequestTypes.EditorEdit)
                    {
                        var originalEntry = thisEditor.Db().Select("tablename", null, query => query.Where("ID", data.Ids[0])).Fetch();
                        if (originalEntry["UserID"].ToString() != User.Identity.Name)
                        {
                            return "Access Denied, you may only edit your own entries";
                        }
                    }
                    return "";
                });

The problem is that data.Ids is null, I'm not sure how to get the ID of the currently edited row within this validator. Better yet, I'd like to retrieve the UserID field value without needing to query the database at all- but I haven't been able to figure that out either

Btw this is an ASP.NET MVC project

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 63,534Questions: 1Answers: 10,475 Site admin
    Answer ✓

    The way to get the row id inside a field validator is actually a bit convoluted. There is a ValidationHost parameter which is passed in and that contains the id. The code for the built in unique validator is useful here. Note the use of host.Id when editing (in this case, it discounts its own host row from the unique validation).

    To get the UserID, assuming that is in the data submitted to the server(? - it will depend on how your client-side form is configured) you could just use data['UserID'].

    Allan

  • kstankiewiczkstankiewicz Posts: 8Questions: 3Answers: 1

    Thanks Allan, your comment about submitting the UserID field from the client-side form pointed me in the right direction. Adding the "submit: all" option to the editor allowed me to pass all fields to the controller:

    <script>
                    $('#tablename').on('click', 'tbody td', function (e) {
                        editor.inline(this, {
                            submit: 'all'
                        });
                    });</script>
    

    And I was able to access the UserID field like so:

                    editor.Validator((thisEditor, action, data) =>
                    {
                        if (action == DtRequest.RequestTypes.EditorEdit)
                        {                      
                            var formFields = (Dictionary<string, object>)data.Data.Values.First();                      
                            
                            if (formFields["UserID"].ToString() != User.Identity.Name)
                            {
                                return "Access Denied, you may only edit your own entries";
                            }
                        }
                        return "";
                    });
    

    Previously the form was only submitting data that was edited instead of all data.

This discussion has been closed.