This is a migrated thread and some comments may be shown as answers.

Call controller before Edit command Grid

8 Answers 1279 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Leoni
Top achievements
Rank 1
Leoni asked on 01 Oct 2015, 02:28 PM

I use the Ajax Editing to manage the record in my grid .
I would like call the controller before edit the selected record to check if the record is not lock.
I would like have this process :
   - Click on "Edit" buttom on grid,
   - Call the action controller to check the lock,
       -> If record lock, Abort Edit record,
       -> If record is not lock, Edit record.
 Do you know of a great way to make this process ?
Thanks
I set up a simple grid like this using the Razor syntax:

@(Html.Kendo().Grid<GridCustomPopupTemplate.Models.Person>().Name("persons")
    .DataSource(dataSource => dataSource
        .Ajax()
        .Model(model => model.Id(m => m.PersonID))
        .Read(read => read.Action("GetPersons", "Home"))
        .Update(up => up.Action("UpdatePerson", "Home"))
    )
    .Columns(columns =>
    {
        columns.Bound(c => c.PersonID).Width(200);
        columns.Bound(c => c.Name);
        columns.Command(cmd => {
            cmd.Edit();
            });
    })
    .Pageable()
    .Sortable()
    .Editable(ed => ed.Mode(GridEditMode.PopUp).TemplateName("Person"))
)

8 Answers, 1 is accepted

Sort by
0
Boyan Dimitrov
Telerik team
answered on 05 Oct 2015, 08:18 AM

Hello Leoni,

 

My suggestion is to use a custom command button as shown in the Grid / Custom command demo, make the request to the server to check whether the selected record is locked and based on the response open the popup editor for the data item. This could be done by calling the editRow method of the Kendo UI DataSoure and pass the jQuery row element. 

 

 

 

Regards,
Boyan Dimitrov
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Leoni
Top achievements
Rank 1
answered on 07 Nov 2015, 01:12 AM

Thank you Boyan for your answer.
I have used  the basic custom command buttons and "edit" event to call action controller with ajax request.The ajax request check the record status : lock or unlock :
- If record is locked then the record is null and the popup edit is close. This process work fine.
- If record is unlocked then record return the last version record (record different of Master grid, if an user has modified the record after display of the grid).
My issue being that the trigger event of the "update" buttom doesn't work after update the setting the model (set.model). The "CTCO_PRENOM" field content the last value, but the popup edit is always display after click "update". 
I have noticed that the "requestEnd" event type of datasource return "undefined" (See enclosed file).

Why the trigger event of the "update" buttom is disabled after the ajax return ?

I'm beginning to use telerik UI for asp .net mvc and i don't know if a good way for edit record of master grid. I found examples with the partial Views.

What is your suggestion ?
I continue this way or change method. Do you have a code library aspnet-mvc to explain this process ?
Regards.

View Master Grid:

<div class="col-xs-18 col-md-12">
    @* Grille "Contact" *@
    @(Html.Kendo().Grid<CSE.Model.ContactEntity>().Name("grid")
    .Columns(columns =>
    {
        // Command disponible au niveau de la grille
        columns.Command(command =>
        {
            command.Edit();
            command.Destroy();
        }).Width(200);
        columns.Bound(p => p.CTCO_ID);
        columns.Bound(p => p.CTCO_CIVILITE);
        columns.Bound(p => p.CTCO_PRENOM);
        columns.Bound(p => p.CTCO_EMAIL);
        columns.Bound(p => p.CTCO_FONCTION).Filterable(ftb => ftb.Multi(true));
        columns.Bound(p => p.CTCO_LIB);
        })
        .ToolBar(toolbar => toolbar.Create())
        // Mode d'édition
        .Editable(editable =>
            {
             editable.Mode(GridEditMode.PopUp).TemplateName("ContactResultEntityTable");
            })
        .Pageable()
        .Events(e =>
            {
                // Edit event to call action controller
                e.Edit("onRequestEdit");
                e.Cancel("onRequestClose");
            })
        .Sortable()
                .Filterable()
        .DataSource(dataSource => dataSource
                    .Ajax()
                    .PageSize(20)
                    .Model(model =>
                        {
                            model.Id(p => p.ID);
                        })
                    .Events(events =>
                    {
                        events.Error("onError");
                        events.RequestEnd("onRequestEnd");
                    })
                    .Create(update => update.Action("Create", "Contacts"))
                    .Update(update => update.Action("Update", "Contacts"))
                    .Destroy(update => update.Action("Destroy", "Contacts"))
                    .Read(r Optionsead => read.Action("Search", "Contacts").Data("additionalInfo")
                    )
            )
    )
</div>

 Javascript in View :

// Event : Edit Record (coté client): Appel Controller "CheckLock"
function onRequestEdit(arg) {
 
    // get model
    var model = arg.model;
    //model.sender.read();
    alert("onRequestEdit");
    kendoConsole.log("onRequestEdit : Edit : " + model.CTCO_ID + ":" + model.CTCO_PRENOM);
    grid = $("#grid").data("kendoGrid");
    // Appel de la méthode "CheckLock" en passant ID du contact pour vérifier le lock sur l'enregistrement.
    $.ajax({
        url: '@Url.Action("CheckLock", "Contacts")',
        type: 'POST',
        data: { ID: model.CTCO_ID },
        //data: JSON.stringify(model),//{ contactAtLock: model.},
        datatype : 'json',
        success: function (result) {
            //if (result.rlock) {
            if (result.contact != null && result.contact !== undefined) {
                // Edit de l'enregistrement possible
                alert('onRequestEdit : Edit record :' + result.contact.CTCO_ID + "Prenom->" + result.contact.CTCO_PRENOM);
                // Mise à jour de l'enregistrement
                for (var property in result.contact) {
                        model.set(property, result.contact[property]);
                }
            }
            if (result.contact == null) {
                // Edition de l'enregistrement impossible
                alert('Edit: Record verrouillé par un autre utilisateur');
                $('span.k-i-close').click();
            }
        },
        error: function () { alert('Error in popup edit'); }
    })
}
 
// Event : Abort Edit (coté client): Appel Controller "UnLock"
function onRequestClose(arg) {
    var model = arg.model;
    // Call de la méthode "UnLock" en passant ID du contact pour vérifier le lock sur l'enregistrement.
    $.ajax({
        url: '@Url.Action("UnLock", "Contacts")',
        data: { ID: model.CTCO_ID },
        success: function (result) {
            if (result.rlock) {
                // Enregistrement courant déverouillé
                alert('onRequestClose : Record unlock');
            }
        }
    })
}
 
// Event : Edit End : Forcer la lecture de la source en cas d'update (Spécifique au Template Custom)
function onRequestEnd(e) {
    kendoConsole.log("onRequestEnd : Start : event type :" + e.type);
    if (e.type == "update") {
        alert("onRequestEnd : Update");
        //Get Grid
        var grid = $("#grid").data("kendoGrid");
        grid.dataSource.read();
    }
}
 
function onError(e, status) {
    if (e.errors) {
        var message = "There are some errors:\n";
        // Create a message containing all errors.
        $.each(e.errors, function (key, value) {
            if ('errors' in value) {
                $.each(value.errors, function () {
                    message += this + "\n";
                });
            }
        });
        // Display the message
        alert(message);
        // Cancel the changes
        var grid = $("#grid").data("kendoGrid");
        grid.cancelChanges();
    }
}

My Template PopupEdit (Form) :

@model CSE.Model.ContactEntity
<html>
<head>
    <title>My Custom PopUpEdit</title>
</head>
<body>
    <div id="inputWindow" class="responsive-table-line" style="margin:0px auto;max-width:700px;">
        <table class="table table-bordered table-condensed table-body-center">
            <tbody>
                <br />
                @Html.HiddenFor(model => model.ID)
                <tr>
                    <td>
                        <div class="form-group">
                            @Html.LabelFor(model => model.CTCO_CIVILITE)
                        </div>
                    </td>
                    <td>
                        <div class="form-group">
                            @Html.EditorFor(model => model.CTCO_CIVILITE)
                            @Html.ValidationMessageFor(model => model.CTCO_CIVILITE)
                        </div>
                    </td>
                </tr>
                <tr>
                    <td>
                        <div class="form-group">
                            @Html.LabelFor(model => model.CTCO_LIB)
                        </div>
                    </td>
                    <td>
                        <div class="form-group">
                            <div class="form-group">
                                @Html.EditorFor(model => model.CTCO_LIB)
                                @Html.ValidationMessageFor(model => model.CTCO_LIB)
                            </div>
                        </div>
                    </td>
                </tr>
                <tr>
                    <td>
                        <div class="form-group">
                            @Html.LabelFor(model => model.CTCO_PRENOM)
                        </div>
                    </td>
                    <td>
                        <div class="form-group">
                            @Html.EditorFor(model => model.CTCO_PRENOM)
                            @Html.ValidationMessageFor(model => model.CTCO_PRENOM)
                        </div>
                    </td>
                </tr>
                <tr>
                    <td>
                        <div class="form-group">
                            @Html.LabelFor(model => model.CTCO_EMAIL)
                        </div>
                    </td>
                    <td>
                        <div class="form-group">
                            @Html.EditorFor(model => model.CTCO_EMAIL)
                            @Html.ValidationMessageFor(model => model.CTCO_EMAIL)
                        </div>
                    </td>
                </tr>
                <tr>
                    <td>
                        <div class="form-group">
                            @Html.LabelFor(model => model.CTCO_FONCTION)
                        </div>
                    </td>
                    <td>
                        <div class="form-group">
                            @Html.EditorFor(model => model.CTCO_FONCTION)
                            @Html.ValidationMessageFor(model => model.CTCO_FONCTION)
                        </div>
                    </td>
                </tr>
                <tr>
                    <td>
                        <div class="form-group">
                            @Html.LabelFor(model => model.CTCO_PUBLIC)
                        </div>
                    </td>
                    <td>
                        <div class="form-group">
                            @Html.EditorFor(model => model.CTCO_PUBLIC)
                            @Html.ValidationMessageFor(model => model.CTCO_PUBLIC)
                        </div>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</body>
</html>

Controller :

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CheckLock([DataSourceRequest] DataSourceRequest request, int ID)
//public ActionResult CheckLock(ContactEntity contactAtLock)
{
    ContactEntity cto = null;
    ContactEntity lastVersionContact = null;
    if (ModelState.IsValid)
    {
        // Vérifier que l'enregistrement courant n'est pas verrouillé par un autre utilisateur
        //IManager manager = new ContactManager();
        InitManager();
 
        (manager as ContactManager).AuthenticationManager = (IAuthenticationManager)Session["UserManager"];
         
        //A l'ouverture de la fiche : Verifier si le contact peut être éditer
        //todo: cto a stocker
        cto = manager.EditElement(ID) as ContactEntity;
         
        //Vérifier si on peut modifier
        if (manager.CanEdit(ID))
        {
            // Simuler Modification du record si valeur différente de la grille
            cto.CTCO_PRENOM = "lastVersion_" + cto.CTCO_PRENOM;
 
            lastVersionContact = cto;
        }
    }
    return Json(new { contact = lastVersionContact }, JsonRequestBehavior.AllowGet); //.ToDataSourceResult(request, ModelState));
    //return Json(new[] { lastVersionContact }.ToDataSourceResult(request, ModelState));
}
 
// Déverrouiller l'enregistrement
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UnLock(int ID)
{
    var result = false;
    if (ModelState.IsValid)
    {
        InitManager();
        (manager as ContactManager).AuthenticationManager = (IAuthenticationManager)Session["UserManager"];
 
        //var entity = manager.EditElement(ID);
        //todo: supprimer
        var entity = manager.GetElement(ID);
 
        // Si utilisateur annule les modifications
        manager.Release(entity);
 
        result = true;
         
    }
    return Json(new { rlock = result }, JsonRequestBehavior.AllowGet);
}
 
// MàJ un "Contact"
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Update([DataSourceRequest] DataSourceRequest request, ContactEntity contact)
{
    bool hasErrors = ModelState.Values.Any(x => x.Errors.Count > 1);
    
    // Test
    if (contact != null && ModelState.IsValid)
    {
        int id = contact.ID;
 
        // Récupérer le manager courant
        InitManager();
        (manager as ContactManager).AuthenticationManager = (IAuthenticationManager)Session["UserManager"];
 
        // Travailler Directement avec l'entitié récupérer 
        var entity = (ContactEntity)contact;
 
        // A la fermeture de la fiche
        // Si utilisateur clic sur save
        manager.Save(entity);
        // Si utilisateur annule les modifications
        //manager.Release(entity);
    }
    return Json(new[] { contact }.ToDataSourceResult(request, ModelState));
}

0
Boyan Dimitrov
Telerik team
answered on 10 Nov 2015, 03:31 PM

Hello Leoni,

Actually the "Update" button in the popup editor will perform an update request to the server. Basically what you are trying to achieve is to perform a validation before the actual update. 

In this case there is another possible solution: to prevent the default behavior when the "Update" button is clicked in order to perform the validation. If it is successful to call the sync method of the Kendo UI DataSource and if not - to show a message or something else. 

Preventing the default behavior when "Update" button is clicked can be done in the save event handler of the Kendo UI Grid. Please refer to the code snippet below:

 

save: function(e){
    e.preventDefault();
      //here goes the validation logic and so on
},

In order to get the Kendo UI DataSource for the gird widget you can use the dataSource property of the Kendo UI Grid widget. 

 

 

Regards,
Boyan Dimitrov
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Leoni
Top achievements
Rank 1
answered on 12 Nov 2015, 04:52 PM

Hello Boyan,

Yes, I would like to update the popup Edit with the last version record from the database after the lock.

I followed your suggestions, but the update method is not called after sync DataSource. I modified :

Add : save event handler of kendi UI Grid :

 @(Html.Kendo().Grid<CSE.Model.ContactEntity>().Name("grid")
    .Columns(columns =>

    ....

.Events(e =>
            {
                // Edit event to call action controller
                e.Edit("onRequestEdit");
                e.Cancel("onRequestClose");
                e.Save("onRequestSave"); // SM 10/11/2015
            })

 Add save function :

function onRequestSave(arg) {
        kendoConsole.log("Grid data onRequestSave");
        arg.preventDefault;
        kendoConsole.log("Grid data onRequestSave : preventDefault");
        var grid = $("#grid").data("kendoGrid");
        grid.dataSource.sync();  // The Update method is not called ?
    }

 I have forgotten somebody ? 

Thanks.

Regards.

0
Leoni
Top achievements
Rank 1
answered on 13 Nov 2015, 01:45 PM

In addition to the reply below :

For "CheckLock" method in Controller :

[AcceptVerbs(HttpVerbs.Post)]
        public ActionResult CheckLock([DataSourceRequest] DataSourceRequest request, int ID)
        //public ActionResult CheckLock(ContactEntity contactAtLock)
        {
            ContactEntity cto = null;
            ContactEntity lastVersionContact = null;
            if (ModelState.IsValid)
            {
                 
                //IManager manager = new ContactManager();
                InitManager();
                (manager as ContactManager).AuthenticationManager = (IAuthenticationManager)Session["UserManager"]; // SM 03/09/2015
                 
                cto = manager.EditElement(ID) as ContactEntity;
                 
                //Check modified
                if (manager.CanEdit(ID))
                {
                    // Simulate update record in database (data different of grid)
                    cto.CTCO_PRENOM = "lastVersion_" + cto.CTCO_PRENOM;
 
                    lastVersionContact = cto;
                }
            }
            // Return last version record to update all fields in popupEdit
            return Json(new { contact = lastVersionContact }, JsonRequestBehavior.AllowGet);
             
        }

Event : onRequestEdit() event grid :

function onRequestEdit(arg) {
....
$.ajax({
            url: '@Url.Action("CheckLock", "Contacts")',
            type: 'POST',
            data: { ID: model.CTCO_ID },
            //data: JSON.stringify(model),//{ contactAtLock: model.},
            datatype: 'json',
            success: function (result) {
                if (result.contact != null && result.contact !== undefined) {
                    for (var property in result.contact) {
                            // SM 13/11/2015 : Update record in popup Edit
                            arg.model.set(property, result.contact[property]);
                        //}
                    }
}
if (result.contact == null) {
                    // Close automatically PopPup
                    alert('Edit: Record verrouillé par un autre utilisateur');
                    $('span.k-i-close').click();
                }

0
Boyan Dimitrov
Telerik team
answered on 16 Nov 2015, 10:16 AM

Hello Leoni,

 

The preventDefault is actually a method, so it should be called as a method: 

arg.preventDefault();

Please find attached a sample project that implements the desired behavior. 

 

Regards,
Boyan Dimitrov
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Leoni
Top achievements
Rank 1
answered on 16 Nov 2015, 02:43 PM

Hello Boyan,

Thank you for your sample project.
I have seen this error in my code.

I compared and checked my code but i don't understand why the update bottom action is not called after "sync" DataSource in onRequestSave event. The edit popup display until.
I was wondering what the real problem is.
The issue may be with the update record process after the ajax resquest (see below) because this process disables the status of master grid (change row). In addition, the "RequestEnd" event of master grid return "undefined". why ?
See enclosed, the controller and view code files.
 I ask myself if this is possible.
What is your opinion?

Thanks,

Regards.

0
Boyan Dimitrov
Telerik team
answered on 18 Nov 2015, 05:51 PM

Hello Leoni,

 

Calling the sync method of the Kendo UI DataSource in the save event handler of the Kendo UI Grid is not supported scenario. At this time the model is not updated with the new value ( the event is preventable). My suggestion is to have a button that will call the sync method of the Kendo UI DataSource. 

 

Regards,
Boyan Dimitrov
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
Grid
Asked by
Leoni
Top achievements
Rank 1
Answers by
Boyan Dimitrov
Telerik team
Leoni
Top achievements
Rank 1
Share this question
or